Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery UI Buttonset Not Adding Classes To Child Elements

I'm having an (intermittent) issue with jQuery UI's buttonset function. Sometimes when I call it, it only applies the classes it adds to the container div and the first child, and other times it works exactly as expected. (Sorry, I can't make a fiddle for this, I can't get it to happen outside of my application.) Same issue with both jQuery UI 1.10.0 and 1.10.4.

i.e. I start with this:

<div class="my-buttonset">
    <input type="radio" name="option" id="option1">
    <label for="option1">Option 1</label>

    <input type="radio" name="option" id="option2">
    <label for="option2">Option 2</label>

    <!-- More elements -->
</div>

and get this after calling buttonset (note the radio button does get a single, incorrect class added):

<div class="my-buttonset ui-buttonset">
    <input class="ui-corner-left" type="radio" name="option" id="option1">
    <label for="option1">Option 1</label>

    <input type="radio" name="option" id="option2">
    <label for="option2">Option 2</label>

    <!-- Other elements unchanged -->
</div>

instead of this:

<div class="container-fluid-full radio-row mode-radio-row ui-buttonset">
    <input class="ui-helper-hidden-accessible" type="radio" name="option" id="option1">
    <label class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left ui-state-hover" for="option1" role="button" aria-disabled="false" aria-pressed="false"><span class="ui-button-text">Option 1</span></label>

    <input class="ui-helper-hidden-accessible" type="radio" name="option" id="option2">
    <label class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left ui-state-hover" for="option2" role="button" aria-disabled="false" aria-pressed="false"><span class="ui-button-text">Option 2</span></label>

    <!-- Other elements correct -->
</div>

Update: I can reproduce this consistently in my application. The application uses AngularJS, and I have 2 views that make use of the button set, call them "A" and "B". It always happens if I go to "A", refresh the page, then navigate to "B". It never happens in the reverse order, or if I start from any other view in the application. Previously, it would not happen if I recreated it then navigated back to "A", but now that I refactored it into a directive, if I refresh at "A", I see the correct button set, go to "B", I see the messed up version, then navigate to "A" and I see the messed up one there too, and it also effects a second button set on "A" that is not part of the directive.

I tried recreating a basic example in JS Fiddle, with two views utilizing buttonset, but it wasn't enough to recreate the bug.

like image 668
lewax00 Avatar asked Apr 02 '14 22:04

lewax00


3 Answers

The best option for you is to make a directive out of your jQuery UI buttonset component. It is very likely that your component loads well when its UI element is viisble and fails when it's not.

Another option is to call the jQuery init function as soon as a new view is loaded, that way you make sure that the buttonset is visible when you try to initialize it.

like image 135
alcfeoh Avatar answered Oct 05 '22 23:10

alcfeoh


I've broken my head with this exactly same issue for about a day without finding a solution.

The problem, in my case, were the use of Bootstrap.

Bootstrap also manages buttons and it uses the same name buttonsas used by Jquery UI.

The solution (really really as simple as non findable!!!) were to simply change the order of inclusion on the page: Bootstrap.js first and then jquery-ui...js.

This simple thing solved the issue (also if it remains the conflict).

For a more solid solution, maybe useful to use JQuery UI Bridge or to put Bootstrap in no conflict mode (but I haven't tested these solutions at the moment, also if I'm 99% sure they will solve the problem).

NOTE: The same conflict exsists also for tooltips.

like image 34
Aerendir Avatar answered Oct 06 '22 00:10

Aerendir


try to make a directive, for post angular link with your page (sample on jsbin)

directive:

angular.module('app').directive('jsButtonset', function() {
    return function(scope, el, attrs) {
        el.buttonset();
    };
});

and use the directive at button container:

<div js-buttonset>
like image 45
Joao Polo Avatar answered Oct 05 '22 23:10

Joao Polo