An editable paragraph

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed ante dapibus diam. Sed nisi.

Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla.

Fired Events:

Text Formatting

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero.

HTML

<p>Lorem ipsum dolor sit amet...</p>

Plain Text

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero.

Plain text blocks don't allow any markup. Newlines are replaced with spaces.

Example:


editable.add('.example', {plainText: true})
          

Styling

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero.

Style the editable element using CSS to match your page’s design.

Inline editables

Some inline editable element.

Highlighting

Is everybody happy? I want everybody to be happy. I know I'm happy.

Whitespace Highlighting

Hair space
Six-per-em space
Thin space
Normal space
Four-per-em space
Mathematical space
Punctuation space
Three-per-em space
En space
Ideographic space
Em space

Copy and Paste

Paste here...

iFrame

Setup


// create a new Editable object, and configure it as needed
var editable = new Editable({
  // here you can pass an iframe window if required (default: main window)
  window: window,

  // activate the default behaviour for merge, split and insert (default: true)
  defaultBehavior: true,

  // fire selection events on mouse move (default: false)
  mouseMoveSelectionChanges: false,

  // control the 'spellcheck' attribute on editable elements (default: true)
  browserSpellcheck: true
});

// add and initialize a block element to make it editable
editable.add(elem)

Setup Highlighting


editable.setupHighlighting({
  // control when the highlighting is triggered
  checkOnInit: true,
  checkOnFocus: false,
  checkOnChange: true,

  // debounce calls to the spellcheckService
  throttle: 500,

  spellcheck: {
    marker: '<span class="highlight-spellcheck"></span>',
    spellcheckService: function (text, callback) {
      // Return an array of words to be highlighted.
      // This only works with complete words. The spellchecker
      // wont highlight parts of words.
      callback(['happy'])
    }
  },

  whitespace: {
    marker: '<span class="highlight-whitespace"></span>'
  }
})

Events

focus blur

Fired when when an editable block gets focus and after it is blurred.

Example:


editable

.on('focus', elem => {
  // your code...
})

.on('blur', elem => {
  // your code...
})

selection

Fired when the user selects some text inside an editable block.

Example:


const getSelectionCoordinates = (selection) => {
  const range = selection.getRangeAt(0) // Assuming you want coordinates of the first range

  const rects = range.getClientRects()
  const coordinates = []

  for (let i = 0; i < rects.length; i++) {
    const rect = rects[i]
    coordinates.push({
      top: rect.top,
      left: rect.left,
      bottom: rect.bottom,
      right: rect.right,
      width: rect.width,
      height: rect.height
    })
  }

  return coordinates
}

editable.on('selection', (elem, selection) => {
  if (!selection) {
    // nothing selected
  } else {
    const coords = getSelectionCoordinates(window.getSelection())
    const text = selection.text()
    const html = selection.html()
    // your code...
  }
})

cursor

Fired when the user moves the cursor within an editable block.

Example:


editable.on('cursor', (elem, cursor) => {
  if (!cursor) {
    // no cursor anymore in that editable block
  } else {
    // example if you wanted to insert an element right before the cursor
    cursor.insertBefore(document.createElement('span'))
  }
})

change

Fired when the user changes the content of an editable block.

Example:


editable.on('change', elem => {
  const currentContent = editable.getContent(elem);
})

spellcheckUpdated

Fired when the spellcheckService has updated the spellcheck highlights.

Example:


editable.on('spellcheckUpdated', elem => {
  const currentContent = editable.getContent(elem);
})

clipboard

Fired for `copy` and `cut` events.

Example:


editable.on('clipboard', (elem, action, selection) => {
  if (action === 'cut') {
    const cutOutText = selection.text()
  }
})

paste

Fired for a `paste` event.

Example:


editable.on('paste', (elem, blocks, cursor) => {
  // blocks is an array of strings preprocessed by editable.js.
  // If the pasted content contains HTML it is split up by block
  // level elements and cleaned and normalized.
  const text = blocks.join(' ')
})

insert

Fired when the user presses enter (⏎) at the beginning or end of an editable (for example you can insert a new paragraph after the element if this happens).

The end 

Example:


editable.on('insert', (elem, direction, cursor) => {
  if (direction === 'after') {
    // your code...
  } else if (direction === 'before') {
    // your code...
  }
})

split

Fired when the user presses return (⏎) in the middle of an editable.

a b

Example:


editable.on('split', (elem, before, after, cursor) => {
  // before and after are document fragments with the content
  // from before and after the cursor in it.
})

merge

Fired when the user pressed forward delete (⌦) at the end or backspace (⌫) at the beginning of an editable.

 ab

Example:


editable.on('merge', (elem, direction, cursor) => {
  if (direction === 'after') {
    // your code...
  } else if (direction === 'before') {
    // your code...
  }
})

switch

Fired when the user presses an arrow key at the top or bottom so that you may want to set the cursor into the preceding or following editable element.

Example:


editable.on('switch', (elem, direction, cursor) => {
  if (direction === 'down') {
    // your code...
  } else if (direction === 'up') {
    // your code...
  }
})

newline

Fired when the user presses shift and enter (⇧ + ⏎) to insert a newline.

Example:


editable.on('newline', (elem, cursor) => {
  // your code...
})