Skip to content

Instantly share code, notes, and snippets.

@aarongustafson
Last active October 14, 2016 14:06
Show Gist options
  • Save aarongustafson/6bfc19e968a08e692d37ccbadaa05db8 to your computer and use it in GitHub Desktop.
Save aarongustafson/6bfc19e968a08e692d37ccbadaa05db8 to your computer and use it in GitHub Desktop.
Saves form data to `localStorage`
if ( window.localStorageAvailable )
{
window.localStorage.removeItem( 'FORM URL GOES HERE' );
}
(function(window,document){
function storageAvailable(type) {
try {
var storage = window[type],
x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
}
catch(e) {
return false;
}
}
window.localStorageAvailable = storageAvailable('localStorage');
if ( ! ( 'querySelector' in document ) ||
! window.localStorageAvailable ) {
return;
}
function formSaver( $form )
{
var page_key = window.location.toString(),
$fields = $form.querySelectorAll('input:not([disabled]),select:not([disabled]),textarea:not([disabled])'),
count,
$field,
data = {},
typing = false,
// Custom event in case you want to do something when a form is re-populated
update_evt = document.createEvent('Event');
update_evt.initEvent('formSaverk::updated', true, true);
// Field functions
function getValue( $field )
{
// console.log('getting a value for',$field);
var type = $field.type,
value,
$related_fields,
len;
switch ( type )
{
case 'radio':
// console.log('radio');
value = document.querySelector( '[name=' + $field.name + ']:checked' ).value;
break;
case 'checkbox':
// console.log('checkbox');
value = [];
$related_fields = document.querySelectorAll( '[name="' + $field.name + '"]:checked' );
len = $related_fields.length;
while ( len-- )
{
value.push( $related_fields[len].value );
}
break;
default:
// console.log('everything else');
value = $field.value;
break;
}
return value;
}
function setValue( $field, value )
{
var type = $field.type,
len;
switch ( type )
{
case 'radio':
document.querySelector( '[name=' + $field.name + '][value="' + value + '"]' ).checked = true;
break;
case 'checkbox':
if ( value.constructor == Array )
{
len = value.length;
while ( len-- )
{
document.querySelector( '[name=' + $field.name + '][value="' + value[len] + '"]' ).checked = true;
}
}
break;
default:
$field.value = value;
break;
}
}
// Form actions
function save() {
// console.log('saving');
count = $fields.length;
while ( count-- )
{
$field = $fields[count];
data[$field.name] = getValue( $field );
}
window.localStorage.setItem( page_key, JSON.stringify( data ) );
}
function reload() {
// console.log('reloading');
count = $fields.length;
data = window.localStorage.getItem( page_key );
if ( data )
{
data = JSON.parse( data );
while ( count-- )
{
$field = $fields[count];
setValue( $field, data[$field.name] );
}
// fake change event
$form.dispatchEvent( update_evt );
}
else
{
data = {};
}
}
// Event Handlers
function throttleKeydownSave()
{
if ( typing )
{
// console.log('typing');
clearTimeout( typing );
typing = null;
}
typing = setTimeout( doneTyping, 300 );
}
function doneTyping() {
// console.log('done typing');
clearTimeout( typing );
typing = null;
save();
}
$form.addEventListener( 'keydown', throttleKeydownSave, false );
$form.addEventListener( 'change', save, false );
$form.addEventListener( 'blur', save, false );
// init
reload();
}
}(this,this.document));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment