Handling contenteditable in Ember.js via Ember.ContenteditableView

by Kasper Tidemann

In web development, the use of an <input> field is limited to single-line input such as a username or password field. But perhaps you want to make a web-based text editor, an auto-expanding description field or something similar? For that purpose, you could use a <div> element with its contenteditable attribute set to "true":

<div contenteditable="true">Content goes here!<div>

Requirements

When rendering a regular Em.TextField, you typically find yourself binding the value of the input field to a property on a record via valueBinding="user.firstname", for instance. So, when a user changes the content of the input field, the underlying record changes as well.

However, we need to take a few details into consideration in order to mimick Em.TextField. Namely, making sure to update the value property when either changing the HTML content of the <div> element itself or when the underlying record changes.

Also, we want to avoid updating the content of the <div> element when the user is typing, otherwise resulting in weird caret position behavior.

Lastly, when rendering the view, the bound record may already have been loaded. Therefore, we need to support both setting the content of the <div> element when the didInsertElement event is triggered and when the value property changes.

Ember.ContenteditableView

To accomplish this, I wrote the tiny Ember.ContenteditableView which does exactly the above. In order to use it, include the source in your project somewhere and render the view like so:

{{view Ember.ContenteditableView valueBinding="blogpost.content"}}

I have put the code on GitHub and questions or pull requests are always welcome.

Moving forward, you may want to support placeholders for your <div> elements as well. I’ll describe how to accomplish this in a upcoming post.