Created
September 3, 2019 07:55
-
-
Save quinncomendant/19cd48840dee1ee5f2c5c3819ace4660 to your computer and use it in GitHub Desktop.
Autosave module makes it easy to save and load form values in localStorage.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Maintain state of form values across page loads with localStorage. | |
// | |
// eslint-disable-next-line no-unused-vars | |
var Autosave = (function ($) { | |
'use strict'; | |
// | |
// Options | |
// | |
var options = { | |
prefix: null, // Prefix of localStorage key names, e.g., 'myapp-', or use NULL to use default 'autosave-'. | |
context: '', // Selector of a parent container, e.g., '#form1'. | |
interval: 3e3, // Frequency of autosaves. | |
timeout: 86400e3, // 24 hours - time after which the user will be prompted before restoring saved data. | |
expiration: 2678400e3, // 31 days - time after which saved data will be deleted without prompt. | |
fields: null, // Array of form input names to save. | |
loaded: function () {} // Callback to run after form data has been loaded (restored from localStorage). | |
}; | |
// Object for dynamic messaging. | |
var sc_msg = new Strangecode.Msg(); | |
// | |
// Set up objects and event listeners. | |
// Run this after document.ready, and before running any other methods here. | |
// | |
var init = function (new_options) { | |
options = $.extend(options, new_options || {}); | |
// Only execute on pages which contain the DOM elements specified in context. | |
if (options['context'] && !$(options['context']).length) { | |
return; | |
} | |
// iOS Safari in Private Browsing mode is unable to use localStorage. Tell the user they must use a normal browsing window. | |
try { | |
localStorage.setItem('localStorage-avaliable-test', null); | |
} catch (e) { | |
sc_msg.raise(_("It appears are in Private Browsing mode. You will need to <a href=\"https://support.apple.com/en-us/HT203036\">disable Private Browsing mode</a> before using this website."), 'alert'); | |
Log.err('Client appears to be in Private Browsing mode', Log.ln()); | |
} | |
if (typeof(Storage) === 'undefined') { | |
sc_msg.raise(_("Your browser does not appear to support localStorage, probably because it’s outdated. You will need to <a href=\"http://browsehappy.com/\">upgrade your browser</a> before using this website."), 'alert'); | |
Log.err('Client does not support localStorage', Log.ln()); | |
} | |
if (null === options['prefix']) { | |
options['prefix'] = 'autosave-'; | |
} | |
}; | |
// | |
// Begin autosaving. | |
// | |
var run = function () { | |
// Only execute on pages which contain the DOM elements specified in context. | |
if (options['context'] && !$(options['context']).length) { | |
return; | |
} | |
var now = Date.now(); | |
if (_get('last-saved') && _get('last-saved') < now - options['expiration']) { | |
// Reset the form if the last saved timestamp exists and the timestamp is older than the expiration threshold. | |
reset(); | |
} else if (_get('last-saved') && _get('last-saved') < now - options['timeout']) { | |
// Prompt to load the form if the last saved timestamp exists and the timestamp is older than the timeout threshold. | |
if (confirm(_("Would you like to continue editing the form that was autosaved {1}? Clicking ‘Cancel’ will erase the saved form data.".format(new Date(+_get('last-saved')).toLocaleString())))) { | |
_load(); | |
} else { | |
reset(); | |
} | |
} else { | |
// Just load the form. | |
_load(); | |
} | |
// Regularly save the form fields at a set interval. | |
setInterval(function () { | |
save(); | |
}, options['interval']); | |
// Instantly save the form fields when the user leaves the page. | |
$(window).on('beforeunload', function () { | |
save(); | |
}); | |
}; | |
// | |
// Save all fields now. | |
// | |
var save = function (allowempty) { | |
// Optional function argument. | |
allowempty = typeof allowempty !== 'undefined' ? allowempty : false; | |
// Only execute on pages which contain the DOM elements specified in context. | |
if (options['context'] && !$(options['context']).length) { | |
return; | |
} | |
var saved = false; | |
// Loop through all the specified form fields. | |
for (var i = 0; i < options['fields'].length; i++) { | |
var f = options['fields'][i]; | |
// Select each form field by its name. | |
$('input[name="' + f + '"]', $(options['context'])).each(function () { | |
// If there is a value and it is not an empty JSON string, then save the value to local storage. | |
if (allowempty || $(this).val() && $(this).val() !== '[]') { | |
_set(f, $(this).val()); | |
saved = true; | |
} | |
}); | |
} | |
if (saved) { | |
// Only save a last saved timestamp is some value was saved. | |
_set('last-saved', Date.now()); | |
} | |
}; | |
// | |
// Reset all form fields to empty. | |
// | |
var reset = function () { | |
// Only execute on pages which contain the DOM elements specified in context. | |
if (options['context'] && !$(options['context']).length) { | |
return; | |
} | |
for (var i = 0; i < options['fields'].length; i++) { | |
localStorage.removeItem(options['prefix'] + options['fields'][i]); | |
} | |
// Set the last saved timestamp to null so that the timeout prompt will not trigger. | |
_set('last-saved', null); | |
}; | |
// | |
// Set a localStorage value | |
// | |
var _set = function (k, v) { | |
try { | |
localStorage.setItem(options['prefix'] + k, v); | |
} catch (e) { | |
sc_msg.raise(_("An error occurred while saving. Please try again, or restart your browser."), 'alert'); | |
Log.err('localStorage quota exceeded or user in Private Browsing mode', Log.ln()); | |
} | |
}; | |
// | |
// Get a localStorage value | |
// | |
var _get = function (k) { | |
return localStorage.getItem(options['prefix'] + k); | |
}; | |
// | |
// Load saved data into form fields. | |
// | |
var _load = function () { | |
// Loop through all the specified form fields. | |
for (var i = 0; i < options['fields'].length; i++) { | |
var f = options['fields'][i]; | |
// Select each form field by its name. | |
$('input[name="' + f + '"]', $(options['context'])).each(function () { | |
// If we can get a value and the current field is empty or contains an empty JSON string, then set the form field to the saved localStorage value. | |
if (_get(f) && (!$(this).val() || $(this).val() === '[]')) { | |
$(this).val(_get(f)); | |
} | |
}); | |
} | |
options['loaded'](); | |
}; | |
// | |
// Reveal module functions. | |
// | |
return { | |
init: init, | |
run: run, | |
save: save, | |
reset: reset | |
}; | |
}(jQuery)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment