2

I have a dynamically generated bootstrap .dropdown-menu and I cannot target the .dropdown-item child class.

I want to be able to toggle a class on each specific .dropdown-item when a user clicks on it.

The html looks like this after is dynamically generated:

<div class="dropdown-menu">
 <label class="dropdown-item">
  <input type="checkbox" data-field="name" value="1" checked="checked">
  <span>name</span>
 </label>

 <label class="dropdown-item">
  <input type="checkbox" data-field="price" value="2" checked="checked">
  <span>price</span>
 </label>

 <label class="dropdown-item">
  <input type="checkbox" data-field="column1" value="3" checked="checked">
  <span>column 1</span>
 </label>
</div>

I have tried targeting it directly with:

$(".dropdown-item").click(function(){
 $(this).toggleClass("item-selected");
});

but it doesn't work.

I read in an answer here: jquery selecting dynamic class id inside dynamically created div, that I needed to delegate with newly created elements and so I am able to target the dynamically generated .dropdown-menu with:

$(document).on('change',"[class*=dropdown-menu]", function() {
 alert("You clicked on a .dropmenu-item!");
 $(this).children(".dropdown-item").toggleClass("item-selected");
});

Clicking on each .dropdown-item toggles the class on all items.

I would like to only toggle the class on the specific .dropdown-item the user is clicking on

https://codepen.io/makloon/pen/mdboxEb

Thanks in advance for any advice

1 Answers1

1

Try this:

// Initialize all to selected, since that's the default state.
$('.dropdown-item').addClass('item-selected');

// Use `mousedown` since Bootstrap Tables prevents propagation of `click`.
$('.dropdown-item').on('mousedown', function(e) {
  // This runs _before_ the checkbox is checked/unchecked.
  if ($(this).find('input').is(':checked')) {
    $(this).removeClass("item-selected");
  } else {
    $(this).addClass("item-selected");
  }
});

Working example: https://codepen.io/mac9416/pen/yLBwKKv

The problem is that Bootstrap Tables prevents propagation of the click event. So we have to listen for an event that happens earlier - namely, mousedown.

And instead of using toggleClass, I've set it up to explicitly use the state of the checkbox.

crenshaw-dev
  • 7,504
  • 3
  • 45
  • 81
  • Thank you for your help. I forgot to mention that I did try that to no avail. It doesnt find the **.dropdown-item** class. – Marcus Wallace Sep 25 '19 at 14:51
  • Can you set up a minimal reproduction of the problem on something like codepen? – crenshaw-dev Sep 25 '19 at 14:53
  • @MarcusWallace updated with example, and maybe a way to solve a second bug. – crenshaw-dev Sep 25 '19 at 15:11
  • @MarcusWallace I think Bootstrap Tables is stopping the event from bubbling up... I'm trying to find a workaround. – crenshaw-dev Sep 25 '19 at 15:35
  • It works on the 3 checkboxes generated by your suggestion but not on the ones generated by the Bootstrap Tables – Marcus Wallace Sep 25 '19 at 15:48
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/199971/discussion-between-michael-crenshaw-and-marcus-wallace). – crenshaw-dev Sep 25 '19 at 15:49
  • Success! I just had to invert the background color on the .dropdown-item classes to suit my needs. I works perfectly. Thank you! – Marcus Wallace Sep 25 '19 at 16:11
  • @MarcusWallace you bet! I noticed some states where a mousedown won’t result in a checkbox state change. That may require a setTimeout to resolve. The ideal solution would be for Bootstrap Tables to fire an afterChange event (since it’s hiding the input’s change event). Then you could just loop over the items and set the appropriate classes. – crenshaw-dev Sep 25 '19 at 16:16