Using contenteditable for editing
The contenteditable attribute has been around since the good old days of Internet Explorer 5.5 and has finally been introduced into the HTML5 standards and is supported by pretty much every browser (http://caniuse.com/#feat=contenteditable). It allows us to edit text directly on an HTML page.
With the release of EPiServer 7 we've added a lot of functionality to the editing experience but unfortunately contenteditable didn't make the cut. However with a little spare time after the release I did a little hacking and have created an add-on that can be easily plugged into a site to add contenteditable editing for plain text!
In EPiServer 7 properties are associated with a particular editor based on their type. These editors are wrapped by an editor wrapper which generically handles the updating of the content model when a change event occurs in the editor and is also responsible for how the editor appears on screen (e.g. forms mode, floating dialog, or inline textbox).
However, in the contenteditable case, the browser is going to be the editor so there is no need to create a custom editor. Which means that since all the built-in editor wrappers require an editor to be available we need to create a new custom editor wrapper that will start editing when an overlay is clicked and cause changes to be passed to the content model when editing is stopped.
Here's one I prepared earlier:
Now, in order to make sure that our new editor wrapper is used instead of the default one for a string typed property we need to create an editor descriptor. An editor descriptor allows us to add custom information to the metadata for properties which will then be evaluated by the client side code at runtime. In this case it is as simple as specifying the uiWrapperType. Since we have a custom editor wrapper we’ll give it our own value of “contenteditable”.
You’ll also notice that I’ve given it a UIHint. This allows us to maintain the default functionality for strings and only use contenteditable where we specify. For example, in the Alloy templates I could change the UIHint for MetaDescription in SitePageData to be "contenteditable".
Which means that MetaDescription will appear like this in on page edit.
Now in order to map the “contenteditable” key that we’ve specified as our uiWrapperType to our actual editor wrapper we need to register a new editor wrapper in the editor factory. Unfortunately this is easier said than done. I have a fairly simple solution (*cough* hack *cough*) that will wire everything up nicely and efficiently. It a bit advanced in terms of dojo concepts but it basically listen on the register method of dependency and when the editor factory is registered we add our custom editor wrapper then unhook ourselves.
Adding the following to your module.config will ensure that this script is run when the CMS module is started.
Installing the ContentEditable add-on
To make your life easier, I’ve packaged this as an add-on which you can manually upload and install on your site if you want to try it out.
After installing the add-on just set the UIHint for any of your string typed properties to “contenteditable” then build. After refreshing the site those properties will now use contenteditable.