Chapter 20

Animating the Web

In This Chapter

arrow Understanding the jQuery user interface features

arrow Using a canvas to draw on a document

Everyone likes special effects. You see special effects everywhere today. Of course, they appear in movies, but even common billboards often have special effects. From the glittery lights that festoon children’s shoes to the blinking of Christmas lights, life has become a festival of special effects. It isn’t too surprising that special effects also appear on Websites, and those sites that lack special effects are often called boring or sometimes aren’t noticed at all. Some developers equate special effects to eye candy — to the glitz that attracts the attention of the consumer, sometimes at the expense of useful content.

Special effects do have useful purposes. One of the most important reasons to use special effects is to focus user attention. A mouseover effect can help people interact with a page with greater ease, especially when lighting conditions or other environmental factors make it hard to see the cursor. Helping the user to focus means that you get better input from the user and the user has a better experience from the application.

In many cases, special effects appear as widgets that you can use to better convey the sort of input that a user should provide. For example, a text box works perfectly well for inputting a range of values, but it doesn’t tell the viewer anything (such as the fact that the input is within a certain range). If you replace that text box with a slider control, suddenly the user understands that any value within a specified range is acceptable. In addition, it’s easier for the user to set the specified range.

You can also use special effects to turn abstractions into concrete concepts for the user. The use of a slide effect (where an element slides into and out of view) can help the user to understand that the user interface contains hidden features that are accessible when the user needs them, but which will stay out of the way when the user doesn’t. Using other special effects can help a user understand the urgency of a particular input or see the data controlled by the input in a real-world perspective. In short, special effects need not be limited to pure glitz. The purpose of this chapter is to introduce you to some of the special effects that you can add to applications by using products such as the jQuery UI.

Getting to Know jQuery UI

