What is an effective way to write a JavaScript if-statement that transfers a data-active attribute from one div to another when a radio is checked?
If this has already been solved somewhere then please share a link. I can’t find one that does.
The goal is to navigate to the corresponding image when a radio is checked, and check the radio when the corresponding image is [data-active].
radio1.addEventListener('click', function(e){
let radio1 = document.querySelector("#radio1");
let radio2 = document.querySelector("#radio2");
let radio3 = document.querySelector("#radio3");
let first = document.getElementsByClassName("first");
let second = document.getElementsByClassName("second");
let third = document.getElementsByClassName("third");
if(first = ["data-active"], "true"){
radio1.classList.add("activeRad");
radio1.classList.remove("inactiveRad");
}
});
<!-- Radio buttons -->
<div class="radio-inputs">
<input class="radio-button" type="radio" name="radio-btn" id="radio1">
<input class="radio-button" type="radio" name="radio-btn" id="radio2">
<input class="radio-button" type="radio" name="radio-btn" id="radio3">
</div>
<!-- Carousel -->
<div class="list" data-slides>
<div class="listItem first" data-active>
<img src="https://placehold.co/100x100/000000/FFFFFF/png" alt="">
</div>
<div class="listItem second">
<img src="https://placehold.co/100x100/000000/FFFFFF/png" alt="">
</div>
<div class="listItem third">
<img src="https://placehold.co/100x100/000000/FFFFFF/png" alt="">
</div>
</div>
3
Answers
Instead of having multiple change events, I’m using a forEach loop on querySelectorAll looking for all radio-buttons.
On each radio button I have a data-target attribute that corresponds to a matching data-id attribute on a div holding an image. I prefer this over IDs as IDs can get messy.
In my event handler, I look for the radio button that was changed (via ev.target).
I also look for anything that already has activeRad. If that exists, I remove that class so we don’t have duplicates.
Then I simply use the target from the data-target to find the div to add the activeRad class to.
Then at the very end I check to see if any divs already have the activeRad class. if so, take that div’s id and check the radio that has the matching data-target.
I chose to use a single class instead of inactive and active as inactive can be achieved by targeting the .listItem in CSS.
You shouldn’t be using
data-
attributes here (and you are not using them correctly). Instead, CSS classes are the way to go.Also, the use of
id
attributes, while simple enough, leads to brittle code that doesn’t scale easily. In most cases, you don’t need them though because there are several other ways to get element references (as you can see below).By avoiding the use of
id
and by setting up just one event handler that can handleclick
events from any element within it, the code below is very scalable. If you need to add more radio buttons and images, just update the HTML accordingly and you won’t need to touch the JS at all. 🙂There’s no need for an
inactive
class as an element becomes inactive as soon as theactive
class is removed from it.See comments inline below for details:
I don’t think you need to toggle classes as others suggest if all you want to do is change some CSS, you can use the data attribute and value.
Now, you want to add another one you don’t need to change code just add elements with the right values. As a bonus the new guys target selector can be anything that works AND even have different active style!