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
JavaScript
x
13
13
1
const radioList = document.querySelectorAll('.back-product.radio')
2
const cardList = document.querySelectorAll('.back-product.card')
3
4
for(let i = 0; i < radioList.length; i++) {
5
radioList[i].addEventListener('change', function() {
6
cardList[i].style.border = '2px solid lightblue';
7
8
if(!radioList[i].checked) {
9
cardList[i].style.border = '1px solid gray';
10
}
11
})
12
}
13
HTML
JavaScript
1
16
16
1
<div class="card back-product">
2
<input type="radio" class="back-product radio" name="product">
3
</div>
4
5
<div class="card back-product">
6
<input type="radio" class="back-product radio" name="product">
7
</div>
8
9
<div class="card back-product">
10
<input type="radio" class="back-product radio" name="product">
11
</div>
12
13
<div class="card back-product">
14
<input type="radio" class="back-product radio" name="product">
15
</div>
16
Advertisement
Answer
You can maintain a reference to the last selected
JavaScript
1
13
13
1
const radioList = document.querySelectorAll('.back-product.radio')
2
const cardList = document.querySelectorAll('.back-product.card')
3
let lastSelected;
4
5
for (let i = 0; i < radioList.length; i++) {
6
radioList[i].addEventListener('change', function() {
7
if (lastSelected) {
8
lastSelected.style.border = '1px solid gray';
9
}
10
cardList[i].style.border = '2px solid lightblue';
11
lastSelected = cardList[i];
12
});
13
}
JavaScript
1
15
15
1
<div class="card back-product">
2
<input type="radio" class="back-product radio" name="product">
3
</div>
4
5
<div class="card back-product">
6
<input type="radio" class="back-product radio" name="product">
7
</div>
8
9
<div class="card back-product">
10
<input type="radio" class="back-product radio" name="product">
11
</div>
12
13
<div class="card back-product">
14
<input type="radio" class="back-product radio" name="product">
15
</div>
I would just add and remove a class so you do not have to maintain a reference to the last selected element.
JavaScript
1
9
1
const radioList = document.querySelectorAll('.back-product.radio')
2
3
for (let i = 0; i < radioList.length; i++) {
4
radioList[i].addEventListener('change', function(event) {
5
const lastActive = document.querySelector(".card.active");
6
if (lastActive) lastActive.classList.remove("active");
7
event.target.closest(".card").classList.add("active");
8
})
9
}
JavaScript
1
7
1
.card {
2
border: 1px solid gray;
3
}
4
5
.card.active {
6
border: 2px solid lightblue;
7
}
JavaScript
1
15
15
1
<div class="card back-product">
2
<input type="radio" class="back-product radio" name="product">
3
</div>
4
5
<div class="card back-product">
6
<input type="radio" class="back-product radio" name="product">
7
</div>
8
9
<div class="card back-product">
10
<input type="radio" class="back-product radio" name="product">
11
</div>
12
13
<div class="card back-product">
14
<input type="radio" class="back-product radio" name="product">
15
</div>
If you alter the code a bit, you can just do this all in CSS
JavaScript
1
13
13
1
input[name] {
2
display: none;
3
}
4
5
.card {
6
display: block;
7
border: 1px solid gray;
8
cursor: pointer;
9
}
10
11
input[name]:checked+.card {
12
border: 2px solid lightblue;
13
}
JavaScript
1
19
19
1
<input type="radio" class="back-product radio" name="product" id="p1">
2
<label class="card back-product" for="p1">
3
X
4
</label>
5
6
<input type="radio" class="back-product radio" name="product" id="p2">
7
<label class="card back-product" for="p2">
8
X
9
</label>
10
11
<input type="radio" class="back-product radio" name="product" id="p3">
12
<label class="card back-product" for="p3">
13
X
14
</label>
15
16
<input type="radio" class="back-product radio" name="product" id="p4">
17
<label class="card back-product" for="p4">
18
X
19
</label>