Muhammad Umar Khan
Muhammad Umar Khan

Reputation: 155

Multilevel Dropdown in sidebar using HTML,CSS & JS

I am using JS for looping the relative array over a sub-drop-down; let's say the list is a loop element i. I want to auto-generate a multilevel dropdown according to the number of time loop runs. When I try it without a loop, it works fine, but when i try it with a loop, it shows only 2nd level drop down but not responsive when click them to further 3rd level dropdown.

HTML below

<div class="sidenav">
                    <button class="dropdown-btn"><i class="fa fa-sticky-note left-icon"></i> Courses
                        <i class="fa fa-caret-down"></i>
                    </button>
                    <div class="dropdown-container" id="testd">
                           <!-- this part is where the subjects would generate -->

                    </div>
                </div>


                <script type="text/javascript">
                    var dropdown = document.getElementsByClassName("dropdown-btn");
                    var i;

                    for (i = 0; i < dropdown.length; i++) {
                        dropdown[i].addEventListener("click", function () {
                            this.classList.toggle("active");
                            var dropdownContent = this.nextElementSibling;
                            if (dropdownContent.style.display === "block") {
                                dropdownContent.style.display = "none";
                            } else {
                                dropdownContent.style.display = "block";
                            }
                        });
                    }
                </script>

JS below

function testing(){

    for(i=0;i<5;i++){
        document.getElementById('testd').innerHTML+=`<button class="dropdown-btn"  ><i class="fa fa-sticky-note left-icon"></i>P${i}
        <i class="fa fa-caret-down"></i>
      </button> <div class="dropdown-container" id="testdd" >
      <a onclick="generateqrrr();" style="color:white;">Generate QRcode</a>
       <a onclick="studentlistrr();" style="color:white;">Student list</a>
       <a onclick="manualattendancerr();" style="color:white;">Manual Attendance</a>
     </div> 
       `
      console.log(i +'<br>')

    }       
}

testing() 

Browser code outerHTML on inspect below

<button class="dropdown-btn active"><i class="fa fa-sticky-note left-icon"></i> Courses
    <i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-container" id="testd" style="display: block;">

    <button class="dropdown-btn"><i class="fa fa-sticky-note left-icon"></i>P0
        <i class="fa fa-caret-down"></i>
    </button>
    <div class="dropdown-container" id="testdd">
        <a onclick="generateqrrr();" style="color:white;">Generate QRcode</a>
        <a onclick="studentlistrr();" style="color:white;">Student list</a>
        <a onclick="manualattendancerr();" style="color:white;">Manual Attendance</a>
    </div>
    <button class="dropdown-btn"><i class="fa fa-sticky-note left-icon"></i>P1
        <i class="fa fa-caret-down"></i>
    </button>
    <div class="dropdown-container" id="testdd">
        <a onclick="generateqrrr();" style="color:white;">Generate QRcode</a>
        <a onclick="studentlistrr();" style="color:white;">Student list</a>
        <a onclick="manualattendancerr();" style="color:white;">Manual Attendance</a>
    </div>
</div> 

I just want to know what mistake I am doing for the outerHTML part such as below is not visible on sidebar.

<a onclick="generateqrrr();" style="color:white;">Generate QRcode</a>
<a onclick="studentlistrr();" style="color:white;">Student list</a>
<a onclick="manualattendancerr();" style="color:white;">Manual Attendance</a> 

Thanks for help in advance.

Upvotes: 1

Views: 525

Answers (1)

winner_joiner
winner_joiner

Reputation: 14695

Update(after Chat):

The Problem is that the Click Event for the new Buttons, are not set.

function testing(){
    // using here a variable, since it fast writing only once to the HTML-DOM
    var newHTML = "";
    for(i=0;i<5;i++){
        // I added a new css-class 'new-buttons' to better select the buttons
        newHTML +=`<button class="dropdown-btn new-buttons">
            <i class="fa fa-sticky-note left-icon"></i>P${i}<i class="fa fa-caret-down"></i>
        </button>
        <div class="dropdown-container" >
            <a onclick="generateqrrr();" style="color:white;">Generate QRcode</a>
            <a onclick="studentlistrr();" style="color:white;">Student list</a>
            <a onclick="manualattendancerr();" style="color:white;">Manual Attendance</a>
        </div> 
       `
    }
    // here the buttons are added to the DOM
    document.getElementById('testd').innerHTML  += newHTML;
    // Call function that binds DropDown CLick Events
    bindNewButtonsAction();
}

// Function that bind the Events, to the new buttons
function bindNewButtonsAction(){
    // here we retrieve all new-buttons
    var newButtons = document.querySelectorAll(".dropdown-btn.new-buttons");

    // loop through all buttons and add the Click Event.
    for (var i = 0; i < newButtons.length; i++) {
        newButtons[i].addEventListener("click", function () {
            // this code is from original HTML, that is used for the first dropdown button
            this.classList.toggle("active");
            var dropdownContent = this.nextElementSibling;
            if (dropdownContent.style.display === "block") {
                dropdownContent.style.display = "none";
            } else {
                dropdownContent.style.display = "block";
            }
        });
    }    
}

This code works and should do the trick. It could be improved abit, if it is used in production.

Important: If the loop for creating the New Buttons run before binding the Button Click Event in your orignial code (line 42), the function call bindNewButtonsAction() can be removed, from the testing() function. Since the code starting at line 42 binds the click event to all buttons with the css-class dropdown-btn, which includes the new Buttons also.

Upvotes: 1

Related Questions