Home arrow HTML arrow Page 2 - How To Autosave Web Forms in HTML5
HTML

How To Autosave Web Forms in HTML5


In this penultimate part of the series, I demonstrate how to implement a working web form autosaving program, thanks to the functionality provided by the “localStorage” HTML5 object. Even though it's simple, this example shows how to utilize the object in a pretty realistic use case.

Author Info:
By: Alejandro Gervasio
Rating: 4 stars4 stars4 stars4 stars4 stars / 14
January 31, 2011
TABLE OF CONTENTS:
  1. · How To Autosave Web Forms in HTML5
  2. · Autosaving with some JavaScript functions

print this article
SEARCH DEVARTICLES

How To Autosave Web Forms in HTML5 - Autosaving with some JavaScript functions
(Page 2 of 2 )

In reality, the web form autosaver that I plan to implement here will be composed of two JavaScript functions. They will perform well-differentiated tasks. The first one will be responsible for restoring the state of the target form, or in other words, for repopulating the form with the data previously entered in it. The second one, on the other hand, will take care of saving this data to the local storage, a process that will be executed at a specified time interval.

If my explanation sounds somewhat confusing to you, then focus your attention on the functions defined below, which hopefully will clear things up. First, here is the function that retrieves the state of the form:

// get the state of the form
function getFormState() {
    var fields = document.getElementsByTagName('form')[0].elements;
    if (fields.length == 0){return};
    for (var i = 1; i <= fields.length-1; i++) {
        var name = fields[i].getAttribute('name');
        if (name in localStorage && localStorage[name] !== null) {
            fields[i].value = localStorage[name];
        }
    }
}

As I just said, all that the "getFormState()" function does is iterate over each field of the form and check for a property in the local storage associated to it. If there is a property, the target field is repopulated with the value assigned to this property. That was really simple to read, wasn't it?  

And now that you grasped the underlying logic of the previous function, it's time to show the definition of its counterpart, which is tasked with saving the data entered in the form in the local storage. For obvious reasons, I called this brand new function "saveFormState()" and its source code is as follows:

// save the state of the form
function saveFormState() {
    var fields = document.getElementsByTagName('form')[0].elements;
    if (fields.length == 0){return};
    var populated = false;
    for (var i = 1; i <= fields.length-1; i++) {
        var name = fields[i].getAttribute('name');
        if (fields[i].value != '' && fields[i].getAttribute('type') != 'submit') {
           localStorage[name] = fields[i].value;
           populated = true;
        }
    }
    // display the time form data was saved (optional)
    if (populated) {
        var date = new Date();
        var hours = date.getHours();
        var mins = date.getMinutes();
        var secs = date.getSeconds();
        hours = (hours < 10) ? '0' + hours : hours;
        mins = (mins < 10) ? '0' + mins : mins;
        secs = (secs < 10) ? '0' + secs : secs;
        var msg = '[Form data was saved at ' + hours + ':' + mins + ':' + secs + ']';
        var timecont = document.getElementById('time_container');
        if (timecont !== null) {
            timecont.innerHTML = msg;
        }
        else {
            timecont = document.createElement('span');
            timecont.setAttribute('id', 'time_container');
            timecont.appendChild(document.createTextNode(msg));
            document.getElementsByTagName('fieldset')[0].appendChild(timecont);
        }
    }
}

Don't feel intimidated by the rather lengthy definition of the above function, since its inner working is quite easy to follow, trust me. Simply put, the function loops over each field of the target form and then saves the value entered in it in a different property of the local storage. Finally (and this step is entirely optional), the date at which the form was saved is displayed at the bottom of the form, thanks to some basic DOM manipulation.

So far, so good. Having already defined the two functions that store and retrieve the state of an HTML form via the local storage, the next step that must be taken is including the functions into the web page previously defined. In this way, you can see how they can be put to work side by side and implement the "autosaving" feature mentioned at the beginning.

This will be done in the next section, so keep reading.     

The finished version of the autosaver

