Skip to content

Instantly share code, notes, and snippets.

@zaus
Last active January 13, 2023 01:38
Show Gist options
  • Save zaus/4717416 to your computer and use it in GitHub Desktop.
Save zaus/4717416 to your computer and use it in GitHub Desktop.
Preserve form values across page loads -- i.e. persistent forms. Uses `localStorage` to persist, `jQuery` for utilities.
var FormRepo = function (namespace) {
/// <summary>Persistent form values, saves to localStorage</summary>
/// <param name="namespace" type="String">the namespace to store values in localStorage</param>
// should also protect per page, since we could have the same forms in various places
this.N = namespace + '.' + window.location.pathname;
};
$.extend(FormRepo.prototype, {
namespace: function (key) {
return this.N + '.' + key;
}
,
preserve: function ($form, iden) {
var data = $form.serializeArray();
localStorage.setItem(this.namespace( 'form.' + (iden || $form.index()) ), JSON.stringify( data ));
}
,
restore: function ($form, iden) {
var data = localStorage.getItem(this.namespace('form.' + (iden || $form.index())));
if (null == data || $.isEmptyObject(data)) return; // nothing to do
$.each(JSON.parse(data), function (i, kv) {
// find form element, set its value
var $input = $form.find('[name=' + kv.name + ']');
// how to set it's value?
if ($input.is(':checkbox') || $input.is(':radio')) {
$input.filter(function () { return $(this).val() == kv.value; }).first().attr('checked', 'checked');
}
else {
$input.val(kv.value);
}
});
}//-- fn restore
,
remove: function ($form, iden) {
localStorage.removeItem(this.namespace('form.' + (iden || $form.index())));
}//-- fn remove
,
all: function () {
var allData = {};
for (var i = 0, l = localStorage.length; i < l; i++) {
allData[localStorage.key(i)] = localStorage.getItem( localStorage.key(i) );
}
return allData;
}//-- fn repo.all
});
<form id="input" action="#">
<!--
div.field>(label[for=INPUT]{INPUT}+textarea#INPUT[name=INPUT])
div.field>(label[for=INPUT]{INPUT}+input#INPUT[name=INPUT][type=text])
-->
<div class="field wide">
<label for="url">Url</label>
<input type="text" name="url" id="url" />
</div>
<div class="field wide">
<label for="format">Format</label>
<select id="format" name="format" class="selectControl"
title="Select form encoding">
<option value="">
Add new...
</option>
<option value="application/atom+xml">
application/atom+xml
</option>
<option value="application/json" selected="selected">
application/json
</option>
<option value="application/x-www-form-urlencoded">
application/x-www-form-urlencoded
</option>
<option value="application/xml">
application/xml
</option>
<option value="multipart/form-data">
multipart/form-data
</option>
<option value="text/html">
text/html
</option>
<option value="text/plain">
text/plain
</option>
</select>
</div>
<div class="field">
<label for="payload">Payload</label>
<textarea name="payload" id="payload" cols="30" rows="10"></textarea>
</div>
<!--
div.field>fieldset.radios>(legend>(span{Submission Style})+ul>(li.field>(input#submit-regular[name=submission][type=radio][value=regular]+label[for=submit-regular]{Regular}))*2)
-->
<div class="field">
<fieldset class="radios">
<legend><span>Submission Style</span></legend>
<ul>
<li class="field">
<input type="radio" id="submit-regular" name="submission" value="regular"/>
<label for="submit-regular">Regular</label>
</li>
<li class="field">
<input type="radio" id="submit-dotnet" name="submission" value="dotnet" checked="checked" />
<label for="submit-dotnet">.NET</label>
</li>
</ul>
</fieldset>
</div>
<input type="submit" value="Send" />
<pre id="output">
</pre>
</form>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="FormRepo.js"></script>
<script>
var $form = $('#input')
, $output = $('#output')
, repo = new FormRepo('restclient')
;
// get the last submitted values back
repo.restore($form/*, $form.attr('id')*/ ); // don't necessarily need an identifier
$form.submit(function (e) {
// preserve the last submitted values
repo.preserve($form/*, $form.attr('id')*/ ); // don't necessarily need an identifier
});
console.log( repo.all() );
</script>
@jimepler
Copy link

I need more documentation on how to use this script. How would I apply this script to a form I've already built? Does my form need to have id changed to "input?" Do I need to add/change my labels so that they are the same as the ones shown in the sample form? I'm assuming I need to add the pre id output to my form? Do I need to add fieldset tags? What about the divs? Are they needed for the script to work? Many, many questions that are unanswered.

@thorstenfriesen
Copy link

Thanks!

for supporting input names like "name[firstname]"
FormRepo.js (Line 25):

var $input = $form.find('[name="' + kv.name + '"]');

@uomopalese
Copy link

Hi, nice job.
Please i need a pattern for input name like <input type="text" name="linea[1][Quantita]" /> to output arrays of elements, I'm trying to do it by myself, but i'm not so skilled...

@claudiocacciotti
Copy link

Hi,
thanks for this but when I follow your usage example on Firefox 45.01 using jQuery 1.11 I get the following error:

"TypeError: FormRepo is not a constructor" pointing to the following line in your example:
, repo = new FormRepo('restclient') as the culprit.

Any clues?

@p4535992
Copy link

p4535992 commented Feb 24, 2017

Beautiful, you save me a lot of time, ty very much

@FThompson
Copy link

This script is nice! Unfortunately I wrote my own before finding yours.

In case anyone is interested: https://github.com/FThompson/FormPersistence.js

@tchesney
Copy link

tchesney commented Jun 12, 2020

Any idea on how to make this work for multiselect fields? In chrome, the js works as expected, but in Firefox (77.0.1), only the last item of the multiselect is retained, the other options are dropped even though they are in localStorage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment