Editable Content and Local Storage in HTML5
Aug 14th, 2010
A lot of the noise around HTML5 has been about whether or not it will replace Flash as the primary means of delivering video content over the Web. While I believe that HTML5’s simple, native video element is superior to Flash’s plugin-based mess of object, embed and param elements, Flash isn’t going away anytime soon. The noise, however, drowns out information about other interesting HTML5 features, two of which, content editable-ness and local storage, I’ll explore in this article with a simple example. Google’s Chrome browser supports both of these features; other browsers support one or the other, or neither.
Let’s say you have a page on your website and you would like to offer your readers the ability to jot down notes related to the content of that page in some kind of input field. Furthermore, since you expect visitors to revisit the page from time to time, you’d like to store their notes somewhere so that the input field can be loaded when they next load the page. Before HTML5, you would either use a server-side process, cookies or some combination of the two to make this happen. With HTML5, there’s a third choice: the localStorage window object.
First, let’s start with the input field. We could use a textarea element but in HTML5, any element can be turned into an input element by adding the contenteditable attribute:
<ul id="notepad" contenteditable="true"> <li></li> </ul>
In the CSS for this list element, we want to set its size and position:
#notepad { height: 20%; width: 20%; display: none; position: fixed; top: 0.5in; right: 0.5in; overflow: auto; padding: 1em; border: thin solid; list-style-type: none; background-color: #fffff0; /* light yellow */ }
This will place the list element 1/2 inch down and in from the top-right corner of the browser’s window. The bordered box will take up 1/5 of the window’s width and height and scrolling will be enabled if there is more content then fits. The display property is set to “none” initially. The user will be able to make the notepad list visible by clicking a button with an onclick handler.
<button id="notepad_toggle" onclick="$('#notepad').toggle()">Notepad</button>
I’m using jQuery for the onclick handler because it makes it easy to target elements . If you copy this code, make sure you load jQuery somewhere in the document’s head.
HTML5 extends the window object with the localStorage property and two primary methods: setItem(name, value) and getItem(name) to set and retrieve name/value pairs of data items. Any number of such items can be stored with a webpage and each page’s storage object is independent of any other page’s. Unlike cookies, local storage items are never sent by the browser to the server and thus provides a efficient means of saving page state information even for megabyte data items.
For our example, we can store the contents of the notepad element each time it is changed. We will do this with the blur method, detecting when the user leaves the notepad to do something else. Here’s some jQuery that does that nicely:
$('#notepad').blur(function () { localStorage.setItem('notepad', this.innerHTML); });
How nice is that? The storage doesn’t have to be initialized; it’s just there waiting for you to throw something into it.
When the page is first loaded we need to check if the notepad contents has been saved from some previous visit by this browser and if so, use the stored value to replace the inner contents of the list. This can be done with the following JavaScript statement:
if ( localStorage.getItem('notepad') ) { var notepad = document.getElementById('notepad'); notepad.innerHTML = localStorage.getItem('notepad'); }
Note that there’s no conflict in the three uses of ‘notepad’ in the code above. The name for the local variable can be anything as can the name of the stored data item. Neither has to be the same as the UL element’s ID. Hopefully, I’m avoiding confusion by naming everything ‘notepad’ and not adding any.
Since this is only going to work on some browsers, let’s test to see if local storage is available. If it isn’t, we can just hide the the button that makes the notepad visible.
if (!window.localStorage) $('#notepad_toggle').hide();
or, for debugging, we can call an alert message.
All of the code can go into a script element embedded in the content body, like this blog post, for example:
Click the button above and enter anything in the light yellow notepad that opens in the top right corner of your HTML5 capable browser. Enter anything you want – I’ll never see it, nor will anyone else. What’s entered in your local storage stays in your local storage. Try dragging and dropping images, tables, links and other thingys. Notice something interesting? You can’t use HTML to markup your own typing but anything you drag or paste in retains all of its HTML formatting. Now Go Away! Come back to this page sometime later (with the same browser) and click the notepad button again. There’s your stuff!
Click here to see the code for a stand-alone demo to get you started.