I have a list of buttons in a menu that all have a unique ID and a collapse-able menu underneath it. When I click one of these buttons I want to use the ID of the clicked button to check if there is a key with the same ID already stored in the local storage.
If there IS already a key in local storage with the same clicked button ID, then I want to update the value of the key to true/false (depending on the collapse-able menu).
If there IS NOT already a key in local storage with the same clicked button ID, then I want to add a new key and value to the local storage using the ID of the clicked button.
I haven’t been able to figure out how to use the ID of the clicked button to check if it exists in local storage. I have been able to write a single new key, but it just replaces the existing key/value, so it’s only replacing a single pair instead of adding new pairs to the object/array.
I have searched for several hours already today and I just haven’t been able to figure out why this won’t work.
MORE INFO:
I wanted to add a little reasoning to why I am doing this. I have over 30 different collapse-able panels in a side navigation menu. I want the browser to remember which panels the user has open/closed, but I didn’t want to write and if/else statement for every single one. And there will be panels that are added or removed in the future, so I didn’t want to have to update this local storage code in the future. I just want everything to happen automatically in the local storage. So, I am just looking for a way to dynamically write these panel IDs and states to the local storage, and then loop through all of them in a mutation observer on page load to open/close them automatically.
Here is my HTML code that has specific classes and IDs:
<a href="#" class="rpLink rpExpandable rpExpanded" id="button-id-one">Menu Button One</a>
<a href="#" class="rpLink rpExpandable" id="button-id-two">Menu Button Two</a>
<a href="#" class="rpLink rpExpandable" id="button-id-three">Menu Button Three</a>
Here is my JS code that listens for when the menu buttons are clicked:
$(document).on("click",".rpExpandable",function()
{
var panelId = $(this).attr("id");
var panelState = false;
if($(this).hasClass("rpExpanded")){panelState = true;}
//update left menu panel settings in local storage
persistLeftMenuPreferences(panelId,panelState);
});
Here is my JS code that tries to check the local storage and add to it or update it:
function persistLeftMenuPreferences(panelId,panelState)
{
setTimeout(function()
{
var panelKey = "panel-preferences";
var panelPreferences = {};
if(localStorage.getItem(panelId) !== null)
{
console.log("not null");
panelPreferences.panels[panelId] = panelState;
}
else
{
console.log("null");
panelPreferences.panels = [panelId,panelState];
}
//set item values in local storage
localStorage.setItem(panelKey, JSON.stringify(panelPreferences));
Cookies.set(panelKey, JSON.stringify(panelPreferences), {expires: 360});
}, 200);
}
EDIT/UPDATE:
So, I have found that the code below is actually doing what I want for the most part. The only down-side is that it’s adding individual key/value pairs instead of putting them all in to one object that contains all of the key/value pairs inside of it. If you can show me how to put them all inside of a single object, that would be ideal.
function persistLeftMenuPreferences(panelId,panelState)
{
setTimeout(function()
{
var panelPreferences = {};
panelPreferences = [panelId,panelState];
//set item values in local storage
localStorage.setItem(panelId, JSON.stringify(panelPreferences));
Cookies.set(panelId, JSON.stringify(panelPreferences), {expires: 360});
}, 200);
}
LATEST EDIT/UPDATE:
I’ve simplified my code even more. I am just writing the panelId and panelState directly to the local storage instead of trying to put it in an object. Ultimately I’d like each key/value pair to be inserted in to a single object, but I will save it for a later day.
function persistLeftMenuPreferences(panelId,panelState)
{
setTimeout(function()
{
//set item values in local storage
localStorage.setItem(panelId, panelState);
Cookies.set(panelId, panelState, {expires: 360});
}, 200);
}
Here is a screenshot of how this looks when adding them to the local storage:
screenshot of local storage key/value paris
2
Answers
You need to get the old value of
panelPreferences
from local storage and update that, not start with an empty object.You shouldn’t be using
panelId
as the local storage key. It’s the key in the JSON object that’s saved in local storage, with the keypanel-preferences
.Following on from the comment of yesterday regarding JSON vs multiple name/value pairs perhaps this might be of interest. I wrote a simple class a while back for working with storage objects which makes the setting and toggling (true/false) of a key/value pair remarkably simple in this instance. By default it will be creating and working with JSON which is ideal for your use case. I can’t see why the need to use both
localStorage
and acookie
– no jQuery code as I never use it but sure it’ll be an easy transposition…