CHAPTER 18

image

Using the Button, Progress Bar, and Slider Widgets

Now that you have configured, downloaded, and installed jQuery UI, you can start to look at the widgets it contains. These are the major functional blocks of jQuery UI, and although there are other features (such as effects, which I describe in Chapter 35), jQuery UI is known for the widgets.

In this chapter, I describe the three simplest widgets: the button, the progress bar, and the slider. All jQuery UI widgets have common characteristics: settings, methods, and events. Mastering one widget provides a solid foundation for working with all of them, so I spend some time at the start of this chapter providing overall context.

It is hard to tie all of the widgets into the flower shop example, so you will find that many of the examples in this part of the book are small, self-contained HTML documents that demonstrate a single widget. I return to the flower shop example in Chapter 26 when I refactor it to include jQuery UI. Table 18-1 provides the summary for this chapter.

Table 18-1. Chapter Summary

Problem Solution Listing
Create a jQuery UI button Select an element and use the button method 1
Configure a button element Pass a map object to the button method or use the option method 2, 3
Use icons in jQuery UI buttons Use the icons setting 4
Use a custom image in a jQuery UI button Set the content of the button to be an img element 5
Remove the jQuery UI button widget Use the destroy method 6
Enable or disable the jQuery UI button Use the enable or disable method 7
Refresh the state of a jQuery UI button to reflect a programmatic change to the underlying element Use the refresh method 8
Respond to a jQuery UI button being created Specify a function for the create event 9
Create uniform buttons from different kinds of element Create jQuery UI buttons from input, button, or a element 10
Create a toggle button Create a jQuery UI from a check box 11
Create a button set Use the buttonset method 12, 13
Create a jQuery UI progress bar Use the progressbar method 14, 15
Get or set the progress shown to the user Use the value method 16
Respond to changes in the progress bar Specify functions for the create, change, or complete event 17
Create a jQuery UI slider Use the slider method 18
Change the orientation of a jQuery UI slider Use the orientation setting 19, 20
Animate the movement of the handle when the user clicks the slider Use the animate setting 21
Create a jQuery UI slider that allows the user to specify a range of values Use the range and values settings 22
Control a jQuery UI slider programmatically Use the value or values methods 23
Respond to changes in the slider handle positions Handle the start, stop, change, or slide event 24

JQUERY UI CHANGES SINCE THE LAST EDITION

As of jQuery UI 1.10, the progress widget can be used to display indeterminate tasks. See the section “Using the jQuery UI Progress Bar” for details and an example.

Using the jQuery UI Button

The first widget I look at provides a good introduction into the world of jQuery UI. The button widget is simple but has a transformational effect on HTML documents. The button widget applies the jQuery UI theme to button and a elements. This means that the size, shape, font, and color of the element are transformed to match the theme I selected when I created my custom jQuery UI download in Chapter 17. Applying jQuery UI widgets is simple, as Listing 18-1 shows.

Listing 18-1.  A Simple HTML Document

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="handlebars.js"></script>
    <script src="handlebars-jquery.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <link rel="stylesheet" type="text/css" href="styles.css"/>
  
    <script id="flowerTmpl" type="text/x-handlebars-template">
        {{#flowers}}
        <div class="dcell">
            <img src="{{product}}.png"/>
            <label for="{{product}}">{{name}}:</label>
            <input name="{{product}}" data-price="{{price}}" data-stock="{{stocklevel}}"
                value="0" required />
        </div>
        {{/flowers}}
    </script>
  
    <script type="text/javascript">
        $(document).ready(function () {
            $.ajax("mydata.json", {
                success: function (data) {
                    var tmplData = $("#flowerTmpl")
                        .template({ flowers: data }).filter("*");
                    tmplData.slice(0, 3).appendTo("#row1");
                    tmplData.slice(3).appendTo("#row2");
                }
            });
  
            $("button").button();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
        <div id="oblock">
            <div class="dtable">
                <div id="row1" class="drow">
                </div>
                <div id="row2"class="drow">
                </div>
            </div>
        </div>
        <div id="buttonDiv"><button type="submit">Place Order</button></div>
    </form>
</body>
</html>

To apply the button widget, I use jQuery to select the elements I want to transform and call the button method; jQuery UI takes care of the rest. You can see the effect in Figure 18-1.

9781430263883_Fig18-01.jpg

Figure 18-1. Applying the Button widget

image Tip  Notice that I apply the button method to a jQuery selection object. The integration between jQuery and jQuery UI is close, and it means that using jQuery UI is generally a natural extension of using the core jQuery techniques that I showed you earlier in this book.

Like all of the jQuery UI widgets, the button shown in the figure is a series of CSS styles applied to the existing HTML elements. The button method transforms an element like this

<button type="submit">Place Order</button>

to this

<button type="submit" class="ui-button ui-widget ui-state-default ui-corner-all
    ui-button-text-only" role="button" aria-disabled="false">
        <span class="ui-button-text">Place Order</span>
</button>

This is a nice approach because it works around the standard HTML elements, meaning that you don’t have to make any special provision for jQuery UI when you create HTML content.

Configuring the Button

The jQuery UI button widget can be configured via settings properties, allowing control over the way that you create the button. Table 18-2 describes these properties.

Table 18-2. The Settings Properties for the Button Widget

Property Description
disabled Gets or sets the disabled state of the button. A true value indicates that the button is disabled. jQuery UI doesn’t take into account the state of the underlying HTML element.
text Gets or sets whether the button will display text. This setting is ignored if the icons property is false.
icons Gets or sets whether the button will display an icon.
label Gets or sets the text that is displayed by the button.

These settings can be applied in two ways. The first is using a map object when calling the button method, as highlighted in Listing 18-2.

Listing 18-2.  Configuring the Button Widget Using a Map Object

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });
  
        $("button").button({
            label: "Place Your Order",
            disabled: true
        });
  
        $("button").button("option", "disabled", false);
    });
