Question

I have a checkbox-button-group like this:

<div class="btn-group" id="id_group" data-toggle="buttons-checkbox">
  <button class="btn myclass" type="button" data-value="0">Value 0</button>
  <button class="btn myclass" type="button" data-value="1">Value 1</button>
</div>

And the JS event handler:

$(".myclass").click(function(event) {
  console.log($(".myclass.active").length);
  console.log($(this).hasClass("active"));
});

I want to get the data-value for all checked buttons, but on the click event, the active class is not yet set. That means, when I first click a button, the output is:

>>> 0
>>> false

And the next time I click the same button (i.e., uncheck it), the output is:

>>> 1
>>> true

That means the active class is being set after the event.

How can I get the real state of the button during the click event?

Was it helpful?

Solution 2

If you desperately want an event each time the class active is added to a button, you could modify the bootstrap.js. active is set/unset in a small function Button.prototype.toggle triggered by click, line 1362-1370 :

Button.prototype.toggle = function () {
    var $parent = this.$element.closest('[data-toggle="buttons-radio"]')

    $parent && $parent
      .find('.active')
      .removeClass('active')

    this.$element.toggleClass('active')
  }

change this to

Button.prototype.toggle = function () {
    var $parent = this.$element.closest('[data-toggle="buttons-radio"]')

    $parent && $parent
      .find('.active')
      .removeClass('active')

    this.$element.toggleClass('active')

    if (this.$element.hasClass('active')) {
        this.$element.trigger('active')
    }
  }

now you have an event you can bind to .myclass

$(".myclass").on('active', function() {
  console.log($(".myclass.active").length);
  console.log($(this).hasClass("active"));
});

OR, if you think the above is too dirty - you can extend / modify the Button.prototype (adding methods, options etc) by following the skeleton described here How to Extend Twitter Bootstrap Plugin

OTHER TIPS

I've been having issues with the click event and the timing of the active class too!

Furthering davidkonrad's answer and using this post I came up with the following to avoid having to modify bootstrap source but a bit more lightweight than a full override.

var _old_toggle = $.fn.button.prototype.constructor.Constructor.prototype.toggle;

$.fn.button.prototype.constructor.Constructor.prototype.toggle = function () {
    _old_toggle.apply(this);

    if (this.$element.hasClass('active')) {
        this.$element.trigger('active')
    }
}

You have deduced correctly. The click event has not updated the active class yet, so when you are searching for them, it does not return. There is no event that is triggered for class change.

However, what you can do is add a setTimout of say, 100ms, enough time to allow the click event to have triggered. Note, you may need to adjust the delay to allow the event propagation.

I used jQuery's data management to store an active state, toggling it on button clicks. Not very nice either but it's something.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top