If you're anything like me, you want to see how the two functions shown earlier can be used for "autosaving" a specific HTML form. Below I listed the source files corresponding to this sample application.

First, here's the web page that renders the sample contact form:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Autosaving a web form with HTML5 local Storage</title>
<script src="autosaver.js"></script>
<link rel="stylesheet" type="text/css" href="default.css" />
</head>
<body>
<div id="wrapper">
    <header>
        <h1>Contact us now!</h1>
    </header>   
    <nav>
        <ul>
            <li><a href="#">About Us</a></li>
            <li><a href="#">Services</a></li>
            <li><a href="#">Products</a></li>
            <li><a href="#">Blog</a></li>
            <li><a href="#">Contact</a></li>
        </ul>
    </nav>
    <section>
        <form action="processform.php" method="post">
            <fieldset>
                <ol>
                    <li>
                        <label for="subject">Subject: <em>[required]</em></label>
                        <input type="text" name="subject" id="subject" class="text" />
                    </li>
                    <li>
                        <label for="email">Email: <em>[required]</em></label>
                        <input type="email" name="email" id="email" class="text" />
                    </li>
                    <li>
                        <label for="comments">Comments:</label>
                        <textarea rows="10" cols="20" name="comments"></textarea>
                    </li>
                    <li>
                        <input type="submit" name="send" value="Submit" />
                    </li>
                </ol>
            </fieldset>
        </form>
    </section>
    <footer>
        <h2>Footer section</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse auctor commodo risus, et ultrices sapien vestibulum non. Maecenas scelerisque quam a nulla mattis tincidunt. Etiam massa libero, pharetra vel laoreet et, ultrices non leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed posuere ullamcorper lacus et sollicitudin. Morbi ultrices condimentum lacus, sit amet venenatis purus bibendum sit amet.</p>
    </footer>
</div>
</body>
</html>

Done. You probably noticed that the above web page includes a JavaScript file called "autosaver.js." In fact, this file encapsulates the functions just created. Before I show you how it looks, however, let me show you the CSS styles that define the visual presentation of this page. Here they are:

(default.css)

/* layout styles */
body {
    padding: 0;
    margin: 0;
    background: #0C2478;
    font: 0.8em Arial, Helvetica, sans-serif;
    color: #000;
}
#wrapper {
    width: 960px;
    margin: 0 auto;
    background: #fff;
}
header {
    display: block;
    padding: 20px;
}
nav {
    display: block;
    width: 920px;
    height: 30px;
    margin: 0 auto;
    padding-top: 10px;
    background: #eee;
}
nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
}
nav ul li {
    float: left;
    width: 120px;
    text-align: center;
}
nav ul li a {
    display: block;
    width: 120px;
    text-decoration: none;
    color: #000;
    border-right: 1px solid #ccc;
}
section {
    display: block;
    padding: 20px;
}
footer {
    display: block;
    padding: 20px;
}
/* form styles */
form {
    width: 280px;
    padding: 30px;
    background: #dfefff;
}
form fieldset {
    border: none;
}
form fieldset ol {
    list-style: none;
    padding: 0;
    margin: 0;
}
form fieldset ol li {
    margin-bottom: 10px;
}
form fieldset ol label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}
form fieldset ol label em {
    font-style: normal;
    font-weight: normal;
    color: #00f;
}
form fieldset ol input.text {
    width: 250px;
}
form fieldset ol textarea {
    width: 250px;
}
/* time container */
#time_container {
    color: #00f;
}

Even though the previous CSS styles are pretty self-explanatory, keep in mind that most of them won't work in IE, as it doesn't offer support for many of the new HTML5 elements. So, be aware of this issue, especially if you're planning to test the earlier web page using Microsoft's browser.

Having clarified that point, here's the definition of the aforementioned "autosaver.js" file, which puts the "autosaving" feature in action: 

(autosaver.js)

// get the state of the form
function getFormState() {
    var fields = document.getElementsByTagName('form')[0].elements;
    if (fields.length == 0){return};
    for (var i = 1; i <= fields.length-1; i++) {
        var name = fields[i].getAttribute('name');
        if (name in localStorage && localStorage[name] !== null) {
            fields[i].value = localStorage[name];
        }
    }
}