</script>
...

I have set the text that the button displays with the label property and used the disabled property to disable the button. Using a map object is the approach for defining the initial configuration for a widget and follows the style you saw most recently in Chapter 15 for configuring Ajax requests.

Listing 18-2 also shows the technique used to change the value for a settings property after the widget has been created, as follows:

...
$("button").button("option", "disabled", false);
...

I call the button method again, but with three arguments this time. The first argument is the string option and tells jQuery UI that I want to change a setting. The second argument is the setting I want to change and the third argument is the new value for the setting. This statement sets the disabled setting to false, enabling the button and changing the value I set with the map object when I created the widget.

You can combine these techniques so that you call the button method with a first argument of option and a map object as the second argument. This allows you to change multiple settings in one go, as shown in Listing 18-3.

Listing 18-3.  Using the Option Argument with a Map Object

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });
  
        $("button").button();
  
        $("button").button("option", {
            label: "Place Your Order",
            disabled: false
        });
  
        console.log("Disabled: " + $("button").button("option", "disabled"));
    });
</script>
...

You can use the same technique to read the value of a setting as well. In this case, you call the button method with just two arguments. The first is the string option and the second is the name of the setting whose value you want to read, as the following statement from the listing demonstrates:

...
console.log("Disabled: " + $("button").button("option", "disabled"));
...

When used this way, the button method returns the current setting value. The example statement reads the value of the disabled setting and writes it to the console, producing the following output:

Disabled: false

Using jQuery UI Icons in Buttons

The jQuery UI themes include a set of icons that you can use for any purpose, including displaying them in buttons. Listing 18-4 shows the use of icons in a jQuery UI button.

Listing 18-4.  Displaying an Icon in a Button

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });
  
        $("button").button({
            icons: {
                primary: "ui-icon-star",
                secondary: "ui-icon-circle-arrow-e"
            }
        });
    });
</script>
...

The icons property specifies which icons will be displayed. The button widget has two positions for icons. The primary icon is displayed to the left of the text and the secondary icon is displayed to the right of the text and both are specified with a map object. You can omit either property to display an icon in just one of the positions. The icons themselves are quite small, as you can see in Figure 18-2.

9781430263883_Fig18-02.jpg

Figure 18-2. Displaying icons in a button

Icons are specified using classes that are defined in the jQuery UI CSS file. There are 173 different icons available, which is too many to list here. The easiest way to figure out the name of the icon you want is to go to http://jqueryui.com, select the Themes page and scroll down the page. You will see all of the icons listed in a grid, and moving the mouse button over each icon reveals the class name to use for the icon, as shown in Figure 18-3.

9781430263883_Fig18-03.jpg

Figure 18-3. The jQuery UI icon grid

image Tip  The name that pops up on the web page has a leading period that must be omitted to be used with the icons setting. So, for example, if the mouse hovers over the first icon in the grid, .ui-icon-caret-1-n will pop up. To use this icon with a button, set the primary or secondary property to ui-icon-caret-1-n.

Using a Custom Image

I don’t find the jQuery UI icons all that useful because they are usually too small for my needs. Fortunately, there is a pair of alternate techniques to display a custom image in a jQuery UI button.

The first is to insert an img element inside the button element to which you intend to apply the jQuery UI button widget. The jQuery UI button widget respects the content of the underlying button element and—as long as you use an image with a transparent background—you don’t have to worry about making the image match the theme. Listing 18-5 gives a simple demonstration.

Listing 18-5.  Using a Custom Image with a jQuery UI Button

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });
  
        $("button")
            .text("")
            .append("<img src=rightarrows.png width=100 height=30 />")
            .button();
    });
</script>
...

Since I want neither text nor a jQuery UI icon, I use the jQuery text method to set the content to an empty string. I then use the append method to insert an img element into the button element and finally call the button method to apply jQuery UI. You can see the result in Figure 18-4.

9781430263883_Fig18-04.jpg

Figure 18-4. Showing a custom image in a button

Using the Button Methods

