userNotFound
userNotFound

Reputation: 13

CSS dropdown button not expanding on second button

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

Answers (4)

s.kuznetsov
s.kuznetsov

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">&nbsp;</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">&nbsp;</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

userNotFound
userNotFound

Reputation: 13

Found a solution

    <div class="cal-dropdown">
    <button onclick="calDropdown(this)" class="cal-dropbtn"><i class="far fa-calendar-alt">&nbsp;</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">&nbsp;</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

vineeth pappu
vineeth pappu

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">&nbsp;</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">&nbsp;</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

cloned
cloned

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

Related Questions