// save the state of the form
function saveFormState() {
    var fields = document.getElementsByTagName('form')[0].elements;
    if (fields.length == 0){return};
    var populated = false;
    for (var i = 1; i <= fields.length-1; i++) {
        var name = fields[i].getAttribute('name');
        if (fields[i].value != '' && fields[i].getAttribute('type') != 'submit') {
           localStorage[name] = fields[i].value;
           populated = true;
        }
    }
    // display the time form data was saved (optional)
    if (populated) {
        var date = new Date();
        var hours = date.getHours();
        var mins = date.getMinutes();
        var secs = date.getSeconds();
        hours = (hours < 10) ? '0' + hours : hours;
        mins = (mins < 10) ? '0' + mins : mins;
        secs = (secs < 10) ? '0' + secs : secs;
        var msg = '[Form data was saved at ' + hours + ':' + mins + ':' + secs + ']';
        var timecont = document.getElementById('time_container');
        if (timecont !== null) {
            timecont.innerHTML = msg;
        }
        else {
            timecont = document.createElement('span');
            timecont.setAttribute('id', 'time_container');
            timecont.appendChild(document.createTextNode(msg));
            document.getElementsByTagName('fieldset')[0].appendChild(timecont);
        }
    }
}

// run the above functions when the web page is loaded
window.onload = function () {
    // check if HTML5 localStorage is supported by the browser
    if ('localStorage' in window && window['localStorage'] !== null) {
        // get the form state
        getFormState();
        // save the state of the form each 15 seconds (customizable)
        setInterval('saveFormState()', 15 * 1000);
    }
}

As you can see in the above code fragment, the data entered in the sample contact form will be saved each 15 seconds (note the invocation of the "saveFormState()" function inside the "setInterval" timer). This value can be modified to suit more specific requirements. Feel free to modify this parameter if you need to either defer or speed up the storage process.

All in all, having already shown all of the source files that make up the "autosaving" program, it's time to give it a try and see how it works. To do so, make sure that there's at least one tab open in your browser. Then, open a new one and run the web page containing the contact form. As soon as you start filling it in, the typed data will be saved to the local storage, and a message will inform you of this action each 15 seconds.

Now, close that tab and reopen it after a while; you should see the form already repopulated with the data that you previously typed in. What's more, the output generated by this process is depicted by the following image:  

Not too bad, huh? Considering that building this "autosaver" only took writing a couple of straightforward JavaScript functions, the result is more than acceptable. Plus, you have the freedom to tweak the program in all sorts of ways to fit your personal preferences. So, go ahead and start playing with it. It'll be fun!

Final thoughts

In this penultimate part of the series, I demonstrated how to implement a working web form autosaving program, thanks to the functionality provided by the "localStorage" HTML5 object. Even though it's  simple, this example showed in a nutshell how to utilize the object in a pretty realistic use case.

Moving on, if you're a strong advocate of optimizing your JavaScript files, the last installment will hopefully catch your attention. I'll be illustrating how to reduce the size of the earlier "autosaver.js" file by means of Google's closure compiler.

Don't miss the final part! 


DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

blog comments powered by Disqus
HTML ARTICLES

- Does HTML5 Need a Main Element?
- Revisiting the HTML5 vs. Native Debate
- HTML5: Not for Phone Apps?
- HTML5 or Native?
- Job Hunting? Freelancer.com Lists This Quart...
- HTML5 in the News
- Report: HTML5 Mobile Performance Lags
- The Top HTML5 Audio Players
- Top HTML5 Video Tutorials
- HTML5: Reasons to Learn and Use It
- More of the Top Tutorials for HTML5 Forms
- MobileAppWizard Releases HTML5 App Builder
- HTML5 Boilerplate: Working with jQuery and M...
- HTML5 Boilerplate Introduction
- New API Platform for HTML5

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2018 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials