Clicking on one element sets it a class, while removing classes from other elements, dynamically.

This, I'm guessing, simple problem is giving me a headache for 3rd straight project in a row. If I for example have 6 buttons of the same class, and I click on any of them, that one gets class of "active". However, if I click on different button, any other button that has that "active" class should lose it. Or simplified, one 1 button can be "active" at the time. How do I achieve this dynamically, through loop, without having to add every button separately, and adding the same exact code to each with .add/.remove class that I have been doing until now?
21 Replies
13eck
13eckā€¢2y ago
#How To Ask Good Questions . What have you tried? What code do you have?
Dovah
DovahOPā€¢2y ago
Ohhhhhh you are here. Was looking for you few days ago. xD I have no code. xD Just add 6 buttons in HTML. That is it. šŸ˜„ And what I'm trying to do is when you click one of them for it to get its style changed so it looks active. But If I click any other, that one loses that style. We already had similar problem in the past with radio buttons. xD That you were helping me. Let me try and get code
for(let i=0;i<tipButton.length;i++) {
tipButton[i].addEventListener('click', function(){
tipButton[i].classList.toggle('active-button');
})
}
for(let i=0;i<tipButton.length;i++) {
tipButton[i].addEventListener('click', function(){
tipButton[i].classList.toggle('active-button');
})
}
This is the loop I would use
13eck
13eckā€¢2y ago
Well, we won't spoon feed you the answer, but I can give you some tips: 1) On click, loop through all button elements you want and 1.1) Remove the active class on all of them 1.2) Add the active class to the clicked button You'll want to look into: ā€¢ document.querySelectorAll() to get all the appropriate elements ā€¢ for...of or forEach() loops to loop through the elements ā€¢ classList.add() and classList.remove
Dovah
DovahOPā€¢2y ago
tip button is just a class for all 6 buttons
13eck
13eckā€¢2y ago
Oh, also, event delegation. Which is when you add an event listener on the parent element and do things to the children elements. This way you're only adding one event listener and if you add more elements later all will still be event-able
Dovah
DovahOPā€¢2y ago
Yeah you were mentioning that last time. But the chat was not saved šŸ˜¦ actually it was video call
Dovah
DovahOPā€¢2y ago
Will you be able to do a video call any time in future? Or now if you are able?
13eck
13eckā€¢2y ago
Basically:
<div class="tipJar">
<button class="tip" data-tip="5">Tip 5%</button>
<button class="tip" data-tip="10">Tip 10%</button>
<button class="tip" data-tip="15">Tip 15%</button>
<button class="tip" data-tip="25">Tip 25%</button>
</div>
<div class="tipJar">
<button class="tip" data-tip="5">Tip 5%</button>
<button class="tip" data-tip="10">Tip 10%</button>
<button class="tip" data-tip="15">Tip 15%</button>
<button class="tip" data-tip="25">Tip 25%</button>
</div>
document.querySelector(".tipJar").addEventListener("click", (ev) => {
// ev.target is the element that was clicked on
console.log(ev.target);
});
document.querySelector(".tipJar").addEventListener("click", (ev) => {
// ev.target is the element that was clicked on
console.log(ev.target);
});
Not for a while, no. Gonna be sitting down to lunch soon and then going to a movie with the wife
Dovah
DovahOPā€¢2y ago
Roger. Let me see those pictures. šŸ˜„
13eck
13eckā€¢2y ago
All that being said, why are you using buttons and no a radio input? Sounds like a perfect use case for it
Dovah
DovahOPā€¢2y ago
Well I had the same problem with radio buttons And I'm just curious at this point. Let me try out this thingie you gave me. šŸ˜„ Can you say if not target somehow? wait
13eck
13eckā€¢2y ago
You'll want to for...of loop through the tip buttons (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of). It's better than the for loop you have above since it does the auto incrementing for you.
const tipJarBtns = document.querySelectorAll(".tipJar > button");
for (const btn of tipJarBtns) {
//do stuff
}
const tipJarBtns = document.querySelectorAll(".tipJar > button");
for (const btn of tipJarBtns) {
//do stuff
}
using my above for...of loop, you'd do something like:
if (btn !== ev.target) {
// do something to the not-target of the click
}
if (btn !== ev.target) {
// do something to the not-target of the click
}
Dovah
DovahOPā€¢2y ago
Hmmmmmmmmm we are getting closer I think xD lemmie type it out How do you add ev.target into that
13eck
13eckā€¢2y ago
You add that into the click handler, so the event is passed in
Dovah
DovahOPā€¢2y ago
const tipJarBtns = document.querySelectorAll(".tipJar > button"); for (const btn of tipJarBtns) { //do stuff }
```js
const tipJarBtns = document.querySelectorAll(".tipJar > button");
for (const btn of tipJarBtns) {
//do stuff
}
```js
const tipJarBtns = document.querySelectorAll(".tipJar > button");
for (const btn of tipJarBtns) {
//do stuff
}
13eck
13eckā€¢2y ago
Wife's home, lunch time. x13ladWave
Dovah
DovahOPā€¢2y ago
Hmm I'm doing something wrong Have a nice meal! šŸ˜„ That is it! Finally Still need to learn that syntax ev => and so on target and so on Either way thanks a lot! LD šŸ˜„ But how do you remove class from the same button now? xD Buttons are perma active now, you can't turn them off.
13eck
13eckā€¢2y ago
Just a small update to the codepen AND BOOM! Toggles the button if it's on to off
Dovah
DovahOPā€¢2y ago
Niceeeeeeee! It works now! Thanks a lot! šŸ˜„
Want results from more Discord servers?
Add your server