Help fixing this bug

I need help to fix a small bug. I have a node list of 9 elements with the class “table__row” and a toggle class function that looks like this:

const toggleActiveClass = (trigger) => {

  if (trigger.parent().hasClass('active')) {
    trigger.parent().removeClass('active')
  } else {
    $('.table__row').removeClass('active')
    trigger.parent().addClass('active')
  }
}

I am calling this function in this event:

$('.table__row').click(event => {
  const target = $(event.target);
  toggleActiveClass(target)
})

The bug is that when I click one of the nodes sometimes the toggle class function will apply to all node elements, resulting this in a bug. It should only apply to the node element that triggers the event, which it does by the way.

The structure of the HTML is something like this:

<div class="table-body">
 <div class="table__row">Some more elements nested here</div>
 <div class="table__row">Some more elements nested here</div>
 <div class="table__row">Some more elements nested here</div>
 <div class="table__row">Some more elements nested here</div>
 <div class="table__row">Some more elements nested here</div>
 <div class="table__row">Some more elements nested here</div>
 <div class="table__row">Some more elements nested here</div>
 <div class="table__row">Some more elements nested here</div>
</div>

If you need any more details please let me know, this bug is driving me crazy.

Umm now that I think about I think this is happening because the active class is applying to the div with the class “table-body” if I happen to click the div with “table__row” class instead of one the nested child within this div.

As I suspected that’s exactly what’s going on, I tried this to find out:

$('.table__row').click(event => {
  const target = $(event.target);

  if (target.hasClass('table__row')) {
    return console.log('Testing');
  } else {
    toggleActiveClass(target)
  }
})

Even though now the active class isn’t apply to the div with class “table-body”, this solution doesn’t fix my issue. What DOM element am I supposed to target here to make this work?

I fixed my bug as followed:

$('.table__row').click(event => {
  const target = $(event.target);

  if (target.hasClass('table__row')) {
    $('.table__row').removeClass('active')
    target.addClass('active')
    console.log('Testing');
  } else {
    toggleActiveClass(target)
  }
})

But I don’t think this is the finest solution because I am repeating myself and I think I will have to deal with this traversing DOM problem again, so any ideas of how you would do this is greatly appreciated!

toggleActiveClass applies a background-color to the parent of the selected element by applying an active class, and remove the same class from the rest of the divs if they have that class.

Here’s how the structure looks like in case you are wondering:

data.map(el => $('.table-body').append(`
<div class="table__row">
     <div class="table__column">${el.room}</div>
     <div class="table__row--inner-wrapper table__column">
      <label class="switch">
        ${el.checked ? `<input class="switch-check" type="checkbox">`: `<input type="checkbox">`}
        <span class="slider"></span>
      </label>
      <span>${el.state}</span>
     </div>
     <div class="table__column">
      ${el.checked ? `<span class="percentage">${el.brightness + '%'}</span>` : `<span class="percentage">0%</span>`}
     </div>
   </div>`))

You can see that I have a lot a of nested elements within the div with the “table__row” class. I don’t think traversing the DOM to apply the active class is the best idea, because now Im running into another issue. If I click the span element with the class “slider”, now the active class will apply to its parent, which is the label, instead of the div with “table__row” class.

@camperextraordinaire take a look at this image:

48%20AM

The first element was clicked and the active class was applied, but if I click the switch button the active class is removed from the div row, and I don’t want that to happen. But I know this is happening because I am traversing the DOM to apply this class.

This is how the original state looks like:
12%20AM

When a row is clicked, then applies an active class to the selected row (that’s what the toggleActiveClass function is for):

25%20AM

But if I click on the switch button the active class is removed and I don’t want this behavior:
00%20AM

Or even worse, if I click where it says “On” or the percentage this happens:
40%20AM

As you probably might’ve guessed, I only want to apply the active class to the div row, and I don’t want to remove the class from the row if the switch button is selected. I know this is happening because I chose to apply this class traversing the DOM, do you think it would be better if I get the index of the row and apply the class to the div row based on its index?

Only the Balcony row, but you should know there’s a hover effect, that’s why the background color of the Balcony row is blue even when it no longer has the active class.

And in case you still have any doubts of what the toggleActiveClass function does, here’s an example:

Balcony was clicked, apply active class;
04%20AM

Living Room was clicked, remove active class from all other rows and applies active to this selected row.
14%20AM

Yes, that is correct. The issue is when I click the switch button or any other nested child as shown in my other post.

There’s a blue background color hover effect for the rows whether or not they have the active class.

This is the table-body div with one row as en example, there are 8 rows in total.

<div class="table-body">
  <div class="table__column">Balcony</div>
    <div class="table__row--inner-wrapper table__column">
     <label class="switch">
       <input class="switch-check" type="checkbox">
       <span class="slider"></span>
     </label>
     <span>On</span>
    </div>
    <div class="table__column">
     <span class="percentage">50%</span>
    </div>
</div>

This fixed the issue:

$('.table-body').click(event => {
  let target = $(event.target);

  if (target.hasClass('switch-btn')) {
    target.closest('.table__row').addClass('active')
  } else if (target.hasClass('table__column') || target.is('span')) {
    target = $(event.target).closest('.table__row');
    toggleActiveClass(target)
  }
});

I was trying ending the function execution like this:

if (target.hasClass('switch-btn')) {
    return;
  } 

But it did not work, not sure why…