How to remove class from other elements by clicking the button?

Asked

Viewed 195 times

0

There are several buttons, which when clicking, opens a box with options. How do I so that when I open a box, the others close?

var button = document.querySelectorAll(".popup-btn")
var pop = document.querySelectorAll(".popup")
var li = document.querySelectorAll("li")



button.forEach(item => {
  item.addEventListener('click', () => {

    let popup = document.getElementById("popup-" + event.target.dataset.itemid);
    popup.classList.toggle("visible");

  })
})


li.forEach(item => {
  item.addEventListener('click', () => {

    let alvo = document.getElementById("alvo-" + event.target.dataset.alvo);
    alvo.value = event.target.innerHTML

    let popup = item.parentNode;
    popup.classList.toggle("visible");

  })
})
.container {
  position: relative;
}

.popup {
  position: absolute;
  display: none;
}

.popup.visible {
  display: block;
}
<div class="container">
  <button class="popup-btn" data-itemid="1"> Button 1</button>
  <input type="text" id="alvo-1">
  <div id="popup-1" class="popup">
    <li data-alvo="1">item 1</li>
    <li data-alvo="1">item 2</li>
    <li data-alvo="1">item 3</li>
  </div>
</div>



<div class="container">
  <button class="popup-btn" data-itemid="2"> Button 2</button>
  <input type="text" id="alvo-2">
  <div id="popup-2" class="popup">
    <li data-alvo="2">item 1</li>
    <li data-alvo="2">item 2</li>
    <li data-alvo="2">item 3</li>
  </div>
</div>

I tried to use the forEach within the button, but it didn’t work

jsfiddle

2 answers

1


As you already have the popups curled in var pop... just go through this list and remove the class visible before displaying the target popup.

var button = document.querySelectorAll(".popup-btn")
var pop = document.querySelectorAll(".popup")
var li = document.querySelectorAll("li")

button.forEach(item => {
  item.addEventListener('click', () => {

    pop.forEach(popup => {
      popup.classList.remove("visible");
    });
    
    let popup = document.getElementById("popup-" + event.target.dataset.itemid);
    popup.classList.toggle("visible");
  })
})


li.forEach(item => {
  item.addEventListener('click', () => {

    let alvo = document.getElementById("alvo-" + event.target.dataset.alvo);
    alvo.value = event.target.innerHTML

    let popup = item.parentNode;
    popup.classList.toggle("visible");

  })
})
.container {
  position: relative;
}

.popup {
  position: absolute;
  display: none;
}

.popup.visible {
  display: block;
}
<div class="container">
  <button class="popup-btn" data-itemid="1"> Button 1</button>
  <input type="text" id="alvo-1">
  <div id="popup-1" class="popup">
    <li data-alvo="1">item 1</li>
    <li data-alvo="1">item 2</li>
    <li data-alvo="1">item 3</li>
  </div>
</div>



<div class="container">
  <button class="popup-btn" data-itemid="2"> Button 2</button>
  <input type="text" id="alvo-2">
  <div id="popup-2" class="popup">
    <li data-alvo="2">item 1</li>
    <li data-alvo="2">item 2</li>
    <li data-alvo="2">item 3</li>
  </div>
</div>

The problem of this method is that if you add new popups and buttons dynamically, these will not work, in this case I suggest creating a new function to hide the popups and within this function get the list of popups with document.querySelectorAll(".popup")

var button = document.querySelectorAll(".popup-btn")
var li = document.querySelectorAll("li")

function hidePopus() {
  document.querySelectorAll(".popup").forEach(popup => {
     popup.classList.remove("visible");
  });
}


button.forEach(item => {
  item.addEventListener('click', () => {

    hidePopus();
    
    let popup = document.getElementById("popup-" + event.target.dataset.itemid);
    popup.classList.toggle("visible");
  })
})


li.forEach(item => {
  item.addEventListener('click', () => {

    let alvo = document.getElementById("alvo-" + event.target.dataset.alvo);
    alvo.value = event.target.innerHTML

    hidePopus();

  })
})
.container {
  position: relative;
}

.popup {
  position: absolute;
  display: none;
}

.popup.visible {
  display: block;
}
<div class="container">
  <button class="popup-btn" data-itemid="1"> Button 1</button>
  <input type="text" id="alvo-1">
  <div id="popup-1" class="popup">
    <li data-alvo="1">item 1</li>
    <li data-alvo="1">item 2</li>
    <li data-alvo="1">item 3</li>
  </div>
</div>



<div class="container">
  <button class="popup-btn" data-itemid="2"> Button 2</button>
  <input type="text" id="alvo-2">
  <div id="popup-2" class="popup">
    <li data-alvo="2">item 1</li>
    <li data-alvo="2">item 2</li>
    <li data-alvo="2">item 3</li>
  </div>
</div>

  • Oops, thank you very much! but in this case, if I click the button again and the popup is open, it does not close, there is a way around it?

  • Just check on the button click if the corresponding popup has the Visible class and if you have to remove it and give a Return to end the execution.

0

You can simplify and listen to events directly in the container:

containers.forEach(item => {
  item.addEventListener('click', (e) => {
    item.querySelector('.popup').classList.toggle("visible");
  })
})

In that case he does .toggle no matter where you click...

const containers = document.querySelectorAll(".container")
var pop = document.querySelectorAll(".popup")
var li = document.querySelectorAll("li")

containers.forEach(item => {
  item.addEventListener('click', (e) => {
    item.querySelector('.popup').classList.toggle("visible");
  })
})


li.forEach(item => {
  item.addEventListener('click', (event) => {
    let alvo = document.getElementById("alvo-" + event.target.dataset.alvo);
    alvo.value = event.target.innerHTML;
  })
})
.container {
  position: relative;
}

.popup {
  position: absolute;
  display: none;
}

.popup.visible {
  display: block;
}
<div class="container">
  <button class="popup-btn" data-itemid="1"> Button 1</button>
  <input type="text" id="alvo-1">
  <div id="popup-1" class="popup">
    <li data-alvo="1">item 1</li>
    <li data-alvo="1">item 2</li>
    <li data-alvo="1">item 3</li>
  </div>
</div>



<div class="container">
  <button class="popup-btn" data-itemid="2"> Button 2</button>
  <input type="text" id="alvo-2">
  <div id="popup-2" class="popup">
    <li data-alvo="2">item 1</li>
    <li data-alvo="2">item 2</li>
    <li data-alvo="2">item 3</li>
  </div>
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.