Help fixing this bug

Help fixing this bug
0

#1

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.


#2

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?


#3

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!


#4

What does toggleActiveClass(target) do?

I do not see that function. If all you want to do is have the background of the currently selected div be the only one having the active class, then you could just write:

$('.table__row').click(({target}) => {
   $('.table__row').removeClass('active');
   $(target).addClass('active');
});

#5

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.


#6

@RandellDawson 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.


#7

Can you edit your last post and add a screenshot of what happens when you click the switch button and the active class is removed from the div row? I am having trouble visualizing what you are saying.

So start with everything off. Click on the Balcony State switch to turn it on and then I assume if you click it to the off position something happens you do not like?


#8

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?


#9

Thank you for the visuals. One more question to solidify what is happening. In the example above are you only talking about the Balcony row or did you click other rows too?

I ask this question, because in the 3rd screenshot, you said you click the button (I assume to off), but the blue background is still there. I thought the blue background meant the active class is still present on the row.


#10

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


#11

In this second pair of screenshots, this is the correct behavior right?


#12

I never would have known that until you mentioned it, since I can not see the code in action.

I assume the background color for the row is blue on hover AND if the row has the active class.


#13

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


#14

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


#15

Can you do me a favor and go into DevTools and click the Elements tab and copy the body element and paste it into a reply? That way, I can have actual html, so I can test out a couple of things. This is the only way for me to do this, because the html is dynamically created by the JavaScript.

EDIT: Just copy the div with class=“table-body”


#16

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>

#17

Can you post the jQuery code you are using which causes the current issue and the toggleActive Class function code?

Honestly, it would be much easier if you could just post all the code on Codepen, because then we would both be on the same page and not have to be going back and forth like this. I only have about 10 minutes left before going to bed.


#18

#19

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…