Skip to content
Advertisement

How to detect when a radio input is unchecked in Javascript

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>
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement