Shape Up Your Buttons with jQuery UI

Dino Esposito | June 17, 2010

 

A graphical user interface wouldn’t be the same without buttons. On the Web, browsers offer a default rendering for push buttons and other types of buttons. By using CSS styles, you can modify the visual rendering of buttons but each button remains of a basic type—whether push button, checkbox, radio button and so forth.

Development practice has raised slightly different needs and pushed different and a bit more sophisticated uses of buttons. So, for example, you might want to have a list of checkboxes or a list of radio buttons, a toolbar, or perhaps a split button. All of these aggregates can be obtained programmatically but that’s just the point—you have to write the code and adapt it to many slightly different scenarios over and over again.

The jQuery UI library can provide some good help also with buttons. Support for scripting buttons, in fact, has been added to version 1.8. Let’s find out more.

Simple Buttons

jQuery UI 1.8 incorporates a new widget to style and configure any types of buttons you can have in your Web page. All you need to do is shown below:

$("#button1").button();

The element with a “button1” ID can be any element that produces a HTML button or a clickable element such as an anchor. Here’s a (non exhaustive) list of HTML button elements to which the preceding code can be successfully applied.

<button id="btn1" type="submit"> OK </button> 
<input id="btn2" type="submit" value="Save" />  
<input id="btn3" type="reset" value="Reset" />  
<input id="btn4" type="button" value="Test" />  
<a id="btn5" href="#"> Click me </a>

As you can see, you apply the button widget to <button> elements as well as classic <input> button elements and hyperlinks. In HTML , the <input> element for buttons can be of type submit, reset, button; all these styles are fully supported by the jQuery UI button widget. The list is completed by special types of buttons such as radio and checkbox. So the following HTML elements would be supported by the widget too:

<input id="btn2" type="checkbox" />  
<input id="btn3" type="radio" />

It should be noted that radio buttons are not supported individually but only as part of a collection. This is overall reasonable as a single radio button makes not much sense in reality. Check boxes, instead, are supported both as individual elements and as part of a collection.

What’s the ultimate effect of calling button() on an appropriate input button element? It simply transforms the native HTML element into a themeable button and offers the programming interface of a classic push button. It turns out that for a <button> element and for submit or push button elements the jQuery UI widget works mostly as a way to apply a theme quickly. When you apply it to checkbox, anchors, or radio elements then some deeper customization is performed as the element is rendered like a classic button and reacts to the click event as if it were a native button.

Checkbox Buttons

A checkbox is a graphical element commonly used to express a binary choice: checked or not. The typical graphics is a square the user can tick on or off by clicking. You can express the same concept by showing a button in a pressed or depressed state. A pressed button indicates the option is selected; a depressed button indicates, instead, that the option is not selected.

The following code transforms a classic checkbox in a two-state button.

$("#checkbox1").button();

The original HTML is the following.

<input id="checkbox1" type="checkbox" checked="checked" />
<label for="checkbox1">
Show more information
</label>

The graphical output is shown in Figure 1 where you can see the look-and-feel of a button in a pressed/depressed state. The style is determined by the default Sunny theme of the jQuery UI library.


Figure 1—A checkbox transformed in a two-state button.

From the programming perspective, nothing is different from having a classic checkbox. At the DOM level, in fact, it still remains a checkbox. Any transformation is purely graphical and no standard features are removed.

Note that a checkbox doesn’t have any associated text per se. The text you often see displayed side of a check box comes from a separate HTML element—a <label> element whose for attribute matches the ID of the check box. In jQuery UI, the value of the <label> element, if any, is used as the text for the button. You can set the label of a button programmatically by used the label property of the button widget. Here’s how to do it upon initialization.

$("#CheckBox1").button({ label: "Your button caption" });

Likewise, to read and write the current caption of a jQuery UI button you can use the option method of all jQuery UI widgets. The following code shows the typical usage of the getter and setter of the label property:

// This is the getter
var caption = $("#CheckBox1").button( "option", "label" );

// This is the setter
$("#CheckBox1").button( "option", "label", "Your button caption" );

The option method works for whatever type of underlying element you have transformed into a button.

Building a Checkbox List

The checkbox element is extremely useful to let users express a choice. When the business rule requires that a choice is made among multiple options, you render out a list of checkboxes. In jQuery UI, you can apply button transformations also to a group of check boxes. You need to resort to a slightly different function, though. No big deal, after all, as the following code snippet demonstrates.

$("#Toppings").buttonset();

You should use a new function—named buttonset(). The function groups together all buttons that the query selects. In the example, Options is the ID of a <div> tag; as a result, all child buttons are grouped together. Here’s an example of some valid HTML markup that can be transformed into a sort of button bar.

<div id="Toppings">
     <input type="checkbox" id="checkbox1" />
     <label for="check1"> Cheddar </label>
     <input type="checkbox" id="checkbox2" />
     <label for="check2"> Mushrooms </label>
     <input type="checkbox" id="checkbox3" />
     <label for="check3"> Bacon </label>
</div>

Figure 2 shows the graphical result of the above HTML markup transformed into a jQuery UI button set.


Figure 2—Multiple check boxes grouped together and handled as a single unit.

In Figure 2, the first two elements are currently selected. If the user clicks on, say, Bacon the corresponding button will be rendered in a selected state. Clicking on a selected button will immediately deselect the button.

It is key to note that the jQuery UI button API doesn’t offer any support to query the state of a button in a button set. When you happen to use a check box list like in Figure 2, it is likely that you also need to read at some point which buttons are selected. You can rely on the core jQuery API to query buttons. Here’s a possible way to do that:

$("#Toppings input:checked").each(function() {
     alert(this.id);
});

