Reputation: 155
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
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 thetesting()
function. Since the code starting at line 42 binds the click event to all buttons with the css-classdropdown-btn
, which includes the new Buttons also.
Upvotes: 1