Form validation
Draftail is easy to integrate with form validation, whether as simple "required" checks or more advanced rich text metrics.
Integrating with a validation library
Content entered in the editor can be stored for validation with the onSave prop, or with onChange. The editor also supports onFocus and onBlur to mark fields as touched/untouched and trigger or stop validation.
Basic validation of required fields
The editor uses null as a content value when it is empty. Here is a what a simple “required field” check would look like:
if (!content) {
  error = "Please enter at least one paragraph"
}
Content validation
For more advanced use cases, the raw ContentState content can be parsed to enforce presence or threshold of specific content formats, or content length.
To calculate plain-text content length,
const contentLength = content.blocks.reduce((sum, b) => sum + b.text.length, 0)
We can also enforce metrics such as a minimum number of paragraphs (blocks):
if (blocks.filter((b) => b.text.trim().length > 0).length < 2) {
  error = "Please enter at least two paragraphs"
}
Demo
Here is a full demo, using Formik as a validation library. It enforces entering at least two paragraphs of content, containing at least one link.
<Formik
  initialValues={{ content: null }}
  onSubmit={window.alert.bind(null, "Success!")}
  validate={(values) => {
    const errors = {}
    if (!values.content) {
      errors.content = "Please enter at least two paragraphs"
    } else {
      const { blocks, entityMap } = values.content
      if (Object.keys(entityMap).length === 0) {
        errors.content = "Please use at least one link"
      }
      // Check there are at least two blocks with non-whitespace text
      if (blocks.filter((b) => b.text.trim().length > 0).length < 2) {
        errors.content = "Please enter at least two paragraphs"
      }
    }
    return errors
  }}
>
  {({ errors, touched, handleSubmit, setFieldTouched, setFieldValue }) => (
    <form onSubmit={handleSubmit}>
      <div className="form-field">
        <DraftailEditor
          entityTypes={[ENTITY_CONTROL.LINK]}
          onSave={setFieldValue.bind(null, "content")}
          onBlur={setFieldTouched.bind(null, "content")}
          stateSaveInterval={errors.content ? 50 : 250}
        />
        <div role="alert">
          {errors.content && touched.content && errors.content}
        </div>
      </div>
      <button type="submit">Submit</button>
    </form>
  )}
</Formik>