Reputation: 1036
I'm trying to enable and disable a checkbox on a keypress on my webpage. I'm trying to use sessionStorage to make it last between page refreshes but not between browser sessions.
$(document).ready(function(){
var set = sessionStorage.getItem('disable');
if (sessionStorage.getItem('disable') === null){
$("#cblDoctors_3").prop('disabled', false);
} else{
$("#cblDoctors_3").prop('disabled', set);
}
console.log(set);
});
$("html").keypress(function( event ){
if(event.which == 119){ //this is the 'w' key
var box = $("#cblDoctors_3").prop('disabled');
$("#cblDoctors_3").prop('disabled', !box);
sessionStorage.removeItem('disable');
sessionStorage.setItem('disable', !box);
console.log(sessionStorage.getItem('disable'));
}
});
So everything works fine, the console logs the correct status of the storage item, but when the page reloads, once the session item is stored, the box never reactivates on page refresh even if it's supposed to. So let's say that the user 'enabled' the box after it was disabled, the console will log false, meaning: prop('disabled', false). This is the expected result. But when the page refreshes, despite the session item being false, the box will still be disabled, meaning that the page is interpreting prop('disabled', true) despite the session variable console logging 'false'. What am I missing?
Upvotes: 0
Views: 1519
Reputation: 106385
The caveat here is that Storage
(interface behind both LocalStorage and SessionStorage) only allows DOMString
as values to be stored (when using setItem()
). Quoting the doc:
storage.setItem(keyName, keyValue);
keyName
A DOMString containing the name of the key you want to create/update.keyValue
A DOMString containing the value you want to give the key you are creating/updating.
The same is with getItem()
- it either returns null
, if there's no item stored under the given key, or a DOMString
.
So if you run it like this:
sessionStorage.setItem('disabled', false);
... it actually casts the boolean into DOMString. That's easy to check: just run...
console.log( typeof sessionStorage.getItem('disabled') );
... and lo and behold, here's 'string'
instead of expected 'boolean'
.
Now, jQuery.prop
actually doesn't check the type of its argument when working with disabled
property. And when it's a string 'false'
, it just casts it to Boolean to decide whether or not it needs to drop attribute or not. And, as you surely know, Boolean('false') === true
.
What to do then? One possible approach is not storing the value at all - just clear the item when it's not needed. Another is storing an empty string (as it's the only string that casts to false). In this case, decision part is trivial:
if (event.which == 119) { //this is the 'w' key
var isDisabled = $("#cblDoctors_3").prop('disabled');
sessionStorage.setItem('disabled', isDisabled || '');
}
// ...
const isDisabled = Boolean( sessionStorage.getItem('disable') );
// it'll be false for both null and ''
$('#cblDoctors_3').prop('disabled', isDisabled);
Upvotes: 2