Channels ▼
RSS

JVM Languages

Getting Started with jQuery


Fetching Dynamic Data with jQuery

In the previous section we were introduced to the jQuery load() method, which made it extremely easy to perform the common task of fetching an HTML snippet to load into a DOM element. While the utility of this method cannot be dismissed, there are times when we might want to exert more control over the Ajax request process, or to obtain data (as opposed to preformatted HTML) from the server.

In this section we'll explore more of what jQuery has to offer in the Ajax arena.

Problem

We wish to augment the code of the previous section to obtain the list of items in the eFridge from a page-initiated asynchronous request.

Solution

Reviewing the previous solution, we can readily see that in order to load the select options dynamically, the changes that we would need to make are to remove the option> elements from the selectg> element and to add code to the ready() handler to fetch and load the items. But before we embark upon that effort, we're going to change the way that we coded the showItemInfo()handler function if for no other reason than as an excuse to further explore jQuery's capabilities. Rather than using the load() method of the jQuery wrapper, we're going to use one of jQuery's utility functions:

$.get() . 

Hey, wait a minute! What's that period character doing in there? That's not the $() wrapper that we've been using up to now!

Not only does jQuery provide the wrapper class that we've make good use of up to this point, but it also provides a number of utility functions, many implemented as class methods of the $ wrapper class.

If the notation $.functionName() looks odd to you, imagine the expression without using the $ alias for the jQuery function:

jQuery.get();

Okay, that looks more familiar. The $.get() function is defined as a class method; that is, a function property of the jQuery wrapper function. Although we know them to be class methods on the jQuery wrapper class, jQuery terms these methods utility functions and to be consistent with the jQuery terminology, that's how we'll refer to them in this section.

The $.get() utility function accepts the same parameters as the load() method: the URL of the request, a hash of the request parameters, and a callback function to execute upon completion of the request. When using this utility function, because there is no object being wrapped that will automatically be injected with the response, the callback function, although an optional parameter, is almost always specified. It is the primary means for causing something to happen when the request completes.

It should also be noted that the callback function can be specified as the second parameter to this utility function when no request parameters need to be passed. Internally, jQuery uses some JavaScript sleight of hand to ensure that the parameters are interpreted correctly.

The rewritten showItemInfo() handler using this utility function is as follows:

function showItemInfo() {
  $.get('fetchItemData.jsp',
        {itemId: $(this).val()},
        function(data) {
          $('#itemData').empty().append(data);
        }
  );
}

Aside from using the $.get() utility function, another change to the code of the previous solution was the addition of a callback function as the third parameter, which we use to insert the returned HTML into the itemData element.

In doing so, we make use of two more wrapper methods: empty(), which clears out the wrapped DOM element, and append(), which adds to the wrapped element the HTML snippet passed to the callback in the data parameter.

Now we're ready to tackle loading the options> from data that we will obtain from the server when the document is loading. In this case, we're going to obtain the raw data for the options from the server in the form of a JavaScript hash object. We could return the data as XML, but we'll opt to use JSON, which is easier for JavaScript code to digest.

jQuery comes to our rescue once again with a utility function that is well suited to this common task: the $.getJSON() utility function. This function accepts the now-familiar trio of parameters: a URL, a hash of request parameters, and a callback function.

The advantage that the $.getJSON() utility function brings to the table is that the callback function will be invoked with the already-evaluated JSON structure. We won't have to perform any evaluation of the returned response. How handy!

Using this utility method, the following line gets added to the document's ready() handler:

$.getJSON('fetchItemList.jsp',loadItems);

