Reputation: 13
I have created a toggle input, where staff can set whether they are in or out of the office. I am using local storage to save the state of the input. When I add more than one toggle input onto the page, each input's state can be changed but when I reload the page all inputs are the same due to the local storage set on the last input ( i.e all to out ).
How do I save each toggles state and use local storage to remember this?
CSS CODE
<style type="text/css">
.toggle {
-webkit-appearance: none;
appearance: none;
width: 150px;
height: 60px;
display: inline-block;
position: relative;
border-radius: 50px;
overflow: hidden;
outline: none;
border: none;
cursor: pointer;
background-color: red;
transition: background-color ease 0.3s;
}
.toggle:before {
content: "in out";
display: block;
position: absolute;
z-index: 2;
width: 80px;
height: 70px;
top: -5px;
left: -10px;
background: #fff;
border-radius: 50%;
font: 30px/70px Helvetica;
text-transform: uppercase;
font-weight: bold;
text-indent: -40px;
word-spacing: 85px;
color: #fff;
text-shadow: -1px -1px rgba(0,0,0,0.15);
white-space: nowrap;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
transition: all cubic-bezier(0.3, 1.5, 0.7, 1) 0.3s;
}
.toggle:checked {
background-color: #4CD964;
}
.toggle:checked:before {
left: 75px;
}
.toggle.in {
background-color: #4CD964;
}
.toggle.in:before {
left: 75px;
}
</style>
HTML CODE
<input class="toggle" type="checkbox" />
<input class="toggle" type="checkbox" />
JQUERY CODE
var toggle = $('.toggle');
toggle.on('click', function(){
if ( $('input[type=checkbox]:checked').length === 0 ) {
localStorage.setItem('result', 'out');
$(this).removeClass('in');
} else {
localStorage.setItem('result', 'in');
$(this).addClass('in');
}
})
if ( localStorage.result === 'in' ) {
toggle.addClass('in');
} else {
toggle.removeClass('in');
}
Upvotes: 1
Views: 901
Reputation: 337560
Your issue is because you're only saving a single state and applying it to all checkboxes. Therefore the state applied last will be given to all on the next load of the page.
To fix this it would make far more sense to use an array. You can then store the state of every checkbox and re-apply when the page next loads, something like this:
var $toggles = $('.toggle').on('click', function() {
var checkedStates = $toggles.map(function() {
return this.checked;
}).get();
localStorage.setItem('checkedStates', JSON.stringify(checkedStates));
$(this).toggleClass('in');
})
if (localStorage.getItem('checkedStates')) {
JSON.parse(localStorage.getItem('checkedStates')).forEach(function(checked, i) {
$('.toggle').eq(i).prop('checked', checked).toggleClass('in', checked)
});
}
.toggle {
-webkit-appearance: none;
appearance: none;
width: 150px;
height: 60px;
display: inline-block;
position: relative;
border-radius: 50px;
overflow: hidden;
outline: none;
border: none;
cursor: pointer;
background-color: red;
transition: background-color ease 0.3s;
}
.toggle:before {
content: "in out";
display: block;
position: absolute;
z-index: 2;
width: 80px;
height: 70px;
top: -5px;
left: -10px;
background: #fff;
border-radius: 50%;
font: 30px/70px Helvetica;
text-transform: uppercase;
font-weight: bold;
text-indent: -40px;
word-spacing: 85px;
color: #fff;
text-shadow: -1px -1px rgba(0, 0, 0, 0.15);
white-space: nowrap;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
transition: all cubic-bezier(0.3, 1.5, 0.7, 1) 0.3s;
}
.toggle:checked {
background-color: #4CD964;
}
.toggle:checked:before {
left: 75px;
}
.toggle.in {
background-color: #4CD964;
}
.toggle.in:before {
left: 75px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input class="toggle" type="checkbox" />
<input class="toggle" type="checkbox" />
As SO places limits on the access to localStorage in a snippet, please see this fiddle for a working example:
Upvotes: 1
Reputation: 6546
Yo need to add an identifier to your checkboxes
. Each time a checkbox is changed
overwrite the value in localStorage
and retrieve on page load. Also, use an array
to save it in localStorage
, becasue it will be easier to work with native JS objects rather than comma separated string.
See below
HTML
<input name="chk1" class="toggle" type="checkbox" />
<input name="chk2" class="toggle" type="checkbox" />
JavaScript
var toggle = $('.toggle');
function updateStorage() {
var storage = [];
toggle.each(function() {
storage.push({
name: $(this).attr('name'),
checked: $(this).prop('checked'),
})
});
localStorage.setItem('prefix-result', JSON.stringify(storage));
}
function loadStorage() {
var storage = localStorage.getItem('prefix-result');
storage = storage ? JSON.parse(storage) : [];
storage.forEach(function (item) {
$('input[name=' + item.name + ']').prop('checked', item.checked)
})
}
loadStorage();
toggle.on('change', updateStorage);
In your current code, you are using single key
to save both values
. That may work if you add both values
but won't work if you overwrite previous one.
Upvotes: 0