The jQuery UI widgets also define methods that you use to control the widget once it has been created. These methods are a little odd because you call the same JavaScript method but pass in different argument values to change the jQuery UI behavior. These are, however, still called methods by the jQuery UI team and I will refer to them as such. Table 18-3 shows the different jQuery UI methods you can use on the button widget and the effect each has.

Table 18-3. Button Methods

Method Description
button("destroy") Returns the HTML element to its original state
button("disable") Disables the button
button("enable") Enables the button
button("option") Sets one or more options; see the section “Configuring the Button”
button("refresh") Refreshes the button; see the section “Refreshing the State of a jQuery UI Button”

Removing the Widget

The destroy method removes the jQuery UI button widget from the HTML button element, returning it to its original state, as shown in Listing 18-6.

Listing 18-6.  Using the destroy Method

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });
  
        $("button").button().click(function (e) {
            $("button").button("destroy");
            e.preventDefault();
        });
    });
</script>
...

In Listing 18-6, I have used the standard jQuery click method to register a handler function for the button element. This is the technique I demonstrated for handling events in Chapter 9 and requires no adjustment to support jQuery UI. The click handler function in the listing means that clicking the button removes the jQuery UI widget from the button element, as illustrated by Figure 18-5.

9781430263883_Fig18-05.jpg

Figure 18-5. Destroying the jQuery UI button widget

Enabling and Disabling the Button

The enable and disable methods change the state of the jQuery UI button, as shown in Listing 18-7.

Listing 18-7.  Enabling and Disabling a Button

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });
  
        $("<span>Enabled:<span><input type=checkbox checked />").prependTo("#buttonDiv");
        $(":checkbox").change(function (e) {
            $("button").button(
                $(":checked").length == 1 ? "enable" : "disable"
            )
        });
  
        $("button").button();
    });
</script>
...

I have inserted a check box into the document and used the change method to register a function that will be called when the box is checked or unchecked. I call the enable and disable methods to change the state of the button to match the check box. You can see the effect in Figure 18-6.

9781430263883_Fig18-06.jpg

Figure 18-6. Enabling and disabling a jQuery UI button

Refreshing the State of a jQuery UI Button

The refresh method updates the state of the jQuery UI button widget to reflect changes in the underlying HTML element. This can be useful when you modify elements elsewhere in the code as shown in Listing 18-8.

Listing 18-8.  Refreshing the jQuery UI Button

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });
  
        $("<span>Enabled:<span><input type=checkbox checked />").prependTo("#buttonDiv");
        $(":checkbox").change(function (e) {
            var buttons = $("button");
            if ($(":checked").length == 1) {
                buttons.removeAttr("disabled");
            } else {
                buttons.attr("disabled", "disabled");
            }
            buttons.button("refresh");
        });
  
        $("button").button();
    });
</script>
...

In this example, I use the check box to trigger adding and removing the disabled attribute from the HTML button element that underpins the button widget. This change isn’t automatically detected by jQuery UI, so I call the refresh method to bring everything back in sync.

image Tip  You might be wondering why I would not just use the jQuery UI enable and disable methods, but the scenario in Listing 18-8 is surprisingly common because jQuery UI is often applied to HTML content late in the development process, frequently to give a face-lift to an existing web application. In this situation, HTML elements will be generated and manipulated by code which predates the user of jQuery UI and doesn't know that a button widget will be used—and so being able to update the state of the widget to reflect the state of the underlying HTML element can be an important feature.

Using the Button Event

The jQuery UI widgets define events in addition to those of the underlying HTML elements. The button widget defines a single event called create, which is triggered when you create a jQuery UI button widget. Handlers for jQuery UI events are defined by passing a JavaScript map object to the jQuery UI method for the widget, which is button in this case, as illustrated by Listing 18-9.

Listing 18-9.  Using the jQuery UI Button create Event

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });
  
        $("button").button({
            create: function (e) {
                $(e.target).click(function (e) {
                    alert("Button was pressed");
                    e.preventDefault();
                })
            }
        });
    });
</script>
...

In Listing 18-9, I use the create event to set up a function to respond to the click event on the button. I don’t find the create event useful and generally find that anything that can be done in response to this event can be done in a way that is more in keeping with the broader jQuery approach.

Creating Different Types of Button

The jQuery UI button widget is sensitive to the kind of element it is applied to. The basic behavior, a regular button, is created when you call the button method on button elements, or on a elements, or on input elements whose types are set to submit, reset, or button. Listing 18-10 shows all of these elements being transformed into jQuery UI buttons.

Listing 18-10.  Creating Standard Buttons

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-1.7.js" type="text/javascript"></script>
    <script src="jquery-ui-1.8.16.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.8.16.custom.css"/>
    <script type="text/javascript">
        $(document).ready(function() {
            $(".jqButton").click(function(e) {
               e.preventDefault();
               $(this).button();
            });
        });
    </script>
