Automatically Saving Form Values In localStorage Cache

As part of the rewrite of a major application process for a client, they have requested the ability to navigate away from the form and come back to finish later. We suggested using database storage at the server, but it was declined as they did not want to use logins, and IP based retrieval could be less secure than desired. They did however, jump at the ability to save data permanently in the user's browser allowing them to come back at need, potentially even year over year. Thus began a small foray into auto persisting forms using localStorage. There's way more to the application than is represented here, but I've pulled the auto-saving piece out as I find it extremely useful in a generic sense.

I've created a small framework, mostly to designate a place for data to be kept for easy saving. As a handy side note, this also makes sending the same saved data to the server for login based persistence, or form processing a breeze. Using this code, any input, select, textarea, or button with a name when changed will automatically write the full contents of form data into localStorage. Loading the page again will automatically put all values back as they belong, and fire change events along the way ensuring most form bound behaviors are triggered. The data object is rather extensible. Using a different namespace such as application.storage.data.addresses, you can keep other sorts of data, I'm using that for a seperate address book among other things.

  1. application = {
  2.   ready: function(){
  3.     application.storage.ready();
  4.     application.form.ready();
  5.   }
  6. }
  7. application.storage = {
  8.   data: null
  9.   ,ready: function(){
  10.     try {
  11.       // Pull our data object out of cache
  12.       cache = localStorage.getItem('school.enrollment.data');
  13.       if( cache == null ){
  14.         // Create it if it does not yet exist
  15.         application.storage.data = {};
  16.         application.storage.persist();
  17.       } else {
  18.         // Recreate the object from the stored JSON
  19.         application.storage.data = JSON.parse(cache);
  20.       }
  21.     } catch (err) { console.debug('Local Storage error', err); }
  22.   }
  23.   ,persist: function(){
  24.     try {
  25.       // Store the entire data object into local storage as is
  26.       localStorage.setItem('school.enrollment.data', JSON.stringify(application.storage.data) );
  27.     } catch (err) { console.debug('Local Storage error', err); }
  28.   }
  29. }
  30. application.form = {
  31.   fields: {}
  32.   ,ready: function(){
  33.     // Bind form behaviors
  34.    
  35.     // Ensure this form's storage namespace exists
  36.     if( 'form' in application.storage.data == false ){
  37.       application.storage.data.form = {};
  38.     }
  39.     // Load stored values we placed into form
  40.     for(var name in application.storage.data.form){
  41.       var value = application.storage.data.form[name];
  42.       var $element = jQuery('[name="' + name +'"]');
  43.       var elementTag = $element[0].nodeName.toLowerCase();
  44.       switch( elementTag ){
  45.         case 'button':
  46.           continue;
  47.         default:
  48.           switch( $element.attr('type') ){
  49.             case 'submit':
  50.               continue;
  51.             case 'radio':
  52.             case 'checkbox':
  53.               // Check the radio or checkbox associated with this stored value
  54.               // TODO see what happens if I've stored multiple checkbox values for one name..
  55.               // Fire a change event in case the form behaviors above change based on this field
  56.               jQuery('[name="' + name +'"][value="' + value + '"]').attr('checked', 'checked').change();
  57.               continue;
  58.             default:
  59.               // Insert our value
  60.               // Fire a change event in case the form behaviors above change based on this field
  61.               $element.val( value ).change();
  62.               continue;
  63.           }
  64.       }
  65.     }
  66.    
  67.     // Bind auto-save behavior
  68.     jQuery('input[name], select[name], textarea[name], button[name]').change(application.form.fieldChanged);
  69.   }
  70.   ,fieldChanged: function(event){
  71.     var $this = jQuery(this);
  72.     var elementTag = this.nodeName.toLowerCase();
  73.     switch( elementTag ){
  74.       case 'button':
  75.         return;
  76.       default:
  77.         switch( $this.attr('type') ){
  78.           case 'submit':
  79.             return;
  80.           default:
  81.             var value = $this.val();
  82.         }
  83.     }
  84.     var name = $this.attr('name');
  85.     // Store all form data points into our storage namespace
  86.     application.storage.data.form[name] = value;
  87.     // Write to localStorage cache
  88.     application.storage.persist();
  89.   }
  90. }
  91.  
  92. jQuery(document).ready(application.ready);

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.