Accessing parent div from child element

Advertisements

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)

  1. How do I access the parent div from the child element id?
  2. 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>

Leave a ReplyCancel reply