</head>
<body>
    <form>
        <input class="jqButton" type="submit" id="inputSubmit" value="Submit">
        <input class="jqButton" type="reset" id="inputReset" value="Reset">
        <input class="jqButton" type="button" id="inputButton" value="Input Button">
        <button class="jqButton">Button Element</button>
        <a class="jqButton" href="http://apress.com">A Element</a>
    </form>
</body>
</html>

I have defined one of each type of the HTML elements I have described. I have used the click method so that each element is transformed into a jQuery UI button widget when it is clicked. You can see the transformation in Figure 18-7.

9781430263883_Fig18-07.jpg

Figure 18-7. Creating standard jQuery UI buttons

Creating a Toggle Button

If you call the button method on an input element whose type is set to checkbox, you get a toggle button widget. A toggle button is switched on or off when you click it, following the checked and unchecked states of the underlying HTML element. Listing 18-11 provides a demonstration.

Listing 18-11.  Applying jQuery UI to a Check Box

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <script type="text/javascript">
        $(document).ready(function () {
            $(".jqButton").button();
        });
    </script>
</head>
<body>
    <form>
        <input class="jqButton" type="checkbox" id="toggle">
        <label for="toggle">Toggle Me</label>
    </form>
</body>
</html>

To create a jQuery UI button from a check box, you must have an input element and a matching label element, as shown in the listing. jQuery UI creates a button that has the same appearance as a basic button but that toggles its state when clicked. You can see the effect in Figure 18-8.

9781430263883_Fig18-08.jpg

Figure 18-8. Creating a toggle button from a check box

Remember that jQuery UI doesn’t change the underlying HTML element, so the check box is still treated the same way by the browser when included in forms. The change of state is reflected using the checked attribute, just as it would be without jQuery UI.

Creating a Button Set

You can use the buttonset method to create jQuery UI buttons from radio button elements, as shown in Listing 18-12.

Listing 18-12.  Creating a Button Set

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <script type="text/javascript">
        $(document).ready(function () {
            $("#radioDiv").buttonset();
        });
    </script>
</head>
<body>
    <form>
        <div id="radioDiv">
            <input type="radio" name="flower" id="rose" checked />
            <label for="rose">Rose</label>
            <input type="radio" name="flower" id="lily"/><label for="lily">Lily</label>
            <input type="radio" name="flower" id="iris"/><label for="iris">Iris</label>
        </div>
    </form>
</body>
</html>

Notice that I have selected the div element that contains the radio buttons in order to call the buttonset method: you don’t call the button method on the individual input elements. You can see the effect of the buttonset method in Figure 18-9.

9781430263883_Fig18-09.jpg

Figure 18-9. Creating a button set

At most, one of the buttons in the set can be selected, allowing you to provide the user with a fixed set of choices in a way that is visually consistent with other jQuery UI buttons. Notice that jQuery UI emphasizes the relationship between the buttons in a set by applying different styling to the edges where buttons meet. This is shown more clearly in Figure 18-10.

9781430263883_Fig18-10.jpg

Figure 18-10. The jQuery UI styling for button sets

Creating Button Sets from Regular Buttons

You can use the buttonset method on any element that can be used with the regular button method. This has the effect of applying the style of a set of radio buttons but not the behavior, so that each button works individually. Listing 18-13 shows this use of the buttonset method.

Listing 18-13.  Creating a Button Set from Regular Buttons

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <script type="text/javascript">
        $(document).ready(function () {
            $("#radioDiv").buttonset();
        });
    </script>
</head>
<body>
    <form>
        <div id="radioDiv">
            <input type="submit" value="Submit"/>
            <input type="reset" value="Reset"/>
            <input type="button" value="Press Me"/>
            <a href="http://apress.com">Visit Apress</a>
        </div>
    </form>
</body>
</html>

Any suitable element in the div container will be transformed into a button, and the adjoining edges will be styled just as with the radio button, as you can see in Figure 18-11.

9781430263883_Fig18-11.jpg

Figure 18-11. Creating a button set from regular buttons

image Tip  Be careful when using this technique. It can be confusing to the user, especially if you are using radio buttons elsewhere in the same document or web application.

Using the jQuery UI Progress Bar

Now that I have used the button to explore the basic structure of a jQuery UI widget, I will look at the other widgets that jQuery UI supports, starting with the progress bar.

The progress bar allows you to show the user progress in completing a task. The progress bar is designed to show determinate tasks, where you can give the user an accurate indication of how far you are through the task as a percentage, and indeterminate tasks, where the percentage of progress is currently unknown.

image Tip  The support for displaying indeterminate tasks was added to jQuery UI in version 1.10. See the section “Creating an Indeterminate Progress Bar” for details of this feature.

SHOWING USEFUL PROGRESS INFORMATION

There are no rules for the way widgets should be used in web applications, but the user expectations of controls such as progress bars are informed by the standards set by operating systems such as Windows and Mac OS. To help the user make sense of your progress bar, there are a couple of rules to follow.

