I have a simple form that will show hidden div when category is selected in a select tag.
What I want is when I refresh the page, the contents is still visible and also the checked items is still there.
here is the sample code
HTML
<select class="form-control" name="food_type1" id="food_type1">
<option selected="selected" disabled="disable" value="0">SELECT</option>
<option value="1">Fruits</option>
<option value="2">Meat</option>
</select>
<div id="food1" style="display: none;">
<input type="checkbox" name="food1[]" value="Mango">Mango <br>
<input type="checkbox" name="food1[]" value="strawberry">Strawberry
</div>
<div id="food2" style="display: none;">
<input type="checkbox" name="food2[]" value="Beef">Beef <br>
<input type="checkbox" name="food2[]" value="Pork">Pork <br>
<input type="checkbox" name="food2[]" value="Chicken">Chicken
</div>
SCRIPT
$(document).ready(function(){
$('#food_type1').on('change', function() {
if ( this.value == '1') {
$("#food1").show();
$("#food2").hide();
}
else if ( this.value == '2') {
$("#food2").show();
$("#food1").hide();
} else {
$("#food1").hide();
$("#food2").hide();
}
});
});
FIDDLE
https://jsfiddle.net/bk2ohogj/
The simplest way would be to use Local storage. I've updated your fiddle, however you will not be able to test the refresh while in JSFiddle, so you will have to try the code locally on your machine.
JSFiddle: https://jsfiddle.net/m0nk3y/bk2ohogj/4/
You will have to create a couple functions to implement it. I kept them as simple as possible, so they may not address all your use cases, but this should help you get closer to what you are trying to do:
JS:
$(document).ready(function(){
var storedItems = [];
//Store selected items
function storeItem(item) {
storedItems.push(item);
localStorage.setItem("storage", storedItems);
}
//Remove item
function removeItem(item) {
var index = storedItems.indexOf(item);
storedItems.splice(index, 1);
}
//Show list according to Dropdown
function showList(type) {
var $food1 = $("#food1");
var $food2 = $("#food2");
localStorage.setItem("list", type);
if ( type == '1') {
$food1.show();
$food2.hide();
} else if ( type == '2') {
$food2.show();
$food1.hide();
} else {
$food1.hide();
$food2.hide();
}
}
//Get list type
if (localStorage.getItem("list")) {
showList(localStorage.getItem("list"));
}
//Get stored items
if (localStorage.getItem("storage")) {
storedItems = localStorage.getItem("storage");
$.each(storedItems, function(i, val) {
$('input[type="checkbox"][value="'+val+'"]').prop("checked", true);
});
}
//Dropdown
$('#food_type1').on('change', function() {
showList(this.value);
});
//Checkbox
$('input[type="checkbox"]').on('change', function() {
var $this = $(this);
if ($this.is(':checked')) {
storeItem(this.val())
} else {
removeItem(this.val());
}
});
});
You'll need a mechanism to remember the states and dynamically set them on page re/load. You can use sessions (if you are using a server language to generate the pages) or cookies in your scripts. It depends on your scenario.
You can store the states on the server in the db. Whenever the state changes, send an update to the back end which will store the state and return the state. You should use this state to populate the form.
You can use HTML5 Local storage on the browser to retain the states. However, ensure you handle this carefully, per user. Whenever the page reloads, read the state from the local storage and populate the form. In case you have security concerns, be aware that users of the browser can see the content of the local storage.
Related
I am having difficulty figuring out how to keep the toggle button yes or no in localStorage even when pages refresh. I also want to keep checked or unchecked the toggle button. Note: I have also tried to use autocomplete="false" but it's not worked that way as well. Anyone can help me? Many Thanks.
HTML
<h1 id="marker" style="text-align: center; padding-bottom:50px;"></h1>
<label class="label-switch switch-primary">
<input type="checkbox" class="switch switch-bootstrap status" name="status" id="status"
onclick="yesno() ">
JS code
function yesno(){
let status = document.getElementById("status");
if(status.checked == true)
{
localStorage.setItem("isChecked", true);
status.checked = true;
location.reload();
}
if(status.checked == false)
{
localStorage.setItem("isChecked", false);
}
}
marker.innerHTML= localStorage.getItem("isChecked");
Here's a working sandbox with the solution you are looking for.
I left the markup untouched, but changed the function to this:
function yesno() {
let statusEl = document.getElementById("status");
localStorage.setItem("isChecked",JSON.stringify(statusEl.checked));
const marker = document.getElementById("marker");
marker.innerHTML = localStorage.getItem("isChecked");
}
And added the following function to mark the checkbox as checked if needed when the page loads:
function onInit() {
const isChecked = JSON.parse(localStorage.getItem("isChecked"))
document.getElementById("status").checked = isChecked
}
I'm about to code, in Javascript some code (involving looping on each <input> and adding listeners):
allowing, after keypress, to save all <input> values to localStorage
restore all <input> values from localStorage in the case the page/browser has been closed and reopened on the same page
But maybe is there an automatic way, provided by the browsers?
e.g. by adding an attribute to <input>, similar to <input autofocus> (which is not related here)
Question: is there an autosave feature of <form> <input> HTML tags?
As far as I know, there is no built-in way to do that, you should do it manually;
function persist(thisArg) {
localStorage.setItem(thisArg.id, thisArg.value);
}
<input id="test" onchange="persist(this)" />
persist and retrieve all together:
function persist(event) {
localStorage.setItem(event.target.id, event.target.value);
}
// you may use a more specific selector;
document.querySelectorAll("input").forEach((inputEl) => {
inputEl.value = localStorage.getItem(inputEl.id);
inputEl.addEventListener("change", persist);
});
<input id="test" />
there is no automatic way to do that.
you have two options :
save the data by code
example:
localStorage.setItem('testObject', JSON.stringify(yourObject)); // for storing data
JSON.parse(localStorage.getItem('yourObject')); // for retrieving data
code snippet:
// for saving data
function saveData(el) {
localStorage.setItem(el.id, JSON.stringify(el.value));
}
// for retrieving data on page load
function getData() {
var inp = document.getElementById("inp");
inp.value = JSON.parse(localStorage.getItem('inp')) || "";
}
<body onload="getData()">
<input id="inp" onchange="saveData(this)" />
</body>
try a helper library like persisto
Based on the accepted answer, here is a one-liner that can be useful:
document.querySelectorAll('input:not([type="submit"])').forEach(elt => { elt.value = localStorage.getItem(elt.name); elt.addEventListener("change", e => { localStorage.setItem(e.target.name, e.target.value); }); });
It serializes/deserializes the <input>s to localStorage, indexed by their attributes name.
I've been trying forever to keep the values the user entered into the added input fields when the web page is refreshed but with no success. I was wondering if anyone can help me with this so far I got the input fields to remain when the web page is reloaded. If it helps I'm using JQuery and PHP. My JQuery code is located below.
JQuery
$(document).ready(function(){
var max_fields = 10;
var x = 1;
if(typeof(Storage) !== 'undefined'){
$('.worker').on('click', function(e){
e.preventDefault();
e.stopPropagation();
if(x < max_fields){
x++;
$(this).closest('li').find('div:eq(3)').append('<input type="text" name="first_name[]" /><input type="text" name="last_name[]" /><select name="title[]" class="title"><option value="Select a Title" selected="selected">Select a Title</option><option value="Boss">Boss</option><option value="Worker">Worker</option><option value="Manager">Manager</option></select>');
sessionStorage.setItem('Data',$(this).closest('li').find('div:eq(3)').html());
}
});
if(sessionStorage.getItem('Data')){
$('.worker').closest('li').find('div:eq(3)').html(sessionStorage.getItem('Data'));
}
}
});
You need a mechanism to:
Devise a way to save data to session storage for all inputs
Trigger saving data to session storage (like a button or input change)
Iterate through all session storage on reload and find the ones you are interested in
Populate the fields with that data
Here's a sample for two text inputs:
$( document ).ready(function() {
if(typeof(Storage) !== 'undefined'){
populateInputs();
}
function populateInputs(){
for(var i=0; i<sessionStorage.length; i++) {
var temp = sessionStorage.key(i);
if(temp.startsWith('inputData')) {
console.log('Setting ' + temp.split('-')[1] +
' to ' + sessionStorage.getItem(temp));
$('#'+temp.split('-')[1]).val(sessionStorage.getItem(temp));
}
}
}
$('.saveInput').on('input', function(){
sessionStorage.setItem('inputData-'+this.id, this.value);
});
});
The HTML:
<label>First Name :</label><input type="text" class="saveInput" id="firstname"></input> <br>
<label>Last Name :</label><input type="text" class="saveInput" id="lastname"></input>
Running example at https://plnkr.co/edit/MrAUBAMALOmYRwxLqBs0?p=preview
You could keep every input and select (and others if needed) value in local storage, save on unload and reload on page load. See simple example:
$(document).ready(function() {
$(window).unload(saveSettings);
loadSettings();
});
function loadSettings() {
$('input, select').each(function(i,o) {
$(o).val(localStorage[$(o).attr('id')])
});
}
function saveSettings() {
$('input, select').each(function(i,o) {
localStorage[$(o).attr('id')] = $(o).val();
});
}
This example save inputs and selects as key-value pairs based on their id attribute. It is dynamic and easily expandable.
See it running
I have an div that is shown when a form is submitted, but when I refresh the page, my data disappears and I'm searching for a way to preserve my data on page refresh.
I know how to save data in a session, but not an entire form. How do I approach this issue? Is it even possible to save an entire form with Javascript?
function showHide() {
var div = document.getElementById("hidden_form");
if (div.style.display == 'none') {
div.style.display = '';
} else {
div.style.display = 'none';
}
}
<form name="product_form" id="product_form" enctype="multipart/form-data" action="admin_products.php" method="post" accept-charset="utf-8" onsubmit="showHide();
return false;">
<input type="textfield" id="title" name="title" value="" readonly>
<div id='hidden_form' style="display:none">
<input type="text" id="name" name="name" value="" placeholder="Product Name">
<label id="option_1" name="option_1">Option Name</label>
<input type="text" id="optionn" name="optionn" value="" placeholder="Product Name">
</div>
<input type="submit" id="add" name="add" value="Save" class="" <!--onclick="myFunction()-->">
When you hit submit, you'll reload the page and lose your data. By using localStorage and JSON.stringify() you are able to save the data locally in your browser and fetch it when you load your page.
Since localStoragecan only store strings, you'll have to convert your object to a string. That's where JSON.stringify() comes into play. And when you fetch it, you can use JSON.parse() to convert it back to an object.
$("#btnSubmit").click(function() {
var data = {};
data.Text = $("#myText").val();
data.isProcessed = false;
localStorage.setItem("myData", JSON.stringify(data));
});
//On load
var data = localStorage.getItem("myData");
var dataObject;
if (data != null) //There's stored data
{
dataObject = JSON.parse(data);
$("#myText").val(dataObject.Text)
localStorage.removeItem("myData"); //Remove data, otherwise it'll be there for a long time.
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<form method="post">
<input type="text" id="myText" />
<button type="submit" id="btnSubmit">Submit</button>
</form>
</div>
More information on localStorage: W3Schools
More information on JSON.stringify and JSON.parse: MDN
I don't know if the snippet will work, since it'll submit a post. Copy this snippet and try it on your local system.
EDIT
As I made a tiny mistake myself, I updated my snippet. But as I suspected, SO doesn't allow access to localStorage.
And ofcourse, you'll have to put this code in your $(document.ready(function() { ... }); for it to work. I did forget to add a <form></form> to my HTML snippet. And I just tested it on my local system and it's working fine.
You can try with localStorage. It's key-value storage that all modern browsers have. There're simple libraries to write to localStorage with fallback to cookies if you need old browser support (written by javascript instead of server side scripts).
I'll give you an example with localStorage:
//emulating that the form was showed (save clicked) and the value true stored on the localStorage
localStorage.setItem('displayedForm', true);
//initializing the state of the page
initialize();
function showHide() {
var div = document.getElementById("hidden_form");
if (div.style.display == 'none') {
div.style.display = '';
localStorage.setItem('displayedForm', true);//if the conditions are meet to display the form, store it on the localStorage
} else {
div.style.display = 'none';
localStorage.setItem('displayedForm', false);//if the conditions are **NOT** meet to display the form, store it on the localStorage as well
}
}
function initialize() {
if (localStorage.getItem('displayedForm') === true || localStorage.getItem('displayedForm') === 'true') {
var div = document.getElementById("hidden_form");
div.style.display = '';
}
}
Working Fiddle: https://jsfiddle.net/y0uep73e/
Facing this problem myself, I wrote a simple library to automatically handle saving and loading form data via local storage: https://github.com/FThompson/FormPersistence.js
Example which saves data upon unload and loads data upon load:
<script src='https://cdn.jsdelivr.net/gh/FThompson/FormPersistence.js#1.0.1/form-persistence.min.js' type='text/javascript'></script>
<script type='text/javascript'>
window.addEventListener('load', () => {
let myForm = document.getElementById('my-form')
FormPersistence.persist(myForm)
})
</script>
I have an odd issue using JavaScript to find an element by ID. No function will run against it because the selection is undefined. It has the same kind of definition as many on the same page. There is only one element by this ID. And, when I assign an ID to the surrounding paragraph, it works just fine. So, the problem is bypassed. But, I am very curious as to the problem. I am showing the pertinent items.
This JavaScript is part and parcel of a Rails application, so it is included as an external file using application.js. It's a large file with many functions and they all work except when referencing this one ID. And, as I stated, I select many other ID's on this page in the same fashion with no issue.
I use RubyMine and have searched the entire application for conflicts and typos related to the issue. There are no conflicts and every expected reference to item_message is found. item_message is included in a partial along with other references that JavaScript locates easily. I searched for syntax errors before it was included and none are found. I reordered the items on the page and in JavaScript to no avail. I simply don't know why this doesn't work.
When I tried to hide the element using class optional, that worked. However, it also hid other items that should not have been hidden.
It's working like this:
HTML:
<p id="item_message_p">
<input class="string optional form-control" placeholder="Message? (optional)" type="text" name="item[message]" id="item_message"></p>
JavaScript:
var item_message_p = $('#item_message_p');
select_item_spot_id.change(function () {
var spot = $(this).val();
if (spot != "") {
$.getJSON('/spots', {spot: $(this).val()}, function (data) {
if (data.name.toLowerCase() === 'sold') {
item_message_p.hide();
} else {
item_message_p.show();
}
})
}
});
It wouldn't work like this, as var item_message is undefined:
HTML:
<p>
<input class="string optional form-control" placeholder="Message? (optional)" type="text" name="item[message]" id="item_message"></p>
JavaScript:
var item_message = $('#item_message');
select_item_spot_id.change(function () {
var spot = $(this).val();
if (spot != "") {
$.getJSON('/spots', {spot: $(this).val()}, function (data) {
if (data.name.toLowerCase() === 'sold') {
item_message.hide();
} else {
item_message.show();
}
})
}
});
As per Andy's suggestion, I ended up checking the generated page to find that another element had generated the same ID. That explains the issue. Thanks to all who helped.
Make sure your page is loaded before looking up elements. So wrap your code in $(function () {...});, like this:
$(function () {
var item_message = $('#item_message');
select_item_spot_id.change(function () {
var spot = $(this).val();
if (spot != "") {
$.getJSON('/spots', {spot: $(this).val()}, function (data) {
if (data.name.toLowerCase() === 'sold') {
item_message.hide();
} else {
item_message.show();
}
})
}
});
});
This will make your code execute when the dom is ready.
Also, it is best to close your input tag explicitly:
<input ..... />
Notice the slash. This absence might also explain the issue, including the spoil-over effect you noticed when hiding the element.
You are trying to access select_item_spot_id.change(), but select_item_spot_id is not defined. You defined item_message or item_message_p. You might like to do it inside a onDOMReady event listener, as spotted by #trincot . This example code works for me:
$(function () {
var item_message = $('#item_message');
var select_item_spot_id = $('#select_item_spot_id');
select_item_spot_id.change(function () {
var spot = $(this).val();
// DEBUG
if(item_message.length > 0)
alert('works!');
// END DEBUG
if (spot != "") {
$.getJSON('/spots', {spot: $(this).val()}, function (data) {
if (data.name.toLowerCase() === 'sold') {
item_message.hide();
} else {
item_message.show();
}
});
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<select id="select_item_spot_id" name="select_item_spot_id">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<input class="string optional form-control" placeholder="Message? (optional)" type="text" name="item[message]" id="item_message">
</p>