Reputation: 13
I'm unclear why but the dropdown function only seems to work on the first button and not the second. When clicking the second button it opens the drop-down for the first button. Am I selecting my elements wrong?
Example here: https://jsfiddle.net/rzLfs8um/
function calDropdown() {
document.getElementById("calDropdown").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function (event) {
if (!event.target.matches(".cal-dropbtn")) {
var dropdowns = document.getElementsByClassName("cal-dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains("show")) {
openDropdown.classList.remove("show");
}
}
}
};
Upvotes: 1
Views: 56
Reputation: 15223
Never declare js events inside html tags. Like this:
onclick="calDropdown()"
This can lead to bad consequences.
And don't use one id
for many tags. This is a unique attribute.
Here is a short js code using method forEach()
and nextElementSibling
.
let btn = document.querySelectorAll(".cal-dropbtn");
btn.forEach(function(btn_current) {
btn_current.addEventListener("click", function () {
this.nextElementSibling.classList.toggle('show');
});
});
.cal-dropbtn {
margin: 0;
font-family: "Verdana";
font-size: 14px;
text-decoration: none;
line-height: 20px;
vertical-align: middle;
box-shadow: 0 0 40px rgba(0,0,0,.13) inset;
border-radius: 4px;
zoom: 1;
background: #fbfbfb;
color: #5f6062;
padding: 7px 15px;
margin-top: 10px;
border: none;
}
.cal-dropdown {
position: relative;
display: inline-block;
}
.cal-dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.cal-dropdown-content a {
color: #5f6062;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.cal-dropdown-content a:hover {background-color: #f1f1f1}
.show {display:block;}
.far.fa-calendar-alt {
margin-right: .25em;
}
<div class="cal-dropdown">
<button class="cal-dropbtn">
<i class="far fa-calendar-alt"> </i>Add to Calendar</button>
<div class="cal-dropdown-content">
<a href="#">Google Calendar</a>
<a href="#">Outlook</a>
<a href="#">Yahoo! Calendar</a>
<a href="#">Apple iCal</a>
</div>
</div>
<div class="cal-dropdown">
<button class="cal-dropbtn">
<i class="far fa-calendar-alt"> </i>Add to Calendar</button>
<div class="cal-dropdown-content">
<a href="#">Google Calendar</a>
<a href="#">Outlook</a>
<a href="#">Yahoo! Calendar</a>
<a href="#">Apple iCal</a>
</div>
</div>
Upvotes: 1
Reputation: 13
Found a solution
<div class="cal-dropdown">
<button onclick="calDropdown(this)" class="cal-dropbtn"><i class="far fa-calendar-alt"> </i>Add to Calendar</button>
<div id="calDropdown" class="cal-dropdown-content">
<a href="#">Google Calendar</a>
<a href="#">Outlook</a>
<a href="#">Yahoo! Calendar</a>
<a href="#">Apple iCal</a>
</div>
</div>
<div class="cal-dropdown">
<button onclick="calDropdown(this)" class="cal-dropbtn"><i class="far fa-calendar-alt"> </i>Add to Calendar</button>
<div id="calDropdown" class="cal-dropdown-content">
<a href="#">Google Calendar</a>
<a href="#">Outlook</a>
<a href="#">Yahoo! Calendar</a>
<a href="#">Apple iCal</a>
</div>
</div>
.cal-dropbtn {
margin: 0;
font-family: "Verdana";
font-size: 14px;
text-decoration: none;
line-height: 20px;
vertical-align: middle;
box-shadow: 0 0 40px rgba(0,0,0,.13) inset;
border-radius: 4px;
zoom: 1;
background: #fbfbfb;
color: #5f6062;
padding: 7px 15px;
margin-top: 10px;
border: none;
}
.cal-dropdown {
position: relative;
display: inline-block;
}
.cal-dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.cal-dropdown-content a {
color: #5f6062;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.cal-dropdown-content a:hover {background-color: #f1f1f1}
.show {display:block;}
.far.fa-calendar-alt {
margin-right: .25em;
}
function calDropdown(el) {
console.log('---asdasd', el.parentNode)
el.parentNode.querySelector('.cal-dropdown-content').classList.toggle("show");
}
Upvotes: 0
Reputation: 542
This is happening because you are using same ID calDropdown
for both dropdowns.
I have updated the id for second dropdown as calDropdown2
and passed the id from the onclick function
function calDropdown(id) {
document.getElementById(id).classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function (event) {
if (!event.target.matches(".cal-dropbtn")) {
var dropdowns = document.getElementsByClassName("cal-dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains("show")) {
openDropdown.classList.remove("show");
}
}
}
};
.cal-dropbtn {
margin: 0;
font-family: "Verdana";
font-size: 14px;
text-decoration: none;
line-height: 20px;
vertical-align: middle;
box-shadow: 0 0 40px rgba(0,0,0,.13) inset;
border-radius: 4px;
zoom: 1;
background: #fbfbfb;
color: #5f6062;
padding: 7px 15px;
margin-top: 10px;
border: none;
}
.cal-dropdown {
position: relative;
display: inline-block;
}
.cal-dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.cal-dropdown-content a {
color: #5f6062;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.cal-dropdown-content a:hover {background-color: #f1f1f1}
.show {display:block;}
.far.fa-calendar-alt {
margin-right: .25em;
}
<div class="cal-dropdown">
<button onclick="calDropdown('calDropdown')" class="cal-dropbtn">
<i class="far fa-calendar-alt"> </i>Add to Calendar</button>
<div id="calDropdown" class="cal-dropdown-content">
<a href="#">Google Calendar</a>
<a href="#">Outlook</a>
<a href="#">Yahoo! Calendar</a>
<a href="#">Apple iCal</a>
</div>
</div>
<div class="cal-dropdown">
<button onclick="calDropdown('calDropdown2')" class="cal-dropbtn">
<i class="far fa-calendar-alt"> </i>Add to Calendar</button>
<div id="calDropdown2" class="cal-dropdown-content">
<a href="#">Google Calendar</a>
<a href="#">Outlook</a>
<a href="#">Yahoo! Calendar</a>
<a href="#">Apple iCal</a>
</div>
</div>
Upvotes: 1
Reputation: 6742
ID is, as the name suggest, a unique identifier. It means you can only have one element with an ID on the page. If you somehow screw up and you render two elements with the same ID on the page you can only select the first one with document.getElementById()
since the second one is invalid.
If you have multiple elements on the page you want to target then use classes.
Upvotes: 0