First, only increment the progress. Don’t be tempted to reduce the progress when the task has more steps than initially expected. The progress bar shows the percentage of a task that been completed and is not an estimate of the remaining time. If there are different possible paths for a task to follow, then show the most pessimistic progress. It is better to take a giant leap in progress than to confuse the user.

Second, don’t loop around the progress bar more than once. If you have enough information to show the user reasonably accurate completion information, then you should be using an indeterminate progress indicator. When the progress nears 100%, the user expects the task to complete. If the progress bar then resets and starts to build up again, you have simply confused the user and made the use of the progress bar meaningless.

Creating the Progress Bar

You create a progress bar by selecting a div element and calling the progressbar method, as shown in Listing 18-14.

Listing 18-14.  Creating a Progress Bar

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <script type="text/javascript">
        $(document).ready(function () {
            $("#progressDiv").progressbar({
                value: 21
            });
        });
    </script>
</head>
<body>
    <div id="progressDiv"></div>
</body>
</html>

The document contains a div element with an id of progressDiv. To create a progress bar, I must use an empty div element–if the div element has any content, it will affect the layout of the progress bar. I use jQuery to select the progressDiv element and call the jQuery UI progressbar method, passing in a map object to provide the initial configuration. The progress bar supports three settings, which I have described in Table 18-4.

Table 18-4. The Settings for the Progress Bar Widget

Setting Description
disabled If true, the progress bar will be disabled. The default value is false.
value Sets the percentage complete displayed to the user. The default is zero. Set the property to false to display an indeterminate progress bar, as described in the section “Creating an Indeterminate Progress Bar.”
max Sets the maximum value that the progress bar will display. The default is 100.

In the example, I specified an initial value of 21 (which will be equivalent to 21% since I have not changed the value of the max setting), and you can see the effect in Figure 18-12.

9781430263883_Fig18-12.jpg

Figure 18-12. Creating a progress bar

Creating an Indeterminate Progress Bar

As of jQuery UI 1.10, the jQuery UI progress bar widget supports displaying progress for indeterminate tasks, which is configured by setting the value configuration property to false rather than specifying a numeric value, as shown in Listing 18-15.

Listing 18-15.  Creating an Indeterminate Progress Bar

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <script type="text/javascript">
        $(document).ready(function () {
            $("#progressDiv").progressbar({
                value: false
            });
        });
    </script>
</head>
<body>
    <div id="progressDiv"></div>
</body>
</html>

jQuery UI displays an indeterminate progress with a simple animation applied to the entire bar. You need to run the example to see the effect of the animation, but Figure 18-13 shows one frame.

9781430263883_Fig18-13.jpg

Figure 18-13. Creating an indeterminate progress bar

Using the Progress Bar Methods

The progress bar widget defines a number of methods, which are in the same style as for the button. In other words, you call the JavaScript progressbar method, and the first argument specifies the jQuery UI widget method you want. Table 18-5 describes the available methods.

Table 18-5. Progress Bar Methods

Method Description
progressbar("destroy") Returns the div element to its original state
progressbar("disable") Disables the progress bar
progressbar("enable") Enables the progress bar
progressbar("option") Sets one or more options; see the section “Configuring the Button” for details of configuring a jQuery UI widget
progressbar("value", value) Gets and sets the value displayed by the progress bar and switches between an indeterminate and determinate progress bar

Most of these methods work in the same way as for the button widget, so I am not going to demonstrate them again. The exception is the value method, which lets you get and set the value that is displayed by the progress bar and switch between the determinate and indeterminate states. Listing 18-16 demonstrates the use of the value method.

Listing 18-16.  Using the Progress Bar Value Method

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
     <script type="text/javascript">
         $(document).ready(function () {
  
             $("#progressDiv").progressbar({
                 value: 21
             });
  
             $("button").click(function (e) {
                 var divElem = $("#progressDiv");
                 if (this.id == "mode") {
                     divElem.progressbar("value", false);
                 } else {
                     var currentProgress = divElem.progressbar("value");
                     if (!currentProgress) {
                         divElem.progressbar("value", 21);
                     } else {
                         divElem.progressbar("value",
                             this.id == "decr" ? currentProgress - 10 :
                                                     currentProgress + 10)
                     }
                 }
             });
         });
    </script>
</head>
<body>
    <div id="progressDiv"></div>
    <button id="decr">Decrease</button>
    <button id="incr">Increase</button>
    <button id="mode">Indeterminate</button>
</body>
</html>

I have added button elements to this example. I use them to increase or decrease the value displayed by the progress bar and switch between the determinate and indeterminate modes. Each press of the Decrease or Increase button changes the value by 10% as shown in Figure 18-14.

9781430263883_Fig18-14.jpg

Figure 18-14. Using the value method to change the progress displayed

The Indeterminate button calls the value method to switch the progress bar to its intermediate mode. Clicking either of the other buttons will set a numeric value, which will put the progress bar back to its determinate mode, as shown in Figure 18-15.

9781430263883_Fig18-15.jpg