You use the input:checked selector to pick up all input elements that are currently checked and located under the element with an ID of Options. You then process all of them recursively using the each function.

More on Button Sets

Let’s spend a few more words about the internal behavior of button sets. When you invoke the buttonset function on an element, all descendent elements of the selector are selected. Each selected element is then applied the transformation as produced by the button() function. For this reason, you should call button set on the container element of the buttons to transform.

To perform operations on a set of buttons, you first need to write a jQuery selector that returns all desired buttons and then you call the button method you wish. For example, you need the following code to disable a button set:

// You first create the button set (which transforms 
// classic check boxes into buttons)
$("#Toppings").buttonset();

// Second, you disable/enable/destroy all buttons by 
// selecting them via the jQuery syntax
$("#Toppings input:checkbox").button("disable");

Radio Buttons

Admittedly, an individual radio button doesn't make much sense. To work with radio buttons in a sensible manner, you first need to transform them into a button set. The code you need is nearly identical to what we already saw for check boxes.

$("#Options").buttonset();

The original HTML, of course, is slightly different.

<div id="Options">
     <input type="radio" id="radio1" />
     <label for="radio1"> True </label>
     <input type="radio" id="radio2" />
     <label for="radio2"> False </label>
     <input type="radio" id="radio3" />
     <label for="radio3"> Don’t know </label>
</div>


Figure 3—A radio button list for mutually exclusive choices.

Adding an Icon

Another fairly common feature of Web buttons is mixing text and images. When you want a really cool button, then you hire a designer and get a bunch of buttons with appropriate text and graphics. In other situations, you just use links but surround such links with creative CSS style to make the final result look like regular push buttons.

The jQuery UI library just makes it easier for everybody to have nice looking buttons without having to hire a designer. (That still remains the option that delivers you the best quality, but you don’t need it all the times.)

A common demand is mixing text and images in a button but still preserving the classic programming interface and behavior of a button. Regular HTML just doesn’t allow for that and to achieve this goal you need a mix of JavaScript and HTML. The button widget is a shortcut to this.

The button widget supports the icons property which turns out to be a container for two possible icons. The primary icon is displayed on the left of the label text; the secondary icon, if any, is placed right of the text. The label for the button is optional. You control the text display through the text property which accepts a Boolean value. Note, though, that if the text is off, and you don’t indicate an alternate icon (or two) the setting is ignored and the label (if specified) is displayed as usual.

The jQuery UI library doesn’t allow you place just any icons on a button. Supported icons are defined in the jQuery UI theme as a class. The CSS style is, on the other hand, entirely customizable both manually and through the ThemeRoller tool available at https://jqueryui.com/docs/Theming/Themeroller.  Here’s an example of how you set up an icon for a button:

$("#Button1"). button( {
                text: false,
                icons: {
                    primary: "ui-icon-triangle-1-s"
                }
            })

If you need a secondary icon, just extend the icons object with an additional entry like

icons: {
    primary: "ui-icon-triangle-1-s",
    secondary: "ui-icon-locked"
}

As mentioned, values for the primary and secondary icons are CSS class names defined in the theme style sheet. Here’s an excerpt:

.ui-icon { 
           width: 16px; 
           height: 16px; 
           background-image: url(images/ui-icons_d19405_256x240.png); 
}
:
.ui-icon-triangle-1-s { 
           background-position: -64px -16px; 
}

The base class ui-icon defines the PNG file that contains all of the library icons and the expected size of each icon (16x16 by default). Next, the specific class that identifies a particular icon just selects the offset of the particular icon in the general PNG file. Figure 4 shows the content of the overall PNG file; the actual content and colors depend on the current jQuery UI theme.


Figure 4—A sample file with supported icons.

Building a toolbar

A toolbar is no more no less a collection of buttons—any type of buttons, including classic push buttons, check boxes and radio buttons. It turns out, therefore, that building a toolbar in jQuery UI isn’t that complicated. All you need to do is placing all the buttons you want under a unique HTML container—usually a DIV element—and then invoke the method button() for each button. Here’s the HTML template of a toolbar:

<div id="container">
   <button> ... </button>
   <button> ... </button>
   <button> ... </button>
   <input type="checkbox" ... />
   <span>
     <input type="radio" ... />
     <input type="radio" ... />
  </span>
</div>

You need to configure each button individually, however. This is necessary in order to assign each button its own icon and click handler. Here’s a sample of the code you need for each button.

$('#Button1').button({
    text: false,
    icons: { primary: 'ui-icon-play' }
})
.click(function() {
    // Do something ...
});

The Plus of the Button Widget

In Web applications, buttons and links are the only two ways to command operations from the client side.  In server-side ASP.NET programming, handling click events on links and push buttons has always been the same since the advent of ASP.NET and the Web Forms framework. On the client side, push buttons (typically, submit buttons) and links have always been two different types of animals with different capabilities. Not to mention all possible number of variations on the theme of buttons — toolbars, radios, check boxes, tri-state check boxes, split buttons and so forth.

The Button widget in jQuery UI attempts to unify the programming interface and the graphical rendering of buttons. In this way, the first takeaway is the ability to render (and handle) push buttons and links in the same way. Next, the Button widget represents an excellent starting point to combine simpler buttons together to build more sophisticated buttons such as split buttons, toolbars and whatever else you may ever happen to need during the development of a Web page.

 

About the Author

Dino is the author of "Programming ASP.NET MVC" for Microsoft Press and also coauthored the bestseller "Microsoft .NET: Architecting Applications for the Enterprise" (Microsoft Press 2008). A long time author and experienced consultant and trainer, Dino lives in Italy (when not traveling) and plays tennis (when not injured).