How to select the tr of a td with vanilla JavaScript?

I have the following HTML.

<tr>
    <td class="a">
    <td class="b">
</tr>

<tr>
    <td class="a">
    <td class="b">
    <td class="c">
</tr>

I want that any <tr> which has <td class="c"> will get a yellow background color.

What is the best way to do that with vanilla JavaScript?

If parentNode was a method instead of a property I could do something like this pseudocode:

document.querySelector(".c").parentNode("tr").style.background = "yellow";

Is there some “uppermostDifferentParent” property to use here?

Maybe something like this:

const myElem = document.querySelectorAll(".c");
myElem.forEach(function (elem, index) {
  elem.closest("tr").style.background = "yellow";
});

Although I would prefer to use css to style things using a class.

2 Likes

That worked ! Thanks a lot.

I have also fixed all the syntax mistakes I had in the question.

1 Like

It does seem like it would be easier to just add a class to the table e.g.

HTML

<table id='my-table'>
  <tr>
      <td class="a">item 1</td>
      <td class="b">item 2</td>
  </tr>
  
  <tr>
      <td class="a">item 1</td>
      <td class="b">item 2</td>
      <td class="c">item 3</td>
  </tr>
</table>

CSS

table.hightlight-a .a,
table.hightlight-b .b,
table.hightlight-c .c {
  background-color: yellow;
}

JS

const table = document.querySelector('#my-table');
// to highlight the 'c's  
table.classList.add('hightlight-c');

edit: Scrap the above. As Paul pointed out, it is the table row that needs styling not the cells.

In this particular scenario, the parent of a <td> will always be a <tr>, so there’s no reason you can’t just use .parentNode or parentElement.

document.querySelector('.c').parentElement.style.background = 'yellow';

That would only style the td itself and not the parent tr that provides a background to the whole row :slight_smile:

Oops! Missed that detail. Scrap that then.

.highlight-a tr:has(.a),
.highlight-b tr:has(.b),
.highlight-c tr:has(.c) {
  background-color: yellow;
}

.has still isn’t ready for prime time though, so I guess it’s back to JS and parent elements.

1 Like

Yes I did have a css version :slight_smile: and all that was needed was:

tr:has(td.c){background:yellow;}

No Js harmed at all :slight_smile:

The css :has property is now up to 89% support which is all the major browsers.

2 Likes

I wasn’t sure if the JS was there to add the style dynamically e.g. maybe on a click. If not then as you point out no JS — which is nice :slight_smile:

2 Likes

It does seem like it would be easier to just add a class to the table e.g.

I can’t really control the sub-table itself backendly because it is generated by a content management system and much longer than having only two or three td elements.

In this particular scenario, the parent of a <td> will always be a <tr> , so there’s no reason you can’t just use .parentNode or parentElement.

Yep, that worked as well, nice to know that. Thanks !