Figure 18-15. Changing the Mode of the Progress Bar

Using the Progress Bar Events

The jQuery UI progress bar widget defines three events, as described in Table 18-6.

Table 18-6. Progress Bar Events

Event Description
create Triggered when the progress bar is created
change Triggered when the value of the progress bar changes
complete Triggered when the value of the progress bar is set to 100

Listing 18-17 shows the events in use.

Listing 18-17.  Using the Progress Bar Events

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
     <script type="text/javascript">
         $(document).ready(function () {
  
             $("button").button();
  
             $("#progressDiv").progressbar({
                 value: 21,
                 create: function (e) {
                     $("#progVal").text($("#progressDiv").progressbar("value"));
                 },
                 complete: function (e) {
                     $("#incr").button("disable")
                 },
                 change: function (e) {
                     var currentValue = $("#progressDiv").progressbar("value");
                     if (!currentValue) {
                         $("#progWrapper").hide();
                     } else {
                         if ($(this).progressbar("value") < 100) {
                             $("#incr").button("enable")
                         }
                         $("#progVal").text(currentValue);
                         $("#progWrapper").show();
                     }
                 }
             });
  
             $("button").click(function (e) {
                 var divElem = $("#progressDiv");
                 if (this.id == "mode") {
                     divElem.progressbar("value", false);
                 } else {
                     var currentProgress = divElem.progressbar("value");
                     if (!currentProgress) {
                         divElem.progressbar("value", 21);
                     } else {
                         divElem.progressbar("value",
                             this.id == "decr" ? currentProgress - 10 :
                                                     currentProgress + 10)
                     }
                 }
             });
         });
    </script>
</head>
<body>
    <div id="progressDiv"></div>
    <button id="decr">Decrease</button>
    <button id="incr">Increase</button>
    <button id="mode">Indeterminate</button>
    <span id="progWrapper">Progress: <span id="progVal"></span>%</span>
</body>
</html>

In Listing 18-17, I use span elements to display the numeric progress value while the progress bar is in the determinate mode. I use the create event to display the initial value, which is set using the value configuration property.

image Tip  Notice that I have used the same map object for the settings and events of the progress bar. This isn’t required, but it does allow me to create and configure a widget in a single method call.

I use the complete event to disable the Increase button when the progress reaches 100% and the change event to ensure that the button is enabled for other values, to display the current value and to switch between the determinate and indeterminate modes. You can see the effect in Figure 18-16.

9781430263883_Fig18-16.jpg

Figure 18-16. Responding to progress bar events

image Tip  There are a couple of things to remember when using the events. First, the complete event fires every time the value is set to 100 or greater. This means the event can fire multiple times if you repeatedly set the value to 100, for example. Second, both the change and complete events are triggered for values of 100 or more, so you have to be able to deal with both when you complete the progress update.

Using the jQuery UI Slider

As its name suggests, the slider widget creates a slider out of an element in the HTML document and allows the user to select a value without having to enter text into an input element. The slider widget is applied to HTML elements using the slider method, as shown in Listing 18-18.

Listing 18-18.  Creating a Slider

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #slider { margin: 10px; }
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
             $("#slider").slider();
         });
    </script>
</head>
<body>
    <div id="slider"></div>
</body>
</html>

The slider is themed consistently with the other jQuery UI widgets and allows the user to use the mouse or arrow keys to move the slider handle up and down the scale. You can see how the basic slider appears in Figure 18-17. (Notice that I defined a CSS style for the element that underpins the slider in this example—without this, the slider is displayed right up against the edges of its parent element.)

9781430263883_Fig18-17.jpg

Figure 18-17. A basic jQuery UI slider

Configuring the Slider

A with all jQuery UI widgets, the slider widget defines a number of settings that you can use to configure the appearance and behavior of sliders. Table 18-7 describes these settings, and I show you how to use these settings to configure the widget in the sections that follow.

Table 18-7. The Settings for the Slider Widget

Setting Description
animate When true, animates the slider when the user clicks a position outside the handle. The default is false.
disabled Disables the slider when set to true. The default is false.
max Defines the maximum value for the slider. The default is 100.
min Defines the minimum value for the slider. The default is 0.
orientation Defines the orientation for the slider; see Listing 18-19 for details.
range Used with the values setting to create a multihandle slider.
step Defines the interval that the slider moves between the min and max values.
value Defines the value that the slider represents.
values Used with the range setting to create a multihandle slider.

image Tip  The min and max values are exclusive, meaning that if you set a min value of 0 and a max value of 100, the user can select values between 1 and 99.

Changing the Slider Orientation

By default, sliders are horizontal, but you can use the orientation setting to create vertical sliders as well, as shown by Listing 18-19.

Listing 18-19.  Using the orientation Setting

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #hslider, #vslider { margin: 10px}
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
             $("#hslider").slider({
                 value: 35
             });
  
             $("#vslider").slider({
                 orientation: "vertical",
                 value: 35
             });
         });
    </script>
