Smithy
Smithy

Reputation: 847

Toggle dropdown for each box with JS

I would like to toggle the dropdown for the each of these boxes, but for some reason only the first one gets visible:

const button = document.querySelector("button");
const dropdown = document.querySelector(".dropdown");

button.addEventListener("click", () => {
  dropdown.classList.toggle("dropdown-visible");
})
.box {  
  height: 100px;
  width: 300px;
  position: relative;
}

.dropdown {
  height: 100px;
  width: 100%;
  position: absolute;
  background: red;
  top: 100%;
  right: 0;
  display: none;
}

.dropdown-visible {
  display: block;
}
<div class="box">
  box 1
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 2
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 3
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>

I guess I should loop through these, but when I tried the querySelectorAll, it did not work..

Upvotes: 0

Views: 293

Answers (3)

Som Shekhar Mukherjee
Som Shekhar Mukherjee

Reputation: 8158

This should help!

const buttons = document.querySelectorAll("button");
const dropdowns = document.querySelectorAll(".dropdown");

buttons.forEach((btn, index) => {
  btn.addEventListener("click", () => {
    dropdowns[index].classList.toggle("dropdown-visible");
  })
})
.box {
  height: 100px;
  width: 300px;
  position: relative;
}

.dropdown {
  height: 100px;
  width: 100%;
  position: absolute;
  background: red;
  top: 100%;
  right: 0;
  display: none;
}

.dropdown-visible {
  display: block;
}
<div class="box">
  box 1
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 2
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 3
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>

Upvotes: 1

mplungjan
mplungjan

Reputation: 177692

Delegation

document.getElementById("container").addEventListener("click", e => {
  const tgt = e.target;
  if (tgt.tagName==="BUTTON") {
    tgt.nextElementSibling.classList.toggle("dropdown-visible");
  }
})
.box {  
  height: 100px;
  width: 300px;
  position: relative;
}

.dropdown {
  height: 100px;
  width: 100%;
  position: absolute;
  background: red;
  top: 100%;
  right: 0;
  display: none;
}

.dropdown-visible {
  display: block;
}
<div id="container">
<div class="box">
  box 1
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 2
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 3
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
</div>

One button loops

const button = document.querySelector("button");// only one button
const dropdowns = document.querySelectorAll(".dropdown");

button.addEventListener("click", () => {
  dropdowns.forEach(dropdown => dropdown.classList.toggle("dropdown-visible"));
})
.box {
  height: 100px;
  width: 300px;
  position: relative;
}

.dropdown {
  height: 100px;
  width: 100%;
  position: absolute;
  background: red;
  top: 100%;
  right: 0;
  display: none;
}

.dropdown-visible {
  display: block;
}
<button>toggle</button>
<div class="box">
  box 1
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 2

  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 3

  <div class="dropdown">dropdown content</div>
</div>

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370639

On button click, navigate to the associated dropdown by using nextElementSibling of the clicked element:

for (const button of document.querySelectorAll('button')) {
  button.addEventListener('click', (e) => {
    button.nextElementSibling.classList.toggle("dropdown-visible");
  });
}
.box {  
  height: 100px;
  width: 300px;
  position: relative;
}

.dropdown {
  height: 100px;
  width: 100%;
  position: absolute;
  background: red;
  top: 100%;
  right: 0;
  display: none;
}

.dropdown-visible {
  display: block;
}
<div class="box">
  box 1
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 2
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>
<div class="box">
  box 3
  <button>toggle</button>
  <div class="dropdown">dropdown content</div>
</div>

Upvotes: 2

Related Questions