Validate a rich text form field

A required rich text field needs an application rule. HTML can be nonempty while the document contains no text. Validate the current editor content, copy it into the submitted field, and repeat the rule on the server.

1. Decide what counts as content

For a support-ticket description, you may require text. For an image captioning tool, an uploaded image may be a valid document by itself. A text-only check must reject an image-only document deliberately, rather than accidentally losing a valid post.

Define required content, minimum text length and maximum payload size as separate rules. HTML length counts markup; it is not a readable-character count. If you use getCharCount() or getPlainText(), verify how your installed version treats whitespace, lists and line breaks before using its result as your business rule.

2. Detect empty text, not empty markup

Code example
// Application policy: this field requires text, not an image-only document.
// Browser-side validation helper. This is NOT an HTML sanitizer.
function hasRequiredText(html) {
  const template = document.createElement("template");
  template.innerHTML = html;
  template.content.querySelectorAll("script, style, template")
    .forEach(node => node.remove());
  return (template.content.textContent || "")
    .replace(/[\s\u00a0\u200b\ufeff]/gu, "").length > 0;
}

This example rejects empty paragraphs, line breaks, nonbreaking spaces and image-only content. It parses into a disconnected template and never inserts that content into the live page. It is a text-presence check, not a security filter or a visual-layout test: CSS-hidden text and application-specific widgets need their own policy.

For a minimum length, decide whether you count code units, Unicode code points or user-perceived characters. JavaScript string length can count an emoji differently from a visible character. Use the same policy on both sides of the request.

3. Copy the current HTML and show a useful error

Code example
// Assumes editor1 is ready and these elements exist on your page.
// Leave the editor's hidden textarea without a native required attribute.
const form = document.querySelector("#ticket");
const field = document.querySelector("#body");
const message = document.querySelector("#body-error"); // e.g. <p role="alert">

form.addEventListener("submit", event => {
  const html = editor1.getHTMLCode();
  field.value = html; // Include programmatic edits in the submitted value.
  if (!hasRequiredText(html)) {
    event.preventDefault();
    message.textContent = "Please enter a description.";
    editor1.focus();
    return;
  }
  message.textContent = "";
  // Normal form submission continues to your application's endpoint.
});

The browser’s native required validation cannot reliably serve as the editor’s required-field rule after its textarea is hidden. Keep normal validation for ordinary form controls, but implement the editor rule against its current content. Do not add a native required constraint to the hidden backing field and expect a focusable error.

Keep Save disabled until initialization finishes. On failure, preserve the draft, show a visible message near the field and move focus back to the editor. Associate the message with the actual editable surface using the accessibility hooks supported by your integration; an attribute on a hidden textarea alone does not label the editing surface.

This snippet covers synchronous text validation only. If images are uploading, follow the upload-completion and save sequence before submitting. In React, read current content at submission as described in editor state and saving.

4. Repeat validation after server-side sanitization

Clients can bypass browser checks. Authenticate and authorize the save, enforce request and storage limits, sanitize HTML with a maintained parser-based policy, then evaluate whether the accepted document meets your content rule. A document containing only rejected markup must not become an accepted empty record.

Return a field-specific error and keep the user’s draft available. Never render rejected HTML unescaped in an error response. For C# or PHP examples of receiving and storing content, start with your language demo and rich text storage guide.

Acceptance checklist

  • Empty editor, blank paragraphs and nonbreaking spaces are rejected.
  • Normal text, formatted text and the languages your users type are accepted.
  • Image-only content follows an explicit policy.
  • Programmatically loaded content is included in submission.
  • Validation errors preserve content and can be reached with keyboard and screen reader.
  • The server rejects invalid direct requests without relying on JavaScript.

Try the form submission demo, read why required fields accept empty HTML, or review textarea installation.