I have 2 radio buttons. Each of these radio buttons are connected to an image.
At the start these images are in black and white (filter:grayscale(1)
).
When one of these buttons are selected, I want the image the button relates to turn (filter:grayscale(0)
).
The grayscale
filter attribute is specified in the <img>
element. Each of these radio buttons are wrapped into a seperate div, with their respective <img>
.
The first step (I think) is to collect the input name that relates to the radio button that is selected. And this works.
I believe from this input name, I need to search for the parent div, and then look for the <img>
element it relates to.
I will admit it, writing this feels a bit complicated. But I cannot think of a better way.
my problem
Where I am struggling now is to fetch the parent div based on the checked input name.
I found a bit of document using either .parentElement()
, .parent()
and parent.Node()
but none of these work. Or probably I am not using them properly.
Then once the parent div is identified, I can probably look for the child <img>
element.
My question(s)
- How do I access the parent div from the child element id?
- Is there a better way/ simpler way to achieve this?
$(document).ready(function() {
/*Manages Radio buttons & images rendering when clicked*/
$('input[name="hero-avatar"]').change(function() {
// Check if the radio button is checked
if ($(this).is(':checked')) {
// captures id of button that is checked
let checkButton = $(this).attr('id');
// Log checked radio button id
console.log(checkButton);
//test to find parent div class
console.log($(`#${checkButton}`).parent().attr('class'));
//this works but doesnt reach the parent div class which contains grayscale property
$(`#${checkButton}`.parentNode).css('filter', 'grayscale(0)')
}
});
//if radio button is checked
//change colour of image attached to it
});
.avatar-img-select {
height: 52px;
filter: grayscale(1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="row first-screen-row-avatar">
<div class="col select-avatar-col">
<label for="avatar1">
<img src="assets/images/avatars/hero-avatar-1.jpg" class="avatar-img-select" alt="Avatar 1">
<input type="radio" id="avatar1" name="hero-avatar" value="assets/images/avatars/hero-avatar-1.jpg" required>
</label>
</div>
<div class="col select-avatar-col">
<label for="avatar2">
<img src="assets/images/avatars/hero-avatar-2.webp" class="avatar-img-select" alt="Avatar 2">
<input type="radio" id="avatar2" name="hero-avatar" value="assets/images/avatars/hero-avatar-2.webp" required>
</label>
</div>
</div>
>Solution :
You can do this entirely without jQuery or JavaScript and a CSS one-liner using :has()
:
label:has(input:checked) img {
filter: grayscale(0);
}
label:has(input:checked) img {
filter: grayscale(0);
}
.avatar-img-select {
height: 52px;
filter: grayscale(1);
}
<div class="row first-screen-row-avatar">
<div class="col select-avatar-col">
<label for="avatar1">
<img src="assets/images/avatars/hero-avatar-1.jpg" class="avatar-img-select" alt="Avatar 1">
<input type="radio" id="avatar1" name="hero-avatar" value="assets/images/avatars/hero-avatar-1.jpg" required>
</label>
</div>
<div class="col select-avatar-col">
<label for="avatar2">
<img src="assets/images/avatars/hero-avatar-2.webp" class="avatar-img-select" alt="Avatar 2">
<input type="radio" id="avatar2" name="hero-avatar" value="assets/images/avatars/hero-avatar-2.webp" required>
</label>
</div>
</div>