A JSP page named fetchItemList.jsp is used as the URL, and a function named loadItems() (whose definition we'll be looking at next) is supplied as the callback function. Note that, since we don't need to pass any request parameters, we can simply omit the object hash and provide the callback as the second parameter.

The loadItems() function is defined as

function loadItems(itemList) {                       
#1
  if (!itemList) return; 
  for(var n = 0; n < itemList.length; n++) {
    $('#itemsControl').get(0).add(                   
#2
      new Option(itemList[n].name,itemList[n].id),   
#3
                 document.all ? 0 : null
    );
  }
}

  • #1 Invokes callback with evaluated JSON structure
  • #2 Locates select element
  • #3 Adds new option

Recall that the $.getJSON() utility function invokes the callback with the JSON response already evaluated as its JavaScript equivalent (#1). In our solution, the fetchItemList.jsp page will return a response that contains

[
{id:'3',name:'BBQ Sauce'},
{id:'5',name:'Mustard'},
{id:'7',name:'Cheese'},
{id:'2',name:'Cole Slaw'},
{id:'4',name:'Lunch Meat'},
{id:'8',name:'Iced Tea'},
{id:'6',name:'Hot Sauce'},
{id:'1',name:'Milk'}
]

When our callback is invoked, this response string will already have been converted to an array of JavaScript objects, each of which contains an id and a name property, courtesy of jQuery. Each of these objects will be used to construct a new option> element to be added to the select control (#3).

In order to add an option to the select> element, we need a reference to that control's DOM element. We could just use document.getElementById() or $(), but we have chosen to do it the jQuery way with the get() wrapper method:

$('#itemsControl').get(0)

This method, when passed no parameters, returns an array of all the elements matched by the CSS selector of the jQuery wrapper on which it is invoked. If we only want one of those matches, we can specify a zero-based index as a parameter. In our case, we know that there will only be a single match to the selector because we used an id, so we specify an index of 0 to return the first matched element.

The code for the entire page, with changes from the previous solution highlighted in bold, is shown here.

<html>
  <head>
    <title>What's for dinner?</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
      $(document).ready(function(){
        <b>$.getJSON('fetchItemList.jsp',loadItems);</b>j
        $('#itemsControl').change(showItemInfo);
      });

      <b>function loadItems(itemList) {
        if (!itemList) return;
        for(var n = 0; n < itemList.length; n++) {
          $('#itemsControl').get(0).add(
            new Option(itemList[n].name,itemList[n].id),
                       document.all ? 0 : null
          );
        }
      }</b>

      function showItemInfo() {
        <b>$.get('fetchItemData.jsp',
              {itemId: $(this).val()},
              function(data) {
                $('#itemData').empty().append(data);
              }
        );</b>
      }
    </script>
  </head>

  <body>
    <form style="float:left">
      <select id="itemsControl" name="items" size="10">
      </select>
    </form>
    <div id="itemData" style="float:left"></div>
  </body>
</html>

Discussion

This section exposed us to more of jQuery's abilities in the areas of DOM manipulation and traversal, as well as Ajax request initiation. We saw the jQuery $.get() utility function, which made it easy for us to make Ajax requests using the HTTP GET method. A corresponding utility function named $.post() with the exact same function signature makes it equally easy to submit POST requests via Ajax. As both utility functions use the same parameter signature -- most notably the request parameter hash -- we can easily switch between which HTTP method we'd like to use without having to get bogged down in the details of whether the request parameters need to be encoded in the query string (for GET) or as the body of the request (for POST).

Another Ajax utility function, $.getJSON(), makes it incredibly easy for us to use the power of the server to format and return JSON notation. The callback for this operation is invoked with the JSON string already evaluated, preventing us from having to work with the vagaries of the JavaScript eval() function ourselves.

For occasions where we might wish to exert more control over, and visibility into, an Ajax request, jQuery provides a versatile utility function named $.ajax(). The online documentation provides more details about how to use this low-level utility function.

We also saw a handful of the powerful DOM manipulation wrapper methods such as get(), empty(), val(), and append(), all geared toward making it easy for us -- as Ajax page developers -- to manipulate the page DOM.

Taking the next steps

This is all just barely plumbing the depth of jQuery capabilities. For example, space prevents us from exploring the effects API, which provides fading, sliding, flashing, hovering. and even the ability to provide your own animations. You are urged to visit http://jquery.com/ for more information on jQuery and how it can help you write powerful Ajax applications.

Additionally, advanced developers might be interested in jQuery's plug-in API. This API is one of jQuery's most powerful assets, as anyone can extend the toolkit in a snap. For more information, please see http://docs.jquery.com/Plugins/Authoring.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video