Previous chapters, especially Chapters 18 and 19, demonstrate the usefulness of jQuery in working with data and performing other low-level tasks in your application. The jQuery UI library (http://jqueryui.com) works with the user interface. You use it to add new kinds of interactions, expand the number of controls at your disposal, create special effects, and perform utilitarian tasks, such as positioning user interface elements precisely.

All these examples require that you provide a link to the jQuery UI as well as jQuery. They also use the jQuery Cascading Style Sheet (CSS) that helps create a pleasant presentation. These external elements make the coding task easier. Make sure you include the following entries in the heading of the file for each of the examples:

<script

   src="http://code.jquery.com/jquery-latest.js">

</script>

<script

   src="http://code.jquery.com/ui/1.9.2/jquery-ui.js">

</script>

<link

   rel="stylesheet"

   href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />

You can always download the required files if desired. However, this approach makes it easier for your application to receive required updates. The following sections introduce you to jQuery UI and help you understand how you can use these features to create more interesting applications.

Considering interactions

The way in which a user interacts with an application is important. When a set of interactions seems contrived or proves inconvenient, users have to concentrate too hard on what the application should be able to do and how to obtain that result, which makes them lose focus on their work goal. Many business users are currently in the process of moving from desktop applications to browser-based applications for at least part of their work. Consequently, these users often anticipate having desktop-like features in their browser-based application solutions. The following sections describe some jQuery UI features that help you provide that desktop experience to your users.

Dragging content from one location to another

Sometimes a user needs to reposition screen elements to make them easier to see or work with. Creating an environment in which the user can move items around need not involve writing reams of code. In fact, all you really need is a single method call, draggable(). The following code shows the method used to create a draggable paragraph in this example. (You can find complete code for this example in the Chapter 20jQueryUI folder of the downloadable code as DragContent.HTML.)

$(function()

  {

      $("#MoveMe").draggable();

  });

This code is interesting because it actually creates a jQuery anonymous function that extends the jQuery environment rather than working with any particular page feature. The focus of this call is a paragraph with an id of MoveMe. All you need to do is access that member and call draggable() to make it move around. Try the downloadable example and you find that you can move the paragraph anywhere you want on the page.

To create a movable box, this example relies on a custom style. The style creates a border, allows plenty of room for the text, and then centers the text both horizontally and vertically. Here’s the style used for this example:

#MoveMe

{

   border: solid;

   width: 200px;

   height: 5em;

   text-align: center;

   line-height: 5em;

}

tip.eps Many developers experience problems vertically centering text within a <p> tag. You can find a number of ways to perform this task. However, one of the easiest ways to get the job done in a platform- and browser-consistent manner is to use the line-height style as shown in the example. The trick though is to set the height and line-height styles to the same value — the text will always appear in the middle.

Dropping items into containers

Sometimes a user needs to drag an item to a container and drop it in the container. There are many instances of this process in current applications. For example, the concept of dragging an item to a trash can and dropping it to delete it is consistent across all platforms. If you want to send an item to the printer, you drag its icon to the printer icon and drop it there.

Of course, to create this effect, you must have one item that's draggable and another item that's droppable. The preceding section describes how dragging works. The following code shows how dragging and dropping can work together to create this desirable user interaction. (You can find complete code for this example in the Chapter 20jQueryUI folder of the downloadable code as DropContent.HTML.)

$(function()

  {

      $("#MoveMe").draggable();

      $("#FillMe").droppable(

         {

            drop: function(event, ui)

            {

               $(this)

                  .addClass("Filled")

                  .html("Filled!");

            }

         });

  });

This example uses the same code for the MoveMe <p> tag. A second <p> tag, with the id of FillMe, acts as a container. When a user drags MoveMe to FillMe, the code calls the anonymous function associated with the drop event. Notice how the example begins with the event name, followed by a colon (:), followed by the anonymous function to handle that event. The droppable() method supports these events:

check.png create: Indicates that the droppable item has been created.

check.png activate: Indicates that a draggable item is active. You can use this event to change the droppable item style so that the user can see where to drop an item.

check.png deactivate: Indicates that the user has stopped dragging an item. You can use this event to change the droppable style back to its original state.

check.png over: Fires when the draggable item is over the top of the droppable item. You can use this event to indicate when the user should release the mouse to drop the item into the container.

check.png out: Fires when the draggable item has moved out of the droppable item container. You can use this event to tell the user that it's no longer possible to drop an item into the container.

check.png drop: Tells the droppable item (the container) that it has received a draggable item.

You can create an event handler for any of the events you want to handle in your code. In fact, there are several opportunities for special effects that would focus the user’s attention.

Resizing display elements

The wide variety and types of screens used to display information make it necessary to allow the user to resize elements as needed. In most cases, you can simply allow the user to make the element any size. However, there may be situations where you need to monitor the amount of resizing so that you can tailor content to meet the needs of the container. The following example shows how to resize an object and monitor its size. (You can find complete code for this example in the Chapter 20jQueryUI folder of the downloadable code as ResizeContent.HTML.)

$(function()

  {

      $("#ResizeMe").resizable(

         {

            minWidth: 200,

            minHeight: 60,

            resize: function(event, ui)

            {

               $("#Content")

                  .html("Width: " +ui.size.width +

                     "<br/>Height: " + ui.size.height);

            }

         });

  });

This example is interesting because it shows how to set properties as well as respond to events. In this case, the minWidth and minHeight properties keep the element a specific minimum size — the user can't make the element smaller.

The code also responds to the resize event. There's a special requirement for resizing you need to know about. The resizing container is separate from the content element. Here's the HTML for this example:

<div id="ResizeMe">

   <p id="Content">

      Resizable Paragraph

   </p>

</div>

When you want to write content to the screen, you must use the content element, not the container element. Otherwise, the sizing handles will disappear, and the user won't be able to resize the element after the first time. In this case, the current size of the container appears as part of the ui object passed to the resize event handler. You access the information though the size.width and size.height properties, as shown in the code. Figure 20-1 shows a typical example of how the output appears.

9781118494189-fg2001.tif

Figure 20-1: The container must be separate from the content when resizing.

Selecting items onscreen

Making it possible to select from a list of items reduces the chance that the user will enter incorrect information. It will also increase application reliability and reduce the potential for security issues, such as injection attacks (see the article at http://www.zdnet.com/sql-injection-attack-what-is-it-and-how-to-prevent-it-7000000881/ for details). The user becomes more efficient as well. Fortunately, HTML5 already comes with a number of selection controls, but you may find that these controls don't quite fulfill your needs at times. In this case, a custom selection technique implemented with jQuery might answer the need. A selection sequence can consist of a <div> and a series of <p> tags, as shown here. (You can find complete code for this example in the Chapter 20jQueryUI folder of the downloadable code as SelectContent.HTML.)

<div id="Selections">

   <p id="Red">Red</p>

   <p id="Green">Green</p>

   <p id="Blue">Blue</p>

   <p id="Purple">Purple</p>

</div>

Notice that the <div> acts as a container and the <p> tags act as items within the container. No matter how you implement your custom list (and it need not be the arrangement shown), it must have a container/item arrangement like the one shown here. When you have the arrangement in place, you can create a selection and tracking mechanism like the one shown in the following code:

// Create an array to track the selections.

var Selections = new Array();

nbps;

// Handle the selects and unselects.

$(function()

  {

      $("#Selections").selectable(

         {

            selected: function(event, ui)

            {

               // Verify the item hasn't already

               // been added.

               if (Selections.indexOf(ui.selected.id ) ==

                   -1)

               

                  // Add the id of the selected item

                  // to the array.

                  Selections.push(ui.selected.id);

            },

            

            unselected: function(event, ui)

            {

               // Find the location of the unselected

               // item in the array.

               var Index =

                  Selections.indexOf(ui.unselected.id);

                  

               // Remove that item.

               Selections.splice(Index, 1);

            }

         });

  })

nbps;

// Display the results.

function ShowResults()

{

   alert("You have selected: " + Selections);

}

The Array, Selections, keeps track of the current selection list. To make the <div>, Selections, selectable, you use the selectable() method. This example uses two events, selected and unselected, to keep track of the current selections. When the user selects a new item, the selected event handler verifies that the item doesn't already appear in Selections, and then it pushes the new item onto Selections.

The unselected event handler must perform two tasks. First, it must locate the unselected item using the indexOf() method. Second, it must use splice() to remove that item from Selections.

This example doesn't provide any fancy output, but you can see for yourself how well the selection methodology works. Click Show Selections to display the list of selected items. The ShowResults() event handler displays a list of the selections for you. In a production application, you could just as easily process each of the selected items.

A final piece to this particular application is the need to define one special style. You must provide a means for the display to register the selected state of a particular item, which means providing values for the .ui-selected style, as shown here:

#Selections .ui-selected

{

   background: black;

   color: white;

}

When a user selects an item, the background turns black with white text so the user can see a visual change. You could also modify the text as a second means of helping the user see the selection.

Making items sortable

Certain kinds of sorting are easy for computers to do. For example, a computer can put items in alphabetical order much faster than a human can, especially when the list is long. However, sorts aren't always logical. You may want the user to sort a list of items by personal preference or other criteria that the computer can't even understand. In these cases, you need a means of allowing manual sorts, and this example gives you just what you need. The following example lets a user sort items by unspecified criteria. (You can find complete code for this example in the Chapter 20jQueryUI folder of the downloadable code as SortContent.HTML.)

$(function()

  {

      $("#SortMe").sortable();

  })

nbps;

function ShowResults()

{

   // Create the output string.

   var Output = "The sort order is:       ";

   

   // Locate each of the required items and

   // add them to the string.

   $("#SortMe p").each(

      function(index, element)

      {

         Output += element.innerHTML.substr(74);

      });

   

   // Display the result.

   alert(Output);

}

The sortable() call is all that you need to do to make the list visibly sortable. The user can place the elements, whatever those elements might be, in any order desired. To make this call work, however, you do need to create a container, a <div> in this case, and a list of items, <p> tags in this case. The SortMe id goes with the <div>.

Accessing the items in order is also a requirement. Otherwise, there's no point in letting the user sort the items. In this case, it's actually easier to use other jQuery functionality to obtain the list of elements in the order in which they appear and process them that way. ShowResults() demonstrates one technique for performing this task. You begin by creating the appropriate selector, which begins with the <div>, SortMe, and ends with each <p> tag it contains. The anonymous function receives both an index and an element argument. By checking the innerHTML property of the element, you can obtain the moniker for that <p> tag. The result is displayed in a dialog box.

This example also makes use of a special jQuery UI CSS style. This style creates a double-ended arrow that helps the user understand that each item can move up or down in the list. You create it using a <span> like this:

<span class="ui-icon ui-icon-arrowthick-2-n-s"></span>

You can find a list of these icons at http://jquery-ui.googlecode.com/svn/tags/1.6rc5/tests/static/icons.html. It's important to create icons that match the way your list appears onscreen. Figure 20-2 shows a typical output of this application, including the list in the order that I personally decided to sort them.

9781118494189-fg2002.tif

Figure 20-2: Sortable lists make it possible for users to place items in order of personal preference.

Understanding the widgets

Widgets are specialty controls you can use to create special effects on a page. The advantage of these controls is that they can make your application easier to use and more appealing as well. The disadvantage of widgets as a whole is that they can be overused or used incorrectly.

remember.eps A widget is only a good idea when it materially adds to the usefulness and accessibility of your application. When you find yourself admiring the pizzazz that a widget adds to the application rather than how it makes the user work faster or with greater ease, reconsider using the widget — your application may work a lot better without it.

HTML5 already comes with a number of useful generic controls of all sorts. For example, if you need a standard check box for your application, rely on HTML5 to provide it. The controls described in the following sections are special in some way. For example, the Accordion widget makes it easy to focus user attention by hiding unused elements from sight. The jQuery UI library does provide access to additional widgets that aren’t discussed in the sections that follow. Most widgets, such as Button, have HTML5 counterparts and aren’t quite as useful for that reason.

Using the Accordion widget

You use the accordion to hide any page element from view. When a user selects a category, the elements in that category become visible, and the elements from all other categories are hidden. The effect is to focus user attention and make the user more efficient in performing specific tasks. The following code is all you need to make this feature usable. (You can find complete code for this example in the Chapter 20Widgets folder of the downloadable code as Accordion.HTML.)

$(function()

  {

      $("#Configuration").accordion();

  });

However, the secret in this case is the way you create the tags for your page. Figure 20-3 shows how the form appears to the user. Notice that the Accordion widget hides settings that the user isn’t focusing on. When the user clicks Background Color, the Foreground Color options are hidden from view. Likewise, clicking Options presents those controls.

The controls in each area don’t matter to the Accordion widget, but the HTML5 formatting does. This form also includes a submit button. If you don’t configure the controls properly, the submit button becomes part of the accordion effect, and clicking it no longer submits the form. Here’s a condensed view of the HTML5 for this example:

<form id="ConfigForm"

      method="get"

      action="Accordion.html">

   <div id="Configuration">

      <h2>Foreground Color</h2>

      <div>

         <input id="FGRed"

                type="radio"

                name="Foreground"

                value="Red"

                checked="checked" />

         <label for="FGRed">Red</label><br />

... More inputs and labels ...

      </div>

      <h2>Background Color</h2>

      <div>

         <input id="BGRed"

                type="radio"

                name="Background"

                value="Red"

                checked="checked" />

         <label for="BGRed">Red</label><br />

... More inputs and labels ...

      </div>

      <h2>Options</h2>

      <div>

         <input id="Sounds"

                type="checkbox"

                name="Sounds"

                value="SpecialSounds" />

         <label for="Sounds">Use Special Sounds</label>

         <br />

         <input id="Effects"

                type="checkbox"

                name="Effects"

                value="SpecialEffects" />

         <label for="Effects">Use Special Effects</label>

      </div>

   </div>

   <input id="ChangeConfig"

          type="submit"

          value="Change Configuration" />

</form>

9781118494189-fg2003.tif

Figure 20-3: The Accordion widget focuses user attention.

Notice that you must place the headings control groups within a separate <div> and then label that <div> as the one you want to use for the accordion effect. A separate <div> houses the individual controls for a specific group. The submit button is part of the form, but it's outside the Configuration <div>. When you click the Change Configuration button, you see that the form works as it should by examining the address field content. Using the defaults, you see an address field that contains http://localhost/Accordion.html?Foreground=Red&Background=Red when you click Change Configuration (assuming you're using the server setup to test the example).

Using the Autocomplete widget

Whenever possible, provide the user with specific inputs for forms you create to help the user work more quickly and reduce security risks. For example, instead of providing a text box and asking the user to type the name of a state, provide a combo box that the user can use to choose a state. Even with the best planning, though, you sometimes encounter situations where you must allow the user to provide a freeform answer in a text box — an error-prone method of input at best. The Autocomplete widget makes it possible to reduce the risk of input errors by suggesting the most common responses to such questions. Using this widget isn’t quite as good as providing a specific answer, but it’s the next-best thing.

The following code shows how you implement an Autocomplete widget for a text box. (You can find complete code for this example in the Chapter 20Widgets folder of the downloadable code as Autocomplete.HTML.)

// Create a list of common colors.

var Colors =

[

   "Red",

   "Orange",

   "Yellow",

   "Green",

   "Blue",

   "Purple",

   "White",

   "Black",

   "Gray"

]

nbps;

$(function()

  {

      // Set up the autocomplete function, complete

      // with a list of common colors.

      $("#ColorEntry").autocomplete({source: Colors});

  })

To make this widget work, you create an array that contains a list of common entries. This list should be as complete as possible to ensure that the user can find a desired choice in most cases. The list also serves to help the user understand what input is desired.

When configuring the autocomplete() method, you include the source option. This is one of the few instances where you must include an option to ensure the widget works properly. Notice that the option and its associated value aren't quoted. Figure 20-4 shows typical output from this example. In this case, typing the letter R displays every option that contains that letter. Typing additional letters refines the list of available choices.

9781118494189-fg2004.tif

Figure 20-4: Use the Auto-complete widget to provide the user with a list of common choices.

Using the Datepicker widget

There are situations where HTML5 currently provides a solution for a particular need, but few vendors have implemented it yet. This is the case with the date and time support for HTML. Only Opera and Chrome provide support for the date and time features. For example, if you want to add a date to a form, you can use the date input type as shown here:

<label for="Date">Enter a Date: </label>

<input id="Date"

       type="date" />

The default date is today. When the user clicks on the field, the application displays a date picker control, but only when you use Opera or Chrome. Until the other vendors provide date and time support, it's still necessary to use the jQuery UI Datepicker widget to ensure that all of your users can enter a date with ease. The following code shows how to use the Datepicker widget. (You can find complete code for this example in the Chapter 20Widgets folder of the downloadable code as Datepicker.HTML.)

$(function()

  {

      $("#DateEntry").datepicker();

  })

DateEntry is a standard <input type="text"> control. When the user clicks the control, jQuery UI automatically displays a calendar like the one shown in Figure 20-5.

9781118494189-fg2005.tif

Figure 20-5: The Datepicker widget makes entering dates much easier.

Using the Progressbar widget

Users are impatient, and sometimes a process takes a while to complete. A file downloads only so fast, and some transactions become bogged down on the server. A progress bar makes it possible for the developer to keep the user informed about the progress of a task. Modern programming strategies try to keep the user from waiting at all by performing longer tasks in the background, but sometimes a user can’t proceed until the task is done. This is the time you need to rely on a progress bar to keep the user from attempting to stop the process before it completes.

The following example shows how to use a progress bar. In this case, the progress bar is updated through a timing loop. Each time the timer expires, the progress bar is updated, and the timer is reinstituted. The result is that the progress part indicator moves from left to right and that the timer eventually stops when the indicator moves all the way to right. (You can find complete code for this example in the Chapter 20Widgets folder of the downloadable code as Progressbar.HTML.)

// Configure the progress bar.

$(function()

  {

      $("#Progress").progressbar({value: 0});

  })

nbps;

// Create a variable to hold the timer object.

var Timer;

nbps;

// Create a variable to hold the total timeout.

var Timeout;

nbps;

function StartTimer()

{

   // Initialize the timeout.

   Timeout = 0;

   

   // Set the progress bar maximum value.

   $("#Progress").progressbar(

      "option", "max", parseInt($("#StartValue").val()));

   

   // Create the timer variable.

   Timer = window.setTimeout(UpdateTimer, 100);

}

nbps;

function UpdateTimer()

{

   // Get the maximum value.

   var MaxTime =

      $("#Progress").progressbar("option", "max");

   

   // Check for the end of the timing cycle.

   if (Timeout >= MaxTime)

      return;

   

   // Update the Timeout value.

   Timeout += 100;

   

   // Update the percentage completed.

   $("#PercentDone").text(

      Math.round((Timeout/MaxTime)*100));

   

   // Set the progress bar value.

   $("#Progress").progressbar("value", Timeout);

   

   // Create the timer variable.

   Timer = window.setTimeout(UpdateTimer, 100);

}

The first task is to create the progress bar itself by calling progressbar(). Notice that you must provide an initial value as input. However, the progress bar configuration isn't complete — the call to StartTimer() later will perform some additional configuration tasks.

The StartTimer() function is called when the user clicks Start Timer on the form. This function initializes two global variables. Timer is a timer object used to animate the progress bar. Timeout is the current elapsed time in milliseconds. This function also configures the max option for the progress bar. The indicator is a percentage of the current value and the max value properties. The maximum value is provided by the user through an <input type="text"> control, StartValue.

Whenever Timer expires, it calls UpdateTimer(). UpdateTimer() obtains the maximum time value from the progress bar and places it in MaxTime. It then verifies that Timeout is less than MaxTime. When Timeout finally reaches MaxTime, the progress bar has reached 100 percent, and it's time to stop the timer.

The next step is to update Timeout to the next value. Every iteration advances Timeout by 100 milliseconds.

After updating Timeout, the example updates the onscreen percentage, which is stored in a <span> with an id of PercentDone. It also updates the progress bar's value attribute so that the bar moves to the next position.

A timer fires only once. To create the next loop of the iteration, the example must reset Timer. When the next 100 millisecond wait is over, UpdateTimer() is called again and the process begins anew.

Using the Slider widget

Sliders give the user the ability to input a value visually — as part of a whole. A slider ensures that the user inputs a correct value within a range of values, so you don't need to worry about security issues or incorrect values. As a result, sliders provide a valuable means of allowing variable input. The following example shows how to use a slider in your application. (You can find complete code for this example in the Chapter 20Widgets folder of the downloadable code as Slider.HTML.)

$(function()

  {

      $("#Slider").slider(

         {

            // Set the maximum slider value.

            max: 50,

            

            // Perform tasks when the value changes.

            change: function(event, ui)

            {

               // Display the current slider value.

               $("#Value").text(

                  $("#Slider").slider("value"));

            }

         });

  })

In this case, the code sets the maximum slider value to 50. The minimum value defaults to 0. However, you can set both the maximum and minimum values to any starting or stopping position. Even though the example doesn't show it, the Slider can have more than one handle, so it can represent a range. This flexibility means that you can ask the user to input both a starting and a stopping point.

One of the most commonly used events is change. The example displays the new value each time the user finishes moving the handle. However, the way in which you use the output depends on your application. Generally, you use the output to provide data input or application control. However, it's a good idea to display the actual slider value so the user knows the actual input value.

Using the Spinner widget

Some, but not all, browsers support the <input type="number"> tag. This tag provides a spinner input for working with numeric input, so the user can simply click up or down arrows to change the numeric value of an input. Because it's important to provide users with easy methods for entering data correctly, the Spinner widget is an important addition to your toolkit. Not only does it work with all major browsers, but you can also add features such as input validation, as shown in the following example. (You can find complete code for this example in the Chapter 20Widgets folder of the downloadable code as Spinner.HTML.)

$(function()

  {

      // Create the spinner and place a reference

      // to it in ThisSpinner.

      var ThisSpinner = $("#Spinner").spinner(

         {

            // Set the minimum and maximum values.

            min: 1,

            max: 5,

            

            // Add validation.

            change: function(event, ui)

            {

               // Check for minimum and maximum value

               // compliance.

               if (ThisSpinner.spinner("value") < 1)

                  ThisSpinner.spinner("value", 1);

               

               if (ThisSpinner.spinner("value") > 5)

                  ThisSpinner.spinner("value", 5);

            }

         });

      

      // Set the initial value.

      ThisSpinner.spinner("value", 1);

      

      // Provide a means for returning the current value.

      $("#GetSpinValue").click(

         function()

         {

            alert(ThisSpinner.spinner("value"));

         }

      );

      

      // Create buttons for all buttons on the form.

      $("button").button();

  });

In this case, the example begins by creating a variable to hold the Spinner widget. You can use this technique with any of the widgets to make them easier to work with. This example needs to access the Spinner widget in several ways, so using a variable makes sense.

To ensure the user enters only values in the correct range, you must set the min and max options. However, these options control input only when the user works with the spinner. To verify that manual input is also correct, you must create a handler for the change event. All that this function does is check whether the value() method returns a number between 1 and 5. If not, the code uses the value() method to set the numeric value appropriately.

remember.eps Validation events, such as change, occur when the control loses focus. When you type an incorrect value into the control, the example doesn't fix it immediately. The fix occurs when the control loses focus. To see this event-handling for yourself, type an incorrect value into the control and then click outside the control so it loses focus. You see the control provide a correct value in place of the one you typed.

Eventually, you need to access the widget's value to send it to the server or use it in other ways. This example also creates an event handler for a <button> control, GetSpinValue. When a user clicks this button, it displays the current value.

Using the Tabs widget

Many developers use tabbed interfaces to reduce application complexity. If you can focus the user's attention on one item at a time, you reduce the potential for errant input. This example provides an alternative to the example shown in the Using the Accordion widget section earlier in this chapter. As with that example, you begin with a simple function call. (You can find complete code for this example in the Chapter 20Widgets folder of the downloadable code as Tabs.HTML.)

$(function()

  {

      $("#Configuration").tabs();

  });

The trick for this example is in the HTML tags, just as it was for the Accordion widget example. There are some important differences in how you create the two pages to obtain the desired appearance, as shown in the following code:

<form id="ConfigForm" method="get" action="Tabs.html">

   <div id="Configuration">

      <ul>

         <li><a href="#Tab1">Foreground Color</a></li>

         <li><a href="#Tab2">Background Color</a></li>

         <li><a href="#Tab3">Options</a></li>

      </ul>

      <div id="Tab1">

         <input id="FGRed"

                type="radio"

                name="Foreground"

                value="Red"

                checked="checked" />

         <label for="FGRed">Red</label><br />

... More inputs and labels ...

      </div>

      <div id="Tab2">

         <input id="BGRed"

                type="radio"

nbps;

                name="Background"

                value="Red"

                checked="checked" />

         <label for="BGRed">Red</label><br />

... More inputs and labels ...

      </div>

      <div id="Tab3">

         <input id="Sounds"

                type="checkbox"

                name="Sounds"

                value="SpecialSounds" />

         <label for="Sounds">Use Special Sounds</label>

         <br />

         <input id="Effects"

                type="checkbox"

                name="Effects"

                value="SpecialEffects" />

         <label for="Effects">Use Special Effects</label>

      </div>

   </div>

   <input id="ChangeConfig"

          type="submit"

          value="Change Configuration" />

</form>

Notice that the <h2> elements are gone in this case. Instead of using headings to define the separation between elements, you provide an unordered list (<ul>) instead. The list must contain a href to each of the <div> elements in the page. There isn't any difference in the page content. Figure 20-6 shows typical output from this example.

9781118494189-fg2006.tif

Figure 20-6: Tabs focus the user’s attention, just as the accordion interface does.



To make a change, you click the tab that contains the information you want to see. You make changes as normal. Clicking the Change Configuration button sends the changes to the server. If you test this example by using the same process you did for the accordion example, you get precisely the same results — only the interface appearance has changed.

Defining the effects

Special effects can add pizzazz to your site. They can turn mundane information into something with that special sparkle that people will remember long after they’ve read the material you provide. Using special effects correctly can draw the user’s attention to a particular area of the page or help the user understand a process when using an animated sequence. The point is that effects are normally an addition to the page, not the main focus of it. Effects normally don’t present any sort of information, but they can enhance the impact of information you do present. The following sections describe some of the more interesting effects that you can create using jQuery UI.

Creating an animation by manipulating classes

Using CSS classes can have an interesting effect on the presentation of information onscreen. jQuery UI makes it possible to use CSS classes to perform animations in four different ways:

check.png Adding a class

check.png Removing a class

check.png Switching between classes

check.png Toggling a class

In all four cases, the effect doesn't occur immediately — you provide a time delay to make the transition between presentations slow enough for the user to see. (You can find complete code for this example in the Chapter 20Animations folder of the downloadable code as ManageClasses.HTML.)

$(function()

  {

      $("#ChangeClass").click(function()

         {

            $("#SampleText").addClass(

               "Effect", 1500, RemoveClass);

            return false;

         });

      

      function RemoveClass()

      {

         $("#SampleText").removeClass(

            "Effect", 1500, "easeOutBounce");

      };

      

      $("#SwitchClass").click(function()

         {

            $(".Normal").switchClass(

               "Normal", "Effect", 1500, "easeInElastic");

            $(".Effect").switchClass(

               "Effect", "Effect2", 1500,

               "easeOutElastic");

            $(".Effect2").switchClass(

               "Effect2", "Normal", 1500,

               "easeInOutElastic");

            return false;

         });

      

      $("#ToggleClass").click(function()

         {

            $(".Normal").toggleClass("Effect", 1500);

            return false;

         })

  })

There are three buttons on the front of the page: Add/Remove Class, Switch Between Classes, and Toggle Between Classes. Each of these buttons is assigned an event handler as shown. The RemoveClass() function is a callback for the Add/Remove Class button. After the transition for the event handler has ended, the code automatically calls this function.

All of these animations work in precisely the same way — they add or remove classes to or from the specified element. In this case, a <div> named SampleText is the target of the animations. The difference between the method calls is how they perform their task. The addClass() method performs a straightforward addition of a class. You supply the name of the class to add as the first argument. If the class already exists for the element, nothing happens. Likewise, the removeClass() method removes the specified class from the element. Again, you supply the name of the class to remove as the first argument.

The switchClass() method switches between one class and another. You can use it to create multiple transitions. For example, this example shows how to switch between three transitions. The Normal class is replaced with Effect, Effect is replaced with Effect2, and Effect2 is replaced with Normal. Consequently, you see the animations rotate between three classes. You supply the name of the class to remove as the first argument and the name of the class to add as the second argument.

The toggleClass() method adds or removes a class depending on whether the class is assigned to the element. In this case, the code adds Effect when SampleText lacks it and removes Effect when SampleText has it applied. You supply the name of the class to toggle as the first argument.

remember.eps jQuery UI can’t animate all styles. For example, there’s a transition between having the text left justified and having it centered in this example. This transition can’t be animated. What you see is that the effect occurs at the end of the animation. In addition, some effects are animated, but they aren’t animated in the way you might expect. For example, if an element changes color, the new color is used throughout the animation, but you see it gradually fade in.

Each of these method calls includes a time delay of 1500 milliseconds. This value indicates the amount of time in which the animation occurs. The default setting is 400 milliseconds, which is a little hard for most people to see. However, this argument is optional, and you don’t have to supply it to make the method work.

The addClass() method includes another optional argument, a callback function. The callback function is called when the animation is over. The example uses the callback function to toggle the effect. However, a callback could be used for any number of purposes. For example, you could use it to create a validation sequence to ensure that users enter the correct data for form fields that have incorrect information.

An animation can also use an easing function. This function determines how the animation appears onscreen. The default setting is to use the swing easing function, which provides a gentle transition that most users will appreciate. However, you might want a little more pizzazz or at least a different effect. You can see a list of easing functions at http://api.jqueryui.com/easings. This example uses a number of different easing functions so that you get an idea of how they work.

Defining a color animation

If you want to perform an actual color animation in your application, you need to use the animate() method. This method seems to be a work in progress because the documentation for it isn't nearly as nice as the other documentation for jQuery UI. The method does seem to work for all the target platforms and browsers for this book, but you'll want to experiment to ensure that it will work for every browser you need to target. The color will actually transition in this case. It's also possible to control the text colors to a large degree. The following example shows the most commonly used transitions. (You can find complete code for this example in the Chapter 20Animations folder of the downloadable code as Animate.HTML.)

$(function()

  {

      // Track the normal state.

      var State = true;

      

      $("#ChangeColors").click(

         function()

         {

            if (State)

            {

               // Set to the changed state.

               $("#SampleText").animate(

                  {

                     backgroundColor: "#0000ff",

                     color: "white",

                     borderColor: "#ff0000",

                     height: 100,

                     width: 600

                  }, 1500);

            }

            else

            {

               // Set to the normal state.

               $("#SampleText").animate(

                  {

                     backgroundColor: "#7fffff",

                     color: "black",

                     borderColor: "#00ff00",

                     height: 50,

                     width: 400

                  }, 1500);

nbps;

            }

            

            // Change the state.

            State = !State;

         }

      )

  })

If you're thinking that this code looks like it works similar to CSS, it does, but the animate() method provides a significantly reduced list of features it can change. You can change many features of the text and the container that holds it, including both the width and height. However, you can't change things like the kind of border used to hold everything — even though you can change the color of the border. The jQuery UI documentation states that animate() supports these properties:

check.png backgroundColor

check.png borderBottomColor

check.png borderLeftColor

check.png borderRightColor

check.png borderTopColor

check.png color

check.png columnRuleColor

check.png outlineColor

check.png textDecorationColor

check.png textEmphasisColor

The library-supplied examples (those provided by the vendor on the vendor's site) show that a few other properties are supported, including width, height, and borderColor. Use these non-published properties with care. Even though they work now, they may not be supported in future releases of the library.

Managing element visibility using effects

Many applications require that you show or hide elements at different points of application execution. It may be something as simple as not needing the element at that particular time (such as a progress bar). In most cases, you simply want the element to go away. Whether the user notices the disappearance is immaterial to the application’s functionality. However, you may want the user to notice the change in some situations. For example, a user might select an option that makes other options inaccessible. Using a special effect to make this more noticeable could be helpful.

The jQuery UI library provides several means of controlling element visibility in an animated manner. The fact that the element is shown or hidden doesn’t change, but the way in which the application shows or hides it does. For example, you could use a slide effect to show that a new element has been added due to a choice the user has made. There are four main methods of animating elements by using this technique:

check.png Use an effect where the element visually changes.

check.png Show a hidden element by using an effect.

check.png Hide an element by using an effect.

check.png Toggle an element’s visibility by using an effect.

The effect that you choose for working with an element controls how jQuery UI visually manages it. For example, an explode effect causes the element to break into pieces, with each piece moving in a different direction off screen. The following keywords define the sorts of effects that you can use (you can find additional details at http://api.jqueryui.com/category/effects):

blind

fade

scale

bounce

fold

shake

clip

highlight

size

drop

puff

slide

explode

pulsate

transfer

In addition to the actual effect, you can use an easing function to make the effect more pronounced or special in other ways. You can see a list of easing functions at http://api.jqueryui.com/easings. The following example shows how to use all four approaches for working with element visibility. There are actually four buttons used for the example, but element visibility limits you to seeing just three at a time because you can't show an element that's already visible or hide an element that's already hidden. (You can find complete code for this example in the Chapter 20Animations folder of the downloadable code as Visibility.HTML.)

$(function()

  {

      // Keep track of the element hidden state.

      var Hidden = false;

      

      $("#Effect").click(

         function()

         {

            $("#SampleText").effect(

               "bounce", "easeOutBounce", 1500);

         });

      

      $("#Show").click(

nbps;

         function()

         {

            Hidden = false;

            

            $("#SampleText").show(

               "slide", 1500, ChangeButtonState);

         });

      

      $("#Hide").click(

         function()

         {

            Hidden = true;

            

            $("#SampleText").hide(

               "explode", 1500, ChangeButtonState);

         });

      

      $("#Toggle").click(

         function()

         {

            Hidden = !Hidden;

            

            $("#SampleText").toggle(

               "scale", {percent: 0}, 1500,

               ChangeButtonState);

         });

      

      // Set the button state as needed.

      function ChangeButtonState()

      {

         if (Hidden)

         {

            $("#Show").attr("hidden", false);

            $("#Hide").attr("hidden", true);

         }

         else

         {

            $("#Show").attr("hidden", true);

            $("#Hide").attr("hidden", false);

         }

      }

  })

The example begins by creating a variable, Hidden, to track the state of the element. When the element is hidden, the Show button is displayed. Likewise, when the element is displayed, the Hide button is displayed as well. This functionality is controlled by a callback function, ChangeButtonState().

The code for the Effect button simply performs an effect on the element, SampleText. In this case, you see the bounce effect. The performance of this effect is modified by the easeOutBounce easing function, and the entire animation lasts 1500 milliseconds. The actual visibility is unchanged, but the user sees an animation of the element onscreen. You could use this technique to point out fields that have incorrect information or require additional information. Of course, you can also use it to perform any other sort of simple animation desired — including a looped animation, where the animation is constantly replayed.

The Show and Hide button codes work hand-in-hand to hide or display SampleText. The Show button uses the slide effect, and the Hide button uses the explode effect. Both perform the task over 1500 milliseconds. Notice that both event handlers set the state of Hidden directly because the state is an absolute based on the task that the button performs. The event handlers also provide ChangeButtonState() as a callback function. The animation calls this function after the animation has completed to set the button state correctly.

The Toggle button works like a combination of the Show and Hide buttons — the event handler simply toggles the SampleText visual state. Because the state isn't known, the value of Hidden is also toggled. In this case, the event handler calls the scale effect, which requires an additional argument in the form of percent. Make sure you check the effects to determine whether they require additional arguments — most don't. When the animation completes, the application calls ChangeButtonState() to reconfigure the user interface as needed.

Canvasing Your Web Page

HTML5 includes the concept of a canvas. As with the artist’s version of the physical canvas, you use the HTML5 canvas to draw images onscreen. Using the canvas makes it easier to manage various sorts of drawings that you need to convey information to the user. The following sections provide additional details about the canvas from a JavaScript perspective and then demonstrate how to use the canvas with the Google Maps API to draw a map onscreen.

Understanding what the canvas does

A canvas is simply a drawing area onscreen. To create a canvas, the browser you interact with must support HTML5. This means that you need to use newer browser versions, such as Internet Explorer 9.

You also need to have an understanding of the source of the canvas and how the canvas works with the client's browser. The canvas relies on an actual <canvas> tag. To draw something onscreen, you provide an id, a height, and a width property for the <canvas> tag like this:

<canvas id="MyCanvas"

        height=500

        width=600 />

The size of the canvas is always in pixels. When you have a canvas to use, you can create a context to it by obtaining a reference to the canvas element and calling getContext() with the type of context you want, such as 2D. The context lets you use various drawing commands to create graphics onscreen. A discussion of precisely how the canvas works is outside the scope of this book. You could quite easily create several books on the topic and not cover the topic thoroughly. A great tutorial on the topic appears at http://www.html5canvastutorials.com. You could also read HTML5 Canvas For Dummies by Don Cowan (Wiley) for additional information.

remember.eps The important issue for this chapter is precisely where the canvas comes from. Most tutorials assume that the client relies on local JavaScript functionality to perform the task. A simple application could use this approach, but most of the applications you'll create will rely on server-based canvases. In this case, you supply a <div> as a container to hold the <canvas> that the server sends to the client. The advantage of this approach is that the server can create a wealth of graphics for the client and send the cached <canvas> tags to every client that needs them — creating an efficient method for sharing graphics. Many developers find this approach confusing, which is why this chapter approaches the canvas from the server-based perspective using the Google Maps API.

Creating a simple Google API application

This chapter doesn't provide a detailed look at the Google Maps API, which is relatively complex. What it does provide is a simple look at something you could easily expand into a full-fledged application later. Many organizations use maps for all sorts of interesting purposes. The article at http://blog.smartbear.com/software-quality/bid/242126/using-the-google-maps-api-to-add-cool-stuff-to-your-applications provides some additional ideas on how you can use the Google Maps API with your browser-based application.

Obtaining a developer key

To use this example, you must obtain a developer key. Google provides two kinds of keys: paid and free. You need only the free key for this example. The paid key does provide considerably more flexibility, and you'll likely need it for any full-fledged application you create. However, for experimentation purposes, the free key works just fine. You can obtain this key at https://developers.google.com/maps/licensing. Make sure you understand the terms of service fully before you begin working with the Google Maps API. You can also find some additional assistance in using the Google Maps API with JavaScript at https://developers.google.com/maps/documentation/javascript/tutorial.

Creating the application

It's best to create the code for this example in several steps. The first is to add the usual jQuery references used in the remainder of the chapter. In addition, you also need to add a reference to the Google Maps API, as shown here. (You can find complete code for this example in the Chapter 20GoogleAPI folder of the downloadable code as GoogleAPI.HTML.)

<script type="text/javascript"

   src="https://maps.googleapis.com/maps/api/js?key=Your Key Here&sensor=false">

</script>

warning_bomb.eps This example won't work at all unless you replace the words, Your Key Here, with the key that you receive from Google. Consequently, this particular step is important because it's the one step you must perform even if you're using the code downloaded from the book's site.

Now that you have all the required references in place, it's time to create a canvas to draw the map. The canvas is simply a <div> with an id: <div id="MapCanvas"></div>. You must provide style information that gives the <div> size or else the map won't appear onscreen, even when Google sends it to you. The example uses the following style information:

#MapCanvas

{

   height: 90%;

   width:100%;

}

In addition to the canvas, the example provides two text boxes for input and a button that you can use to request a new map. There isn’t anything too complex about the interface, but it gets the job done. The code for this example uses many of the jQuery and jQuery UI tricks you’ve already seen in other places in the book, as shown here:

$(function()

  {

      // Track the current latitude using a

      // spinner control.

      var Latitude = $("#latitude").spinner(

         {

            min: -90,

            max: 90,

            step: .1,

            

            change: function(event, ui)

            {

               if (Latitude.spinner("value") < -90)

                  Latitude.spinner("value", -90);

               if (Latitude.spinner("value") > 90)

                  Latitude.spinner("value", 90);

            }

nbps;

         });

      

      // Track the current longitude using a

      // spinner control.

      var Longitude = $("#longitude").spinner(

         {

            min: -180,

            max: 180,

            step: .1,

            

            change: function(event, ui)

            {

               if (Longitude.spinner("value") < -180)

                  Longitude.spinner("value", -180);

               if (Longitude.spinner("value") > 180)

                  Longitude.spinner("value", 180);

            }

         });

      

      // This function actually displays the map on

      // screen.

      function GetMap()

      {

         // Create a list of arguments to send to Google.

         var MapOptions =

         {

            center: new google.maps.LatLng(

                        Latitude.spinner("value"),

                        Longitude.spinner("value")),

            zoom: 8,

            mapTypeId: google.maps.MapTypeId.ROADMAP

         }

         

         // Provide the location to place the map and the

         // map options to Google.

         var map = new google.maps.Map(

            document.getElementById("MapCanvas"),

            MapOptions);

      };

      

      // The example provides two methods of getting a

      // map: during page loading or by clicking Get Map.

      $(window).load(

         function()

         {

            GetMap();

         });

      

      $("#submit").click(

         function()

         {

            GetMap();

         });

  })

To make it easier to browse an area, the example provides spinner controls for the latitude and longitude inputs. These spinners work much like the spinner example described in the earlier Using the Spinner widget section of this chapter. However, moving an entire degree at a time wouldn't make the application very useful, so the two spinners change the inputs by a tenth of a degree at a time. (Even this setting may be too large, so you might want to change it.) Notice the use of the step option to perform this task. Latitudes range from 90 degrees north to –90 degrees south, so the example reflects this requirement. Likewise, longitudes range from 180 degrees west to –180 degrees east of Greenwich, England. You can read more about latitude and longitude at http://geography.about.com/cs/latitudelongitude/a/latlong.htm.

The GetMap() function performs the actual task of obtaining the map. To do this, your application must create a list of map options. The example shows a simple, but typical, list. The most important of these options is where to center the map. In this case, the map automatically centers itself on Milwaukee, Wisconsin, but you can change the settings to any location you want. The example uses a zoom factor of 8, and you'll see a road map. The Google Maps API actually provides a number of map types that you can try.

There are two times when GetMap() is called. When the application loads, you see Milwaukee, Wisconsin (unless you change the default settings). After you change the inputs, you can also click Get Map to display a new location. Figure 20-7 shows typical output from this application.

9781118494189-fg2007.tif

Figure 20-7: The example can show any location for which you have a longitude and latitude.

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

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