{"id":1716,"date":"2013-09-15T13:31:19","date_gmt":"2013-09-15T13:31:19","guid":{"rendered":"http:\/\/www.sitekickr.com\/blog\/?p=1716"},"modified":"2015-02-06T21:42:50","modified_gmt":"2015-02-06T21:42:50","slug":"persisting-form-field-data-page-loads","status":"publish","type":"post","link":"https:\/\/www.sitekickr.com\/blog\/persisting-form-field-data-page-loads\/","title":{"rendered":"Persisting form field data between page loads"},"content":{"rendered":"<p>Persisting the information in form fields is a nice usability enhancement. Users do close pages unintentionally, so it&#8217;s a welcomed surprise when they return to the page to find their information intact.<\/p>\n<p>This capability has always been available through AJAX\/server-side databases or the use of cookies. But setting up database tables to collect incomplete submissions for each form on a site often doesn&#8217;t fit into our budgets. Cookies work great for only very small amounts of data, as they increase the size of each page request with each new piece of data.<\/p>\n<p>Now, with the adoption of HTML 5 by over 80% of user&#8217;s web browsers, we have access to another technique, local storage. This allows us to use JavaScript to store individual pieces of information inside the browser&#8217;s internal database.<\/p>\n<p>&nbsp;<\/p>\n<h3>Getting the storage key<\/h3>\n<p>One easy way to do this is to create a storage key for each form on your site. The storage key can essentially be a modified version of the page URL.<\/p>\n<p><code>var storageKey = location.href.split('?')[0].split('\/').splice(3).join('_');<\/code><\/p>\n<p>That will give us a key name similar to:<\/p>\n<p><code>section1_subsection_pagename<\/code><\/p>\n<p>&nbsp;<\/p>\n<h3>Serializing the form data<\/h3>\n<p>Now that we have our storage key, we want to store all of the form field data under that key name. We can do that by serializing the form data into a string. jQuery&#8217;s serialize method does the job nicely for us. And, since we&#8217;re trying to save form data for the next page load, the best time to store the existing form field data is during the window unload event.<\/p>\n<p><code>$(window).unload(function() {<br \/>\nwindow.localStorage.setItem(storageKey, $('#myform').serialize());<br \/>\n});<\/code><\/p>\n<p>&nbsp;<\/p>\n<h3>Loading the data back into the form<\/h3>\n<p>Unfortunately, jQuery doesn&#8217;t provide us with a deserialize function. So, I slightly modified <a href=\"http:\/\/stackoverflow.com\/questions\/6992585\/jquery-deserialize-form\/16215183#16215183\" target=\"_blank\">Jack Allan&#8217;s version of a deseralize function<\/a>, to deserialize the form data string and load it back into the form.<\/p>\n<pre class=\"prettyprint linenums\"><code>deserialize = function(query) {\r\n    var pairs, i, keyValuePair, key, value, map = {};\r\n\r\n    \/\/ remove leading question mark if its there\r\n    if (query.slice(0, 1) === '?') {\r\n        query = query.slice(1);\r\n    }\r\n\r\n    if (query !== '') {\r\n        pairs = query.split('&amp;');\r\n\r\n        for (i = 0; i &lt; pairs.length; i += 1) {\r\n            keyValuePair = pairs[i].split('=');\r\n            key = decodeURIComponent(keyValuePair[0]);\r\n            value = (keyValuePair.length &gt; 1) \r\n                    ? decodeURIComponent(keyValuePair[1]) : undefined;\r\n\r\n<\/code><code><code>            \/\/ this is the magic, loads the value into the form field<\/code>\r\n            <strong>$('input[name=' + key + ']').val(value);<\/strong>\u00a0 \r\n        }\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h3>Protecting older browsers<\/h3>\n<p>Back to our point above about the 80% browser share, that&#8217;s 20% that won&#8217;t be able to make use of this feature, yet. Furthermore, it&#8217;ll throw a JavaScript error if they try.<\/p>\n<p>We can prevent this by wrapping our local storage usage in a conditional, which first checks to see if the Storage module is available.<\/p>\n<pre class=\"prettyprint linenums\"><code>if (typeof Storage !== 'undefined') {\r\n    deserialize(window.localStorage.getItem(storageKey));\r\n\r\n    $(window).unload(function() {\r\n         window.localStorage.setItem(storageKey, $('#myform').serialize());\r\n    });\r\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Maintaining the values in form fields between browser sessions has never been easier with HTML 5 Storage. It can go a long way towards enhancing the usability of your forms.<\/p>\n","protected":false},"author":1,"featured_media":1719,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"amp_status":""},"categories":[238,5],"tags":[82,248],"_links":{"self":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/1716"}],"collection":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/comments?post=1716"}],"version-history":[{"count":7,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/1716\/revisions"}],"predecessor-version":[{"id":2420,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/1716\/revisions\/2420"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/media\/1719"}],"wp:attachment":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/media?parent=1716"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/categories?post=1716"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/tags?post=1716"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}