jQuery UI Cookbook
上QQ阅读APP看书,第一时间看更新

Controlling the spacing with buttonsets

The jQuery UI toolkit gives developers a container widget used for working with groups of buttons called a buttonset. You would use a buttonset for things like groups of checkboxes or groups of radio buttons—things that form a collaborative set.

The default appearance of the buttonset is of a unified whole. That is, the goal is to form a seemingly single widget out of several buttons. By default, the buttonset widget has no spacing controls for the developer. The buttons within the set, by default, are all stacked up against one another. This may not be what we're after, depending on the context of the buttonset widget in our overall user interface.

Getting ready

To better illustrate the spacing constraints we're presented with, let's build a buttonset widget and look at the result before we go about trying to resolve the issue. We'll use the following group of radio buttons as our markup:

<div>
    <input type="radio" id="first" name="items" />
    <label for="first">Item 1</label>
    <input type="radio" id="second" name="items" />
    <label for="second">Item 2</label>
    <input type="radio" id="third" name="items" />
    <label for="third">Item 3</label>
    <input type="radio" id="fourth" name="items"/>
    <label for="fourth">Item 4</label>
</div>

And we'll create the buttonset widget as follows:

$(function() {
    $( "div" ).buttonset();
});

Here is what our buttonset looks like. Notice that this widget still exhibits radio button functionality. Here the third item is selected, but will become deselected if I were to click elsewhere in the widget.

How to do it...

Now, there is nothing wrong with the default presentation of the buttonset widget. The only potential challenge we might face is if we have a spacing theme happening elsewhere in the application—the stacked against one another look of the widget just might not fit in from an aesthetic perspective. We can tackle this issue with relatively little effort by extending the widget with an option that allows us to "explode" the buttons so that they're no longer touching.

We'll implement this new exploding buttonset capability by extending the buttonset widget and adding a new option that will enable this behavior. The HTML stays the same as previous, but here is the new JavaScript code.

(function( $, undefined ) {

$.widget( "ab.buttonset", $.ui.buttonset, {

    options: {
        exploded: false
    },

    refresh: function() {

        this._super("refresh");

        if ( !this.options.exploded ) {
            return;
        }

        var buttons = this.buttons.map(function() {
            return $( this ).button( "widget" )[ 0 ];
        });

        this.element.addClass( "ui-buttonset-exploded" );

        buttons.removeClass( "ui-corner-left ui-corner-right" )
               .addClass( "ui-corner-all" );

    }

});

})( jQuery );

$(function() {
    $( "div" ).buttonset( { exploded: true } );
});

We'll want to include the following CSS on the page—including it via a new stylesheet is the recommended practice here:

.ui-buttonset-exploded .ui-button {
    margin: 1px;
}

How it works...

Our extension of the buttonset widget adds the exploded option, allowing the programmer using the widget to specify whether they would like the individual buttons separated from one another or not. We also override the refresh() method here in order to alter the display if the exploded option is true.

To do this, we create a jQuery object representing all the individual buttons in the buttonset. The reason we're using map() here is because of a work-around required with checkbox and radio buttons. The ui-buttonset-exploded class adds the margin that we're looking for between the buttons—it explodes them outward. Next, we remove the ui-corner-left and ui-corner-right classes from any of the buttons, and add the ui-corner-all class to each button that gives them each their own independent borders.