Retain state of multi-level navbar/sidebar on new page

Viewed 342

I'm very new to programming & working on creating a website for a work project. In it, there will be a multi-level (w/sub-menus) vertical sidebar on each page. The problem I'm facing is that every time a user clicks on one link, the sidebar resets to its original state & will have to redo the same thing & not very UX friendly.

I took the template of the accordian sidebar from here. I've looked at various search results on both stack overflow & google, but can't seem to understand how to get it working to retain the state of the sidebar, regardless of how many levels are opened.

Can someone please help me with the JS code to get it working?

UPDATE: Nathan, thanks for writing mate! I really appreciate the help.

So based on your suggestion, I've written the following (shoddy) code that injects the 'checked' attribute to the input element.

But it isn't transferring over to the new/redirected html page when a user clicks on one of the sub-menus. What am I missing here?

var menuIndex = -1;

//extract all the input elements
var inputs = document.querySelectorAll('.parent-menu');

//Find index of the element from the array that has "checked == true"
function indexFinder() {
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].checked == true) {
            menuIndex = i;
            console.log(menuIndex);
        }
    };
}

//Function to set/inject the attribute
function attributeSetter() {
    inputs[menuIndex].setAttribute('checked', 'checked')
}

//When a user clicks literally anywhere, it'll run the indexFinder function
//to check if any of the input elements were expanded (i.e. checked == true)
window.addEventListener('click', () => {
    indexFinder();
});

//Run the attributeSetter function when a page loads
window.addEventListener('DOMContentLoaded', () => {
    attributeSetter();
});
1 Answers

Welcome to the world of programming! Hopefully I can help you out a little! So what you're asking is something that can easily get a little complicated. In order to achieve what you're trying to do you need to specify how you want your menu to look on each individual page! Allow me to present a few menu options for an imaginary site:

Home

Contact

Email

Mail

About

The Company

Our Owner

I've indented the page names based on how we want them to show up in our menu. So for example you may click on "Contact" and it drops down with the Email and Mail options.

Well, if you take your regular code from that webpage and copy and paste it everywhere. Any time you reload a page (or travel to another page with the same code) it's gonna reset the code! Thus "closing" the menu. Think of it as some sort of multi-dimentional sci-fi. When you load a webpage, you are accessing the main flow of time, any time you make an update to that page it takes you to an alternate reality with that change! but once you reload the webpage you jump back to the main timeline as if you never made that change (when you get into more advanced web dev, this analogy will break down but it should work to help your understanding for now.)

So let's say I click on the Contact > Email option and it takes me to the Email page. Well, in order to make it seem like my changes to the menu bar (clicking "Contact" to expand the dropdown) are still active. I need to hardcode the change into the Email page! Here's some sample code:

<nav class="nav">
   <a class="navOption">Home<a>
   <a class="navOption">Contact<a>
   <div class="navDropdown">
       <a class="navOption">Email<a>
       <a class="navOption">Mail<a>
   </div>
   <a class="navOption">About<a>
   <div class="navDropdown">
       <a class="navOption">The Company<a>
       <a class="navOption">Our Owner<a>
   </div>
<nav>

By default the .navDropdown will be closed. However when we add a class to them .active they will expand! If this is my base menu, then how should I make it so that the "About" dropdown is expanded when you are on one of the About pages? Simply by adding .active to that dropdown!

<nav class="nav">
   <a class="navOption">Home<a>
   <a class="navOption">Contact<a>
   <div class="navDropdown">
       <a class="navOption">Email<a>
       <a class="navOption">Mail<a>
   </div>
   <a class="navOption active">About<a>
   <div class="navDropdown">
       <a class="navOption">The Company<a>
       <a class="navOption">Our Owner<a>
   </div>
<nav>

Now, my example is different from yours because it's meant more for JavaScript. However, you can use the same concept in your code too. For you, instead of having a .active class to expand a dropdown menu. You are using a checkbox element! In your codem you have CSS which is checking to see if the checkbox is checked and then it is opening the dropdown menu if it is:

<input class="cd-accordion__input" type="checkbox" name ="group-1" id="group-1">

So, if we use this method on our example webpage. We could set it to be open by setting the checkbox to start out being checked. Like so:

<input class="cd-accordion__input" type="checkbox" name ="group-1" id="group-1" checked>

It's important to note that as you get better and better at web development (eventually learning JavaScript and a server side language such as PHP). You will be able to piece together more advanced methods to doing what we're trying to accomplish! But for now, I hope I was able to break this down for you!

Related