</head>
<body>
    <div id="hslider"></div>
    <div id="vslider"></div>
</body>
</html>

I created two sliders, one of which has the orientation setting of vertical. I have also changed the style element so that I can apply a margin to the slider elements to keep them apart. You control the size and position of sliders (and any jQuery UI widget) by styling the underlying element (which is why div elements work best; they can be readily manipulated with CSS). You can see the sliders in Figure 18-18. Notice that I used the value setting to set the initial position of the handle.

9781430263883_Fig18-18.jpg

Figure 18-18. Creating vertical and horizontal sliders

Although I am keeping the options and methods separate, I could have written Listing 18-19 differently to make better use of the underlying jQuery functionality, as shown in Listing 18-20.

Listing 18-20.  Making Better Use of jQuery

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #hslider, #vslider { margin: 10px}
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
             $("#hslider, #vslider").slider({
                 value: 35,
                 orientation: "vertical"
             }).filter("#hslider").slider("option", "orientation", "horizontal");
         });
    </script>
</head>
<body>
    <div id="hslider"></div>
    <div id="vslider"></div>
</body>
</html>

It is a minor point but I don’t want you to forget that jQuery UI is built on and tightly integrated with jQuery and that you can use all of the selections and manipulations you saw earlier in the book.

image Tip  Notice that I set the initial orientation to vertical and then changed it to horizontal. There is a bug with the slider where changing the orientation to vertical after the slider has been created causes the handle to be misaligned.

Animating the Slider

The animate setting enables smooth handle movement when the user clicks the slider at the point he wants the handle to move to (as opposed to setting a value by dragging the slider). You can enable the default animation by setting animate to true, set a speed for the animation by using fast or slow, or specify the number of milliseconds that the animation should last for. Listing 18-21 shows the use of the animate setting.

Listing 18-21.  Using the animate Setting

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-1.7.js" type="text/javascript"></script>
    <script src="jquery-ui-1.8.16.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.8.16.custom.css"/>
    <style type="text/css">
        #slider {margin: 10px}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#slider").slider({
                animate: "fast"
            });
        });
    </script>
</head>
<body>
    <div id="slider"></div>
</body>
</html>

I have set the animate setting to fast. It is hard to show animations in a screenshot, but Figure 18-19 shows what the animate setting does.

9781430263883_Fig18-19.jpg

Figure 18-19. Animating the movement of the handle

This screenshot shows the slider just before I clicked the mouse button. If I had not enabled animations, then the handle would snap to the location I clicked, immediately setting the new value for the slider. But since I have enabled animations, the slider will gracefully move to its new position in a less jarring way. However, like any effect or animation, I don’t want to overdo the effect, which is why I have selected the fast option.

image Tip  This is an example that you need to play with to see the full result. If you don’t want to type in the code and HTML, you can find the code samples for this chapter in the Source Code/Download area of the Apress web site at www.apress.com. It is freely available from apress.com and contains all of the examples in this book.

Creating a Range Slider

A range slider has two handles and lets the user specify a range of values rather than a single value. For example, you might want to let the user express the price range she is willing to pay for products so that you can filter anything else out. Listing 18-22 demonstrates creating a range slider.

Listing 18-22.  Creating a Range Slider

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #slider {margin: 20px}
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
             $("#slider").slider({
                 values: [35, 65],
                 range: true,
                 create: displaySliderValues,
                 slide: displaySliderValues
             });
  
             function displaySliderValues() {
                 $("#lower").text($("#slider").slider("values", 0));
                 $("#upper").text($("#slider").slider("values", 1));
             }
         });
    </script>
</head>
<body>
    <div id="slider"></div>
    <div>Lower Value: <span id="lower">
    </span> Upper Value: <span id="upper"></span></div>
</body>
</html>

To create a range slider, you must set the range setting to true and set the value setting to an array that contains the initial lower and upper bounds of the range. (When using a regular slider, you use the value setting, and when using a range slider, you use the values setting.) In this example, I have set the bounds to 35 and 65. You can see the effect in Figure 18-20.

9781430263883_Fig18-20.jpg

Figure 18-20. Creating a range slider

I have added a handler function for the create and slide events. I’ll get to the events supported by the slider in the section “Using Slider Events,” but I want to demonstrate how to obtain the position of the handles in a range slider. You do this through the values method, specifying the index of the slider you are interested in, as follows:

...
$("#slider").slider("values", 0);
...

The index is zero based, so this statement gets the value for the handle that represents the lower bound of the range. I have used the events to set the contents of two span elements.

Using the Slider Methods

The slider defines the same set of basic methods that all jQuery UI widgets define, plus a couple that let you set either a single value or the range of values to be shown. Table 18-8 describes the methods.

Table 18-8. Slider Methods

Method Description
slider("destroy") Returns the underlying element to its original state
slider("disable") Disables the slider
slider("enable") Enables the slider
slider("option") Sets one or more options; see the section “Configuring the Button” for details of configuring a jQuery UI widget
slider("value", value) Gets or sets the value for a regular slider
slider("values", [values]) Gets or sets the values for a range slider

Listing 18-23 shows how you can use the value and values methods to control a slider programmatically.

Listing 18-23.  Controlling Sliders Programmatically

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #slider, #rangeslider, *.inputDiv { margin: 10px}
        label {width: 80px; display: inline-block; margin: 4px}
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
  
             $("#slider").slider({
                 value: 50,
                 create: function () {
                     $("#slideVal").val($("#slider").slider("value"));
                 }
             });
  
             $("#rangeslider").slider({
                 values: [35, 65],
                 range: true,
                 create: function () {
                     $("#rangeMin").val($("#rangeslider").slider("values", 0));
                     $("#rangeMax").val($("#rangeslider").slider("values", 1));
                 }
             })
  
             $("input").change(function (e) {
                 switch (this.id) {
                     case "rangeMin":
                     case "rangeMax":
                         var index = (this.id == "rangeMax") ? 1 : 0;
                         $("#rangeslider").slider("values", index, $(this).val())
                         break;
                     case "slideVal":
                         $("#slider").slider("value", $(this).val())
                         break;
                 }
             })
         });
    </script>
</head>
<body>
    <div id="rangeslider"></div>
    <div class="inputDiv">
        <label for="rangeMin">Range Min: </label><input id="rangeMin" />
        <label for="rangeMax">Range Max: </label><input id="rangeMax" />
    </div>
    <div id="slider"></div>
    <div class="inputDiv">
        <label for="slideVal">Slide Val: </label><input id="slideVal" />
    </div>
</body>
</html>

This document contains two sliders and three input elements that allow the values for the handles to be specified without moving the handles themselves. You can see the layout of the elements in Figure 18-21.

9781430263883_Fig18-21.jpg

Figure 18-21. Controlling sliders programmatically

I used jQuery to select the input elements and called the change method to set up a handler for the change event, meaning that the function is invoked whenever the value of one of the input elements is changed.

Within the handler function, I use the id attribute of the element that triggered the event to figure out which slider I need to manipulate and call the value or values methods to set the handle positions. The relationship between the input elements and the sliders is one-way, meaning that moving the handles doesn’t update the input elements. I’ll show you how to create a two-way relationship in the next section.

Using Slider Events

Table 18-9 shows the events that the slider supports. The best feature of these events is the support for both change and stop, which allows you to differentiate between new values created by the user moving the handle and values that you set programmatically.

Table 18-9. Slider Events

Event Description
create Triggered when the slider is created
start Triggered when the user starts sliding the handle
slide Triggered for every mouse move while the handle is sliding
change Triggered when the user stops sliding the handle or when the value is changed programmatically
stop Triggered when the user stops sliding the handle

Listing 18-24 shows the use of slider events to create a two-way (bidirectional) relationship between sliders and input elements, similar to the example in the previous section, albeit I have removed one of the sliders to keep the example simple. The two-way relationship allows me to tie together programmatic support and user interaction to manage the sliders.

Listing 18-24.  Using Slider Events to Create a Bidirectional Relationship Between Sliders and Inputs

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #rangeslider, *.inputDiv { margin: 10px}
        label {width: 80px; display: inline-block; margin: 4px}
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
             $("#rangeslider").slider({
                 values: [35, 65],
                 range: true,
                 create: setInputsFromSlider,
                 slide: setInputsFromSlider,
                 stop: setInputsFromSlider
             });
  
             function setInputsFromSlider() {
                 $("#rangeMin").val($("#rangeslider").slider("values", 0));
                 $("#rangeMax").val($("#rangeslider").slider("values", 1));
             }
  
             $("input").change(function (e) {
                 var index = (this.id == "rangeMax") ? 1 : 0;
                 $("#rangeslider").slider("values", index, $(this).val())
             });
         });
    </script>
</head>
<body>
    <div id="rangeslider"></div>
    <div class="inputDiv">
        <label for="rangeMin">Range Min: </label><input id="rangeMin" />
        <label for="rangeMax">Range Max: </label><input id="rangeMax" />
    </div>
</body>
</html>

I handle the create, slide, and stop events in this example. Now the slider handles are moved when new values are entered into the input elements, and the values in the input elements are updated when the slider is moved. You can see how the document appears in Figure 18-22, but this is an example that requires interaction to see the full effect.

9781430263883_Fig18-22.jpg

Figure 18-22. Responding to slider events

Summary

In this chapter, I introduced you to the first three jQuery UI widgets: the button, the progress bar, and the slider. Each widget follows the same basic structure: there is a single method that creates and configures the widget as well as letting you supply functions that will respond to its events. Some methods and events are common to each widget, but there are unique additions as well that expose the special functionality that some widgets offer. Now that I have the basics out of the way, I’ll show you some more flexible and complex widgets in the chapters that follow. In Chapter 19, I show you the autocomplete and accordion widgets.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.3.175