I have 4 radio input separated by divs. I want to select the input, and make the card border change. But the event listener only works when it’s checked, no when it’s unchecked.
Codepen version https://codepen.io/nazarenoalt/pen/dyOKqYp
const radioList = document.querySelectorAll('.back-product.radio') const cardList = document.querySelectorAll('.back-product.card') for(let i = 0; i < radioList.length; i++) { radioList[i].addEventListener('change', function() { cardList[i].style.border = '2px solid lightblue'; if(!radioList[i].checked) { cardList[i].style.border = '1px solid gray'; } }) }
HTML
<div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div> <div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div> <div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div> <div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div>
Advertisement
Answer
You can maintain a reference to the last selected
const radioList = document.querySelectorAll('.back-product.radio') const cardList = document.querySelectorAll('.back-product.card') let lastSelected; for (let i = 0; i < radioList.length; i++) { radioList[i].addEventListener('change', function() { if (lastSelected) { lastSelected.style.border = '1px solid gray'; } cardList[i].style.border = '2px solid lightblue'; lastSelected = cardList[i]; }); }
<div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div> <div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div> <div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div> <div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div>
I would just add and remove a class so you do not have to maintain a reference to the last selected element.
const radioList = document.querySelectorAll('.back-product.radio') for (let i = 0; i < radioList.length; i++) { radioList[i].addEventListener('change', function(event) { const lastActive = document.querySelector(".card.active"); if (lastActive) lastActive.classList.remove("active"); event.target.closest(".card").classList.add("active"); }) }
.card { border: 1px solid gray; } .card.active { border: 2px solid lightblue; }
<div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div> <div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div> <div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div> <div class="card back-product"> <input type="radio" class="back-product radio" name="product"> </div>
If you alter the code a bit, you can just do this all in CSS
input[name] { display: none; } .card { display: block; border: 1px solid gray; cursor: pointer; } input[name]:checked+.card { border: 2px solid lightblue; }
<input type="radio" class="back-product radio" name="product" id="p1"> <label class="card back-product" for="p1"> X </label> <input type="radio" class="back-product radio" name="product" id="p2"> <label class="card back-product" for="p2"> X </label> <input type="radio" class="back-product radio" name="product" id="p3"> <label class="card back-product" for="p3"> X </label> <input type="radio" class="back-product radio" name="product" id="p4"> <label class="card back-product" for="p4"> X </label>