Make disaster-proof HTML5 forms
Shwetank Dixit of Opera Software explains how to use localStorage to save data offline so that what a user types into the form isn’t lost if disaster strikes
This article first appeared in issue 225 of .net magazine – the world's best-selling magazine for web designers and developers.
How many times have you been in the middle of meticulously typing information inside a form and – BAM! – the browser crashed? I bet it’s happened a few times at least. And when it has, you’ve had to open the browser, go to the URL again and enter all that information one more time – hoping the browser doesn’t crash again a few minutes later.
Various things can and do go wrong every day when filling in online forms. The browser may crash, your internet connection can barf at the wrong moment (especially on dial-up or flaky Wi-Fi), or you could even accidentally close the page yourself (something I’ve been guilty of myself at times).
Web builders should be looking at ways to ease the pain of the disgruntled user in such situations and to make their experience as painless as possible. One great (and easy) way to do this is to make sure that whatever the user has spent time and effort typing into your app is saved locally.
That way, even if the browser crashes or the tab gets accidentally closed, the information is still there when the user revisits the page later on.
There are a number of technologies people can use to store data offline. Until recently, people used to use cookies. However, there are certain problems associated with the use of cookies. They’re typically only allowed to store a few KBs of data. There isn’t any programmatic API to access them. And overall, they’re a bit of a pain to use.
For this reason, in this tutorial we’ll be using the Web Storage API and more specifically, localStorage, to store data on the client side.
What’s localStorage?
The W3C Web Storage API defines a new way to store data on the client side, in key-value pairs.
The API defines two storage mechanisms, localStorage and sessionStorage. The latter deals with storing data on the client side just for one particular session. As soon as you close the tab or window, the info is gone.
However, we’re more interested in storing information in a persistent way. This is where localStorage comes in.
As localStorage is persistent, data stored is available even after the user has closed the tab or window.
This means the next time a user loads your web application, the information will still be available for the application.
Web storage (which includes localStorage and sessionStorage) has storage quotas. Most browsers, by default, provide a 5MB quota per-origin. This can be extended further, but only if you exceed this limit. Then the browser will ask the user whether they want to increase the limit to more than 5MB. However, you don’t have any information about how much space you have left in the quota allotted to you.
Another thing to note is that localStorage and sessionStorage require data to be stored as strings. So if you want to store an object, you have to use something called JSON.stringify() to store it, and JSON.parse() to convert it back to an object once you retrieve it.
Browser support
The latest versions of most browsers have ECMAScript 5 support built in, so you can use those functions natively. Otherwise you could always include the json2.js file (available from json.org) to provide support for those functions.
There is a good amount of cross-browser support for web storage, with IE8+, Safari 4+, Opera 10.50+, Firefox 3.5+ and Chrome 4+ all supporting it. This means robust support among all modern browsers.
Even smartphone browsers such as Opera Mobile, Mobile Safari and the native Android browser support Web Storage.
How to use it
Using localStorage is very simple. For storing a key-value pair you have a function called setItem() and for retrieving a value for a particular key, you have a getItem() function.
The following code stores the value 'john' in the key 'name':
localStorage.setItem('name') = 'john';
The next snippet assigns the value of the 'name' key (which is 'john') to the variable 'fname'.
Get top Black Friday deals sent straight to your inbox: Sign up now!
We curate the best offers on creative kit and give our expert recommendations to save you time this Black Friday. Upgrade your setup for less with Creative Bloq.
var fname = localStorage.getItem('name'); //will assign 'John' to the variable fname
And this snippet will remove the key from localStorage:
localStorage.removeItem('name');
To clear keys, you have a clear() function. localStorage.clear() will clear all of the local storage entries you have for your app.
Our contact form
So let’s make a quick contact form for a site.
I personally believe that forms on the web should be short and to the point. Our sample contact form will be so too.
<form method="post" action="process.php"><label for="name">name:</label><input type="text" id="name" /><label for="email">Email address:</label><input type="email" id="email" /><label for="comment">Comment:</label><textarea id="comment" rows="15" cols="75"></textarea><input type="submit" value="submit form" /></form>
Saving data locally
Now that we’ve made our form, we want to save whatever the user has entered to the client.
In this form, we don’t want to save the password locally, so we’ll ignore those fields.
function savedata(){ var uname = document.querySelector("#name").value; var email = document.querySelector("#email").value; var comment = document.querySelector("#comment").value; localStorage.setItem('name', uname); localStorage.setItem('email', email); localStorage.setItem('comment', comment)}
I’m using document.querySelector() here as it’s more readable and supported on modern browsers.
However, if you like, you could always use document.getElementById. What we’re doing here is getting whatever has been entered in the various form fields, and then with the help of localStorage’s setItem() function, storing it locally as a key-value pair.
Now that we have a function to save the data locally, we can run this function at regular intervals of time, so that it keeps saving data periodically on the local machine.
var myInterval = setInterval(savedata, 5000); //saves data locally every 5 seconds
In this case, we make sure the page saves the user’s data locally every five seconds.
Retrieving data and repopulating the form
Okay. The form now saves data locally after regular intervals of time. Now to make sure that if the page is accidently closed, then the data stored locally repopulates the form the next time the user opens the same page.
function retrievedata(){ var uname = localStorage.getItem("name"); var email = localStorage.getItem("email"); var comment = localStorage.getItem("comment");document.querySelector("#name").value = uname;document.querySelector("#email").value = email;document.querySelector("#comment").value = comment;}
We run retrievedata() whenever the page is loaded. This means that whenever the page is loaded, it will first check whether there is any value stored in localStorage for the form entries. If so, any entered data will be loaded there. Otherwise the form will appear just as it would normally with nothing filled in.
Cleaning up
Great. The user has successfully used the form to send the information to you. However, right now if they go to the form again, they’ll see whatever they typed in it last time, even though it been submitted successfully.
What we really want is the page to save what the user has entered locally up to the point that the user has submitted the form. Once the user successfully submits the form, the form should once again clear.
For that, we’ll look at process.php:
<!DOCTYPE html><html><head><style type="text/css"><?php//code for processing form data......?><script type="text/javascript">localStorage.removeItem('name');localStorage.removeItem('email')localStorage.removeItem('comment');</script></head><body><h1>Thanks for the comment!</h1><p>Return to the <a href="form.htm">previous page</a></p></body></html>
Here we are processing the form, and in the end making sure that we delete the values in localStorage for 'Name', 'Email' and 'Comment' so that if the user goes back to the contact page, they don’t see the comment that they had just submitted again.
Going further
You can enhance this form in other ways. Right now the form saves all the data every five seconds. You could use something like the oninput event to only save to localStorage when a person actually types something in the form itself.
However, keep in mind that IE9 has a bug where it only fires the oninput event if something is added by the user. If the user uses a backspace to delete something, that doesn’t seem to register. This example also directs you to another page to process it, but you could send the form information through Ajax and clear the form if there is a successful response. This would be especially useful for commenting systems in blogs.
Conclusion
Using localStorage, it’s now possible to make forms that save user data offline until it’s submitted to the site. This makes the user experience so much better – if the tab is closed by accident, the user can find that whatever they spent their precious time typing is still there in the form when they revisit the URL later.
Thank you for reading 5 articles this month* Join now for unlimited access
Enjoy your first month for just £1 / $1 / €1
*Read 5 free articles per month without a subscription
Join now for unlimited access
Try first month for just £1 / $1 / €1
The Creative Bloq team is made up of a group of design fans, and has changed and evolved since Creative Bloq began back in 2012. The current website team consists of eight full-time members of staff: Editor Georgia Coggan, Deputy Editor Rosie Hilder, Ecommerce Editor Beren Neale, Senior News Editor Daniel Piper, Editor, Digital Art and 3D Ian Dean, Tech Reviews Editor Erlingur Einarsson and Ecommerce Writer Beth Nicholls and Staff Writer Natalie Fear, as well as a roster of freelancers from around the world. The 3D World and ImagineFX magazine teams also pitch in, ensuring that content from 3D World and ImagineFX is represented on Creative Bloq.