var $searchesList = $('#searches-list');
var $form = $('#form');
var searches = window.localStorage.getItem('searches');
function buildSearchesList(searches, $searchesList, $form) {
$searchesList.empty();
// Loops over each previous search to create a list shown to the user.
// Each item of the list shown will display as a mnemonic name the
// value of the main field, and a sublist containing all the fields
// of the form displayed only when the user hovers or focuses on
// the mnemonic name.
// Every time the user clicks, or press ENTER or SPACE on an item
// of the list, the form is autofilled using the selected set of values.
for (var i = 0; i < searches.length; i++) {
// Converts each item in the list retrieved from the local storage
// into a JSON-parsable string and then convert it into its
// equivalent object.
var params = JSON.parse('{"' +
decodeURIComponent(
searches[i]
.replace(/&/g, '","')
.replace(/=/g, '":"')
.replace(/\+/g, ' ')
) +
'"}'
);
// Creates the sublist containing all the fields of the form
var text = '<dl>';
for (var key in params) {
text += '<dt>' + key + ':</dt><dd> ' + params[key] + '</dd>';
}
text += '</dl>';
// Adds the sublist to the main list and add the event handler
// for the click and the keypress events
(function(searchData) {
$searchesList.append(
$('<li tabindex="0">')
.text(params['search'])
.on('click keypress', function(event) {
if (
event.type !== 'keypress' ||
event.keyCode === 13 ||
event.keyCode === 32
) {
$form
.trigger('reset')
.deserialize(searchData);
}
})
.append(text)
);
})(searches[i]);
}
}
searches = (searches === null) ? [] : JSON.parse(searches);
buildSearchesList(searches, $searchesList, $form);
$form.submit(function(event) {
// The demo doesn't have a server page to which sending the request,
// so this statement avoid the request
event.preventDefault();
// The last performed search is at the top of the list.
// Besides, the demo avoid storing the same
// search multiple times, so the code searches for duplicates and
// removes them. Finally, the demo stores a maximum of 10 searches per user.
var currentSearch = $(this).serialize();
searches.unshift(currentSearch);
// Removes the duplicates
for(var i = 1; i < searches.length; i++) {
if (searches[0] === searches[i]) {
searches.splice(i, 1);
}
}
// Stores only the last 10 searches
if (i === searches.length && searches.length > 10) {
searches.pop();
}
// Stores the new list into the local storage
window.localStorage.setItem('searches', JSON.stringify(searches));
buildSearchesList(searches, $searchesList, $form);
});
<div class="side">
<h1>Test form</h1>
<form name="form" id="form">
<label for="search">This is the main search field:</label>
<input type="search" name="search" id="search" />
<label for="text">This a text field:</label>
<input type="text" name="text" id="text" />
<label for="email">This an email field:</label>
<input type="email" name="email" id="email" />
<label>This a set of checkbox:</label>
<label>
Checkbox1:
<input type="checkbox" name="checkbox[]" value="checkbox1" />
</label>
<label>
Checkbox2:
<input type="checkbox" name="checkbox[]" value="checkbox2" />
</label>
<label>This a set of radio buttons:</label>
<label>
Radio1:
<input type="radio" name="radio" value="radio1" checked />
</label>
<label>
Radio2:
<input type="radio" name="radio" value="radio2" />
</label>
<label>
Radio3:
<input type="radio" name="radio" value="radio3" />
</label>
<label for="date">This a date field:</label>
<input type="date" name="date" id="date" />
<input type="reset" value="Reset" />
<input type="submit" value="Submit" />
</form>
</div>
<div class="side">
<h1>Previous searches</h1>
<ol id="searches-list">
</ol>
</div>
body
{
max-width: 800px;
margin: 0 auto;
padding: 1em;
font-size: 20px;
}
label,
input
{
display: block;
}
input[type="checkbox"],
input[type="radio"],
input[type="reset"],
input[type="submit"]
{
display: inline;
}
input
{
font-size: inherit;
margin-bottom: 0.5em;
}
@media (min-width: 600px)
{
.side
{
display: inline-block;
width: 49%;
vertical-align: top;
}
}
dt
{
float: left;
margin-right: 0.2em;
}
#searches-list
{
cursor: pointer;
}
#searches-list > li:hover dl,
#searches-list > li:focus dl
{
display: block;
}
#searches-list dl
{
margin: 0;
display: none;
}
External resources loaded into this fiddle: