Checkboxes

Dijit's collection of form widgets provides a convenient and flexible range of options for creating rich forms. In this tutorial we will look at the options available for checkbox-style interaction.

Getting Started

The checkbox and radio button are staples of any user interface that requires input and selection. Dijit includes the dijit/form/CheckBox and dijit/form/RadioButton widget modules that can be used as drop-in replacements for the native checkbox and radio button elements. These widgets are themed to help create a consistent look and feel when building forms and to provide a convenient set of methods for managing input value and state.

The driving principle in Dijit's form widgets is to enhance the native controls while preserving the existing semantics and patterns of use where they make sense. So, you can expect CheckBox and RadioButton widgets to support all the same functionality you're used to in native checkbox and radio input types.

Declare a CheckBox

Like all Dijit widgets, dijit/form/CheckBox can be instantiated using markup (declaratively) or in code (programmatically). The following two examples create an initially-checked CheckBox:

<input type="checkbox" id="dbox1" checked
    data-dojo-type="dijit/form/CheckBox">
<label for="dbox1">Want</label>
require(["dijit/form/CheckBox"], function(CheckBox) {
    var box1 = new CheckBox({
        id: "pbox1",
        checked: true
    });

    // place the widget on the page
    box1.placeAt("pbox1_container", "first");
});

View Demo

Clicking on either the label or the input itself toggles it between a checked and unchecked state. You can also use the tab key to navigate between controls using the keyboard and check/uncheck elements with the space bar, just as you can with native controls. By referencing the corresponding CheckBox widget's ID, HTML labels also continue to work the same as they would with a native form element.

One of the new features introduced in Dojo 1.6 was the ability to use HTML5 data-dojo-type attributes instead of dojoType attributes. In Dojo 1.6, however, data-dojo-type prevented Dojo from picking up values from standard HTML attributes, which meant that you needed to duplicate all of your normal HTML attribute values (checked, disabled, etc.) in data-dojo-props if you choose to use this attribute. This issue was resolved in Dojo 1.7.

Checkbox Values

All Dijit form widgets have getter and setter methods to retrieve and update the widget's value (<var>widget</var>.get("value") and <var>widget</var>.set("value")). Remember that for native checkboxes, a checkbox's value is only sent to the server if it is checked. Dijit's CheckBox works somewhat similarly: if it is in a checked state, <var>widget</var>.get("value") will return the value property of the widget. Otherwise, it returns false. If no value property has been provided or set, dijit/form/CheckBox has a default value of "on". We can infer the checked state by asking for the value and seeing if we get a boolean false back, or we can inspect the checked property itself:

require(["dijit/registry"], function(registry){

    var toppings = [];
    if(registry.byId("topping1").get("checked")){
        toppings.push(registry.byId("topping1").get("value"));
    }

    if(registry.byId("topping2").get("value") !== false){
        toppings.push(registry.byId("topping2").get("value"));
    }

View Demo

This demo also wires up an additional CheckBox which modifies the value of one of the others, providing an example of the value property setter:

registry.byId("deluxe").on("change", function(isChecked){
    registry.byId("topping2").set("value", isChecked ? "kalamata olives" : "olives");
}, true);

When you pass a truthy (i.e. non-empty, non-zero) value to a dijit/form/CheckBox, the widget is automatically put into a checked state.

Radio Buttons

Much of what we've discussed so far in the context of checkboxes and dijit/form/CheckBox is also true of Dijit's radio button widget, dijit/form/RadioButton. A radio button differs from a checkbox in that it is:

  • Typically rendered as a disc, with or without a circular dot inside depending on its checked state
  • Used for single-choice selections, where only one of a series of items can be checked at a time

Otherwise, its use is very similar to the checkbox. Let's see an example:

<ul>
    <li>
        <input id="topping1" type="radio" name="topping" value="anchovies" checked
            data-dojo-type="dijit/form/RadioButton">
        <label for="topping1">Anchovies</label>
    </li>
    <li>
        <input id="topping2" type="radio" name="topping" value="olives"
            data-dojo-type="dijit/form/RadioButton">
        <label for="topping2">Olives</label>
    </li>
    <li>
        <input id="topping3" type="radio" name="topping" value="pineapple"
            data-dojo-type="dijit/form/RadioButton">
        <label for="topping3">Pineapple</label>
    </li>
</ul>

View Demo

The key difference here is the use of the name property. Just as with native HTML radio controls, you associate a group of Dijit radio buttons by having them share a name property. Now, when you check one of the options in the list, the others are automatically unchecked.

It is common to want to treat a series of radio buttons as a single control, and to get the value of whichever is checked at that time. The dojox/form/CheckedMultiSelect widget provides this functionality.

Events

So, we can create and interact with these fine looking controls. What else can we do? Like many of the widgets provided by Dijit, RadioButton and CheckBox provide methods you can hook into for notification when activity occurs. A full list of these events can be found in the API docs. For our next demo, we'll focus on the one you'll probably use most often: change.

registry.byId("topping1").on("change", function(isChecked){
    if(isChecked){
        summaryNode.innerHTML = "Likes the salty!";
    }
}, true);

registry.byId("topping2").on("change", function(isChecked){
    if(isChecked){
        summaryNode.innerHTML = "Likes the sweet!";
    }
}, true);

registry.byId("crust").on("change", function(isChecked){
    remarkNode.innerHTML = isChecked ? "Healthy gums!" : "";
}, true);

View Demo

We saw a sneak preview of this in our earlier value getters & setters demo. The pattern is simple since dojo/aspect lets us treat the widget method just the same way that we might treat a DOM event on a regular element. The listener function receives the checked state as a sole argument, and we respond by updating a message on the screen. The many events provided by these widgets opens up a broad range of interaction and form-logic options.

dijit/form/ToggleButton

We will cover one more variation on the boolean-state button: dijit/form/ToggleButton. A toggle button is a button that has two states. It is functionally very similar to CheckBox and RadioButton, but the user interface is different. Each state can contain an icon, text, or both. The icon is defined using a CSS class.

<input type="checkbox" dojoType="dijit/form/ToggleButton" checked iconClass="dijitCheckBoxIcon" label="Toggle Me">
var myToggleButton = new ToggleButton({
    checked: true,
    iconClass: "dijitCheckBoxIcon",
    label: "Toggle Me, Too."
}, "toggleButtonProgrammatic");

View Demo

In this widget, the label property is mandatory for correct functionality. Like all other properties, after initialization, label and iconClass can be updated via the set method:

// provide a new label for the button
myToggleButton.set("label", "New Label");

// hook a .recent rule in our stylesheet
myToggleButton.set("iconClass", "recent");

Note that you must use the <var>widget</var>.set() method; simply assigning the property will not update the widget properly.

Conclusion

Dijit's out-of-the-box form widgets meet many of the most common requirements for user input and selection. CheckBox, RadioButton, and ToggleButton are three widget classes that help you provide a richer, more visually engaging and consistent user experience. There are other widgets in Dijit that you may want to familiarize yourself with if forms are an important part of your project: dijit/Menu (and the dijit/CheckedMenuItem), dijit/form/Select and related widgets FilteringSelect, ComboBox and MultiSelect. The dojox/form package has even more options—and when that's not enough, you'll find dijit/form/_FormWidget an extremely useful base to build on. That, however, is a topic for another tutorial.