Tech Vistora
Hotline 24/7

+2 999 000 777

Saving contenteditable Content With data-* Attributes

html datatext contenteditable

Content With data-* Attributes such as in a contenteditable Text Area can be saved.

The core idea is very straightforward: listen to events on the element, get the data using textContent (or sanitized innerHTML) and store the last value in a data-* attribute to check if it changed. Putting this into practice for the html datatext contenteditable is a matter of a few minutes. If you don’t need the formatting, use contenteditable=”plaintext-only”, and use textarea for plain(text) forms.

The Need for Extra Handling in contenteditable

Contenteditable can be set to true (or blank) to make an element editable, set to false to make the element non-editable, or to ‘plaintext-only’ for plain text editing, with the loss of rich text formatting. It’s a low level feature and it doesn’t include aspects that are provided at no cost by form controls. No native change event, therefore listen to input – every time the editing host changes it gets the event.

A number of developers have had some rough-and-tumble experiences with it, and there is one simple tip: don’t use it unless you have a specific use case — a textarea should be employed for obtaining plain text input from the user. To provide inline formatting, custom layout or an editor-like experience, consider using contenteditable.

HTML Datatext Contenteditable: Read-Clean-Store Path

This is an editor style and not a standard.

  1. Read. Listen for participation and read text.
  2. Clean. Take the formatting off, or sanitize markup.
  3. Store. Store the value and use a data-* attribute to store a copy of the value to detect changes.

Step 2: Read the Left Property

TypeValueCopy/Paste atBeware of
innerTextMarkup is processed when printing to text fileNotes, titles, small bits of textDoes not reflect visual line breaks like in the innerText case.
innerTextRendered textDisplay-like readsOne developer reported that Firefox is ignoring line breaks in user typed content.
innerHTMLstring containing markupMarkup will be retainedInjection risk if not sanitized.

The advice from one source is to use innerHTML for including formatting, and textContent for including plain text. Another states that using innerHTML it is what makes a notes field an attack surface.

Step 2: Cleaning what users paste

Messy content is most contributed to by pasting. Content copied from the contenteditable=”true” element retains all formatting while a plaintext-only element loses all formatting attributes. Where necessary, you may look at pasted data using InputEvent.Since January 2020, dataTransfer has been available for data adding or removal to/from content that can be edited across browsers, returning richtext or plaintext data.

One guide applies DOMPurify.sanitize(html) to the stored / inserted markup prior to assigning to innerHTML. Consider any unsanitised, innerHTML write statement as a direct injection vector.

Step 3: Store, and Track Changes With data-*

The last saved value or a “dirty” flag can be easily stored in a data-* attribute:

html

<div id=”note” contenteditable=”plaintext-only”

     data-saved=”” role=”textbox” aria-label=”Notes”></div>

js

const note = document.getElementById(‘note’);

note.dataset.saved = note.textContent;

note.addEventListener(‘input’, () => {

  const changed = note.textContent !== note.dataset.saved;

  note.toggleAttribute(‘data-dirty’, changed);

});

// If the save is successful:

// note.dataset.saved = note.textContent;

Minimal illustration that works by me, but I haven’t tested it on a browser, so try it. It allows for CSS styling of unsaved state using [data-dirty] and it allows to alert the user if he/she wants to leave without saving.

What to Avoid

  • document.execCommand. It is not standardized and is being deprecated. To support true rich-text, one guide suggests using either the Selection and Range APIs and the beforeinput and input events, or a specific editor library.
  • Stacking events. Older answers propose a combination of keyup, blur, cut and paste to mimic the event. The input event is supported by modern browsers and one of the developers stated that handler events were not always triggered, but a MutationObserver was triggered consistently.
  • Creating a full editor from scratch. An editor library, like ProseMirror, Lexical or Tiptap, is recommended for trusted rich texts or structured, collaborative content.

Comparing and Selecting Appropriate Tools (OCOTO)

This is not a benchmark – it is an editorial comparison.

NeedBest choice
Plain text, that is single or multi-line, found in a form_input or textarea field
Support inline plain text with custom styling: contenteditable=”plaintext-only”.
Contenteditable contains input – sanitize light rich text by trusted users
Content (collaborative/structured)Editor library

Checklist for contenteditable (Linkable Asset)

  • Avoid used a textarea unless I really need some edited marking up
  • Fairly acted upon feedback, rather than an accumulation of key and mouse clicks
  • Read and write to textContent or innerHTML knowingly
  • Look at the pasted quality as plaintext format
  • Markup, sanitised prior to storage and prior to rendering.
  • Restores the previously set value in a data- attribute
  • Improved accessibility including providing a visible label or aria-label
  • Tested Pasted into the following browsers Chrome, Firefox and Safari
  • Checked for current Browser support – plaintext only
  • This is because the creation of new work is achieved through avoided execCommand.

Guest Post Angles

These topics are appropriate for publications in the front-end and web security and accessibility:

  • The difficulties with contenteditable – lines, paste and browser differences.
  • XSS with ‘editable’ fields: purging user markup.
  • textarea or contenteditable, guide to choosing for forms.

Before You Write Any JavaScript

These notes don’t contain any JavaScript.

The first question you should ask yourself is do you need formatting at all? Otherwise, using plaintext-only and textContent will eliminate most of the paste and security issues. Add the data-* change tracking last for any html datatext contenteditable feature once reading/cleaning acts the same in all browsers.

Facebook
Twitter
LinkedIn
Telegram
Pinterest
Picture of David Ace
David Ace

Explore our latest articles, expert insights, and helpful guides covering technology, business, SEO, digital marketing, and more. Browse all posts to discover valuable content, practical tips, and industry updates designed to keep you informed.

All Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Search
Categories
Newsletter
Social Media
TECH VISTORA TEAM