Chapter 25

jQuery

WHAT’S IN THIS CHAPTER?

Wrox.com Code Downloads for this Chapter

Please note that all the code examples in this chapter are available as a part of this chapter’s code download on the book’s website at www.wrox.com on the Download Code tab.

The open source JavaScript library jQuery is the de facto standard for today’s modern JavaScript development. According to a statistic from http://trends.builtwith.com/javascript (as of January 2013), more than 40 percent of the top 1,000,000 websites that use a well-known JavaScript library have picked jQuery. So, it comes as no surprise that Microsoft has also embraced jQuery.

Previously, Microsoft worked on its own JavaScript project: the Microsoft Ajax Library. It is still part of ASP.NET Web Forms (and is loaded automatically if the ScriptManager control is added to a page, as discussed in Chapter 23), but never caught on with non-Microsoft developers. Therefore, Microsoft decided to favor the market leader instead. Many of the web templates that ship with Visual Studio 2010 and later come with jQuery.

jQuery is a very powerful library and makes countless common JavaScript tasks really easy. Entire books have been written about jQuery, including Wrox’s 336-page Professional jQuery by Cesar Otero and Rob Larsen (John Wiley & Sons, 2012). Obviously, this chapter can only scratch the surface and guide you through the most common tasks when working with the JavaScript library. For more in-depth information, refer to the aforementioned book, or the rich documentation on the jQuery site at http://api.jquery.com/.


NOTE The code in this chapter was written and tested with jQuery 1.9, but should also run in all jQuery versions after 1.7 (some of the listings will run with even older versions).

INTRODUCTION TO JQUERY

The jQuery homepage is http://jquery.com/ (see Figure 25-1) and was redesigned in January 2013. It prominently features the three main selling points of the library:

FIGURE 25-1

image

To use jQuery in an ASP.NET application, you need to add the library to the current website or project. If you want to download the library manually, just click the download link on the jQuery homepage; however, the code looks quite illegible (see Figure 25-2). The reason is that the code has been optimized for performance: Whitespace was removed, and identifiers have been renamed so that they are shorter.

FIGURE 25-2

image

You can download a more readable, and commented, version of the code if you click the Download Un-minified Copy link. Figure 25-3 shows part of the JavaScript within that file.

FIGURE 25-3

image

Pick whichever version of the file you want (hint: usually, the smaller version is good enough for development, and it’s the one you should deploy anyway), and add it to your site or web project.

A more convenient way to add the most current version of jQuery to your project is to use the NuGet package manager. In the Package Manager Console, execute the command from Listing 25-1.

LISTING 25-1: Installing jQuery via NuGet

Install-Package jQuery

After a short while, your website contains a new Script folder with at least the following files in it (assuming that jQuery 1.9.0 is the most current version — the latest version at the time you are trying this may vary):

Depending on how you are installing jQuery and which version is current, the path and the name of the file might be a bit different than what is used in this chapter. Make sure you adapt the filenames to your system.

The third file in the preceding list is of specific interest, because it can facilitate working with jQuery a bit. To demonstrate this, have a look at Listing 25-2. You see that the jQuery JavaScript library has been added to a page with a <script> tag.

LISTING 25-2: Loading jQuery

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
 
    </script>
</head>
<body>
    <div>
    </div>
</body>
</html>

In the currently empty <script> tag, enter jQuery(. If you have downloaded jQuery manually, you will probably get an IntelliSense window similar to the one in Figure 25-4. If you have used NuGet (and have the jQuery VSDOC file in your project), IntelliSense will look as shown in Figure 25-5.

FIGURE 25-4

image

FIGURE 25-5

image

The reason for the different IntelliSense: The VSDOC file contains the additional type hints and comments shown in Figure 25-5. But even if you downloaded jQuery manually, there is no reason to despair: You can also download the VSDOC file separately. Microsoft’s content delivery network (CDN) usually carries the VSDOC version shortly after a new jQuery version has been released. http://www.asp.net/ajaxlibrary/cdn .ashx#jQuery_Releases_on_the_CDN_0 shows you an up-to-date list.

Before diving deeper into using jQuery, this section presents a common pattern that is used in most jQuery-powered sites. Listing 25-3 shows the usual setup: first, you load jQuery; you might just want to change the version number if you are using a different one than used here. In the next <script> block, you start using jQuery code. The first line looks a bit strange:

$(function() {

It starts with the dollar sign — are you suddenly using PHP? To the contrary — in JavaScript it’s perfectly fine to use $ as an identifier. Because no one would actually call one of their functions $(), many JavaScript libraries use $() instead so that there is no name clash.

LISTING 25-3: A Common pattern for using jQuery

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            // DOM is ready
        });
    </script>
</head>
<body>
    <div>
    </div>
</body>
</html>

Actually, $() is the central function of jQuery and serves several purposes. If you think that this makes code hard to read, you might want to use jQuery instead of $ — its equivalent.


NOTE Most code written with jQuery uses the short form.

If you have a look at the IntelliSense output of $()/jQuery() in Figure 25-5, you will see several of the overloads of that function. The third option is called “Binds a function to be executed when the DOM has finished loading.” In Ajax applications, this is crucial. Most of the time, you are using the document object model (DOM) to access an element on the page. However, this is only possible once the DOM has been fully loaded — this usually happens very shortly after the HTML document has been fully transmitted from the server to the browser.

So if you are providing a function as an argument to $() — isn’t JavaScript a fascinating language! — this very function is executed once the DOM is ready. Most of the time, this is exactly what you want. Therefore, you use this pattern throughout this chapter.


NOTE Some time ago, a more common — but more verbose — way of achieving the same effect (code being executed once the DOM is ready) looked like this:
$(document).ready(function() { 
  //... 
});
Today this is a sign of old code. It still works, though.

SELECTING ELEMENTS

The common order of actions when working with any JavaScript library is as follows: you wait for an event (for example, the DOM has finished loading, the user clicks a button, and so on), then you select an element on the page, and, finally, you read from or write to that HTML element. Because you already know how one of those events works (the DOM has finished loading), you can move on to selecting elements. Luckily, the jQuery team did not invent a completely new syntax for this task; instead, it was reusing an established standard that serves the same purpose: cascading style sheets (CSS) selectors.

This World Wide Web Consortium (W3C) standard, part of CSS, describes how specific elements on a page are selected. In the context of CSS, the purpose of this selection process is to style or position elements. In the context of jQuery, you can do anything you want with those objects.


NOTE The current version of the specification (http://www.w3.org/TR/css3-selectors/) contains a complete list of the standard, and jQuery supports most of it. Actually, jQuery is very clever: In older browsers, the JavaScript library has its own selector engine called Sizzle, which is also available as a separate project (http://sizzlejs.com/). This selector engine parses a CSS selector and returns a set of elements.

More modern browsers have built-in JavaScript APIs to do CSS selection. If such a client is encountered, jQuery delegates the complex parsing and selection task to the browser.

Like jQuery, CSS is a very complex topic. Wrox’s Beginning CSS by Richard York (John Wiley & Sons, 2004) had 648 pages! However, in most scenarios one of the common CSS selectors just does the job. Three general kinds of CSS element selectors exist:


WARNING When working with ASP.NET Web Forms, this approach is usually dangerous, because ASP.NET by default rewrites some IDs. Using ClientIDMode="Static" might help, or dynamically determining a client ID with a control’s ClientID property. In most cases, however, a combination of tag and class selectors is the best way to go.

If you call the $() function with a CSS selector as an argument, you will get back a list of those elements on the page that match this selector. To be exact, you will receive a jQuery object, representing the selected elements. The difference is that a jQuery object can have methods, so you could process those selected elements further. You use this feature quite a bit later in this chapter.

For now, you just use one of the methods of the jQuery object: size() returns the number of elements. Listing 25-4 shows a simple page that contains a few elements. The JavaScript code then selects a few ­elements and uses JavaScript’s alert() to output the result, which is also shown in Figure 25-6.

FIGURE 25-6

image

LISTING 25-4: Selecting elements with jQuery

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            var divs = $("div").size();
            var spans = $("span").size();
            alert(divs + " <div> elements\n" +
                  spans + " <span> elements");
        });
    </script>
</head>
<body>
    <form runat="server">
        <div>
            <span>First label</span>
        </div>
        <asp:Panel ID="Panel1" runat="server">
            <asp:Label ID="Label1" runat="server" 
                Text="Second label" />
        </asp:Panel>
    </form>
</body>
</html>

The result in Figure 25-6 might be a bit surprising. However, consider that <asp:Panel> is rendered as a <div> element by default, and <asp:Label> turns into a <span> element. Also, a look at the resulting HTML markup reveals that the hidden ViewState field is enclosed in yet another <div> element, so the result is correct. Remember: It’s the HTML that matters, not the ASP.NET markup.

MODIFYING ELEMENTS

Just counting how many elements you have selected is rare; usually you know exactly how many elements you are getting. What matters is what you do with them afterwards. You have full Create, Read, Update, Delete (CRUD) functionality with jQuery, but most of the time you either read from or write/into an element, or you add new elements to your page.

Modifying Content

jQuery offers four methods to read information from a selected element, depending on the type of element:

Changing those values is possible, too. The following four methods are provided:

As you can see, the getter and setter methods are the same — just the number of arguments helps jQuery determine what to do. From an API point of view, this may look weird at first, but it also helps to keep the list of methods short and concise.

Listing 25-5 shows the two purposes of the html() method in action: Once the DOM is ready, the current HTML content of the selected element is retrieved; then, the current time is appended. See Figure 25-7 for the result.

FIGURE 25-7

image

LISTING 25-5: Reading and writing HTML content with jQuery

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            var oldvalue = $("div").html();
            $("div").html(oldvalue + " " + new Date().toLocaleTimeString());
        });
    </script>
</head>
<body>
    <div>
        <i>jQuery</i>
    </div>
</body>
</html>

If you are using html() (or text(), val(), or attr()), as a setter, the return value of such a method call is still a jQuery object representing the selected elements. Therefore, you can use chaining — just chain method call after method call. Cynics may claim that most jQuery code is actually just one line of JavaScript — a very long line.

To demonstrate chaining, take a look at another jQuery method that you can use to modify elements: css(). As the name suggests, you can use it to get or set CSS properties. This method has three uses:

Listing 25-6 builds upon Listing 25-5 and adds a background and foreground color to the text that has been changed by jQuery before. The calls to css() are chained after the call to html(). Figure 25-8 depicts the result in the browser.

FIGURE 25-8

image

LISTING 25-6: Changing CSS styles with jQuery

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            var oldvalue = $("div").html();
            $("div").html(oldvalue + " " + new Date().toLocaleTimeString())
                    .css("color", "orange")
                    .css("background-color", "black");
        });
    </script>
</head>
<body>
    <div>
        <i>jQuery</i>
    </div>
</body>
</html>

Adding and Removing Elements

The techniques demonstrated in the previous section are very well suited for displaying text and HTML on a page. However, when you want to add several HTML elements to the page, this approach becomes cumbersome: You need to assemble HTML markup, be careful about special characters, and, in the end, everything is added with the html() method.

However, jQuery has a very powerful API to add (and remove) new elements to an HTML page, as well. Start with adding elements. You could use the html() method, but then would need to take care about escaping. However, there is another API available in jQuery. Several steps are required to use it. First you need to create a new element. Once again, the $() function can help here. If the first argument is an HTML element with angle brackets (such as $("<a>")), the return value of the function call is a jQuery object representing the new HTML element. You can then further modify this element using html(), css(), and the other aforementioned methods. Finally, if you want to add the new element to the page, you first need to select the host — this could be a placeholder like a <div> element or the <body> element. Then, the append() method adds the new HTML element to the selected one.

Listing 25-7 creates a new <a> element and then sets its href attribute to make it a proper link. Finally, the new link is then appended to the page’s <body> element.

LISTING 25-7: Adding an element with append()

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $("body").append(
                $("<a>").attr("href", "http://jquery.com/").html("jQuery")
            );
        });
    </script>
</head>
<body>
</body>
</html>

In Listing 25-8, a similar approach is used. This time, you use the appendTo() method of the newly created element. As an argument you once again have to pick a CSS selector, this time one for the existing element(s) you would like to append the new HTML element to.

LISTING 25-8: Adding an element with appendTo()

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $("<a>").attr("href", "http://jquery.com/")
                    .html("jQuery")
                    .appendTo("body");
        });
    </script>
</head>
<body>
</body>
</html>

Both Listings 25-7 and 25-8 lead to the result shown in Figure 25-9.

FIGURE 25-9

image

If you want to get rid of elements, it is quite easy to delete them. A rather hacky way is to select a surrounding element and then execute html(""). A cleaner approach is to select the element you want to delete, and then call the remove() method, as Listing 25-9 shows.

LISTING 25-9: Removing an element with remove()

$(function() {
    $("p.myClass").remove();
});

EVENT HANDLING

So far, all code has been executed once the DOM is fully loaded. This is an important step, because availability of the DOM is paramount for most JavaScript applications. However, there are more events, for instance the user clicking a button, or hitting a key.

For most of those events, jQuery provides a specific method. The following list shows some of the most common ones:

These methods are jQuery object methods: You first use $() to select one or more elements, and can then subscribe to events fired for those elements. As an argument for aforementioned methods, you provide a JavaScript function. This function is then executed should the element actually receive the given event.

Listing 25-10 adds text to the page when the user clicks a button. Note that the event handling is (and can only be) set up once the DOM has finished loading. Figure 25-10 shows the result.

FIGURE 25-10

image

LISTING 25-10: Event handling with a specific method

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#button1").click(
                function () {
                    $("#label1").html("clicked at: " + 
                                      new Date().toLocaleTimeString());
                }
            );
        });
    </script>
</head>
<body>
    <form runat="server">
        <span id="label1"></span>
        <input type="button" id="button1" value="Click!" />
    </form>
</body>
</html>

Not all DOM events are represented by those specific jQuery methods; for instance, gestures available on mobile devices. For this purpose, jQuery offers a generic event handler setup method called on(). You provide the name of the event and the event handler function, and you are set. See Listing 25-11 for a port of Listing 25-10 to use the on() method.

LISTING 25-11: Event handling with the on() method

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#button1").on(
                "click",
                function () {
                    $("#label1").html("clicked at: " + 
                                      new Date().toLocaleTimeString());
                }
            );
        });
    </script>
</head>
<body>
    <form runat="server">
        <span id="label1"></span>
        <input type="button" id="button1" value="Click!" />
    </form>
</body>
</html>

USING BIND(), LIVE(), DELEGATE()
The on() method (and also its counterpart to remove event handlers, off()) was introduced in jQuery 1.7. It includes additional features, like adding event handlers to HTML elements added later to the page. Previous versions of the JavaScript library had other methods to set up event handlers, usually bind(), and for binding event handlers later, delegate() and live(). Using on() is preferred over using these methods, although you will still find them in older code. The jQuery documentation has great information on how to port older code to the new on() syntax; see http://api.jquery.com/bind/, http://api.jquery.com/delegate/, and http://api.jquery.com/live/.

In some cases, you want your event handler to be fired only once; for instance, when submitting an order. (I’ve learned the hard way that not all websites take this into account, and impatiently clicking twice is a bad thing.) For this scenario, the one() method will be your friend: The event handler will be executed once and then be removed.

Have a look at Listing 25-12, which uses one(). When you click the button the first time, the current time is shown. All subsequent clicks show no result.

LISTING 25-12: Event handling with the one() method

$(function () {
    $("#button1").one(
       "click",
        function () {
            $("#label1").html("clicked at: " + new Date().toLocaleTimeString());
        }
    );
});

AJAX

The last missing “big” ingredient for your jQuery recipes is, of course, Ajax in its true sense: making HTTP requests to the server. To facilitate testing this feature, you first create an ASHX handler (see Listing 25-13) that accepts GET and POST requests and returns some data depending on the input. Actually, there are three behaviors of this handler:

1. The browser sends a simple GET request. Then the handler returns the current time as a string.
2. The browser sends a GET request with the URL info json=true. Then the handler returns the current time as a string in JSON format (enclosed in double quotes).
3. The browser sends a POST request. Then the handler returns a text stating exactly that this is a POST request.

LISTING 25-13: The generic handler for your Ajax calls

VB

<%@ WebHandler Language="VB" Class="Listing_25_13" %>
 
Imports System
Imports System.Web
Imports System.Web.Script.Serialization
 
Public Class Listing_25_13 : Implements IHttpHandler
    
    Public Sub ProcessRequest(ByVal context As HttpContext) _
        Implements IHttpHandler.ProcessRequest
        Select context.Request.RequestType
            Case "GET"
                If context.Request("json") Is Nothing OrElse _
                    context.Request("json") <> "true" Then
                    context.Response.ContentType = "text/plain"
                    context.Response.Write(DateTime.Now.ToLongTimeString())
                Else
                    Dim json = New JavaScriptSerializer().Serialize(
                        DateTime.Now.ToLongTimeString())
                    context.Response.ContentType = "application/json"
                    context.Response.Write(json)
                End If
            Case "POST"
                context.Response.ContentType = "text/plain"
                context.Response.Write("POST at " + _
                                       DateTime.Now.ToLongTimeString())
        End Select
    End Sub
 
    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property
 
End Class

C#

<%@ WebHandler Language="C#" Class="Listing_25_13" %>
 
using System;
using System.Web;
using System.Web.Script.Serialization;
 
public class Listing_25_13 : IHttpHandler {
 
    public void ProcessRequest(HttpContext context)
    {
        switch (context.Request.RequestType)
        {
            case "GET":
                if (context.Request["json"] == null ||
                    context.Request["json"] != "true")
                {
                    context.Response.ContentType = "text/plain";
                    context.Response.Write(DateTime.Now.ToLongTimeString());
                }
                else
                {
                    var json = new JavaScriptSerializer().Serialize(
                        DateTime.Now.ToLongTimeString());
                    context.Response.ContentType = "application/json";
                    context.Response.Write(json);
                }
                break;
            case "POST":
                context.Response.ContentType = "text/plain";
                context.Response.Write("POST at " + 
                                       DateTime.Now.ToLongTimeString());
                break;
        }
    }
 
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
 
}

jQuery offers a number of ways to do the actual Ajax requests. Let’s first start with the simple GET request. The method $.get() (note the dot between $ and get!) prompts the browser to send an HTTP GET request to a URL (first argument). Once the server sends data back, the callback function (second argument) is executed, with the data from the server automatically passed as an argument. Listing 25-14 shows this.

LISTING 25-14: Sending a simple GET request

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $.get("Listing%2025-13.ashx", function (result) {
                $("div").text(result);
            });
        });
    </script>
</head>
<body>
    <div></div>
</body>
</html>

If you are using a browser add-in like the Internet Explorer F12 Developer Tools or Firebug for Firefox, you can watch the HTTP request being made and the data being sent back to the browser before it is displayed (see Figure 25-11).

FIGURE 25-11

image

WARNING The Same Origin Policy is a JavaScript security feature which dictates that HTTP requests are only possible if the request target (the URL that is requested) has the same origin (domain, port, protocol) as the HTML page that hosts the JavaScript code doing the Ajax request. Modern browsers provide mechanisms to circumvent this restriction; however, for the sake of backward compatibility you should try to use the same origin for your Ajax call targets and for your HTML pages. To make the code examples in this section work, it is best to use a website that hosts both the HTML files and the services (ASHX, ASMX).

If you want to send data along with your GET request, you can provide it as the second argument; the callback function then moves back to the third place. Note that it is best to provide an object; jQuery takes care of URL-encoding this properly. Listing 25-15 sends a GET request with some additional data.

LISTING 25-15: Sending a GET request with data

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $.get("Listing%2025-13.ashx",
                  { a: 1, b: 2 },
                  function (result) {
                      $("div").text(result);
                  });
        });
    </script>
</head>
<body>
    <div></div>
</body>
</html>

So far, the data being returned by the GET request was a simple string. For more complex data, the de facto standard is to use JavaScript Object Notation (JSON, http://json.org/). Of course, it would be possible to load the JSON from the server as a string and then write user-land code to convert it to a JavaScript object, for instance with JavaScript’s built-in JSON.parse() method. However, it is even more convenient to use jQuery’s $.getJSON() method — it both does the HTTP request and parses the JSON result, as Listing 25-16 shows.


NOTE The $.get() method also supports parsing JSON. By default, jQuery tries to be clever: If it looks like JSON was returned, the data is parsed as JSON. If you want to explicitly state which data is expected to come back, you can provide the data type (for example, "json") as the last argument to the method call.

LISTING 25-16: Sending a GET request and parsing the returned JSON data

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $.getJSON("Listing%2025-13.ashx",
                  { json: "true" },
                  function (result) {
                      $("div").text(result);
                  });
        });
    </script>
</head>
<body>
    <div></div>
</body>
</html>

Sending a POST request seems to be very similar, but underneath the surface you will find out that the browser needs to send an additional HTTP header so that the server can parse the input data. Of course, jQuery can take care of all of this, if you are using the $.post() method. It works exactly as $.get(), except that POST is used instead of GET. Listing 25-17 sends a POST request to the server and displays the result; Figure 25-12 proves that POST was indeed used.

FIGURE 25-12

image

LISTING 25-17: Sending a POST request

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $.post("Listing%2025-13.ashx",
                   { a: 1, b: 2 },
                   function (result) {
                       $("div").text(result);
                   });
        });
    </script>
</head>
<body>
    <div></div>
</body>
</html>

$.get(),$.getJSON(), and $.post() are actually short-hand methods that internally just delegate the work to the generic Ajax method of jQuery: $.ajax(). This method expects two arguments: the URL to send the HTTP request to, and a hashtable containing additional options, like the HTTP verb to use, the callback function, and much more. As of jQuery 1.9.0, 33 different options are possible, so a complete list would be out of the scope of this chapter. However, Table 25-1 shows the most important ones.

TABLE 25-1

OPTION DESCRIPTION
contentType The content type HTTP header to be sent to the server.
Data Data to be sent to the server.
dataType Format of data expected back from the server (for example, "json" or "xml").
error Handler function in case the HTTP request fails.
success Handler function in case the HTTP request succeeds.
timeout Timeout value in milliseconds. After this amount of time has passed after sending the HTTP request without a result coming back from the server, the error handler function is executed.
type Request type like GET or POST.
url The URL to send the request to.

With this, it is possible to execute more complex HTTP requests. For instance, if an ASMX Web Service is used, the HTTP request to call it from Ajax (see also Chapter 23) needs to be very specific: An additional header must be set, and the return data has a specific format.

Listing 25-18 implements a simple ASMX service. Note how the System.Web.Script.Services.ScriptService attribute is used to make it callable via JavaScript. The ASMX service creates a list of “Link” objects. Each of those objects contains a link URL and a link text. Finally, the list is returned. The ASMX service automatically converts this data to JSON and returns it to the browser.

Listing 25-19 then calls this service using $.ajax() and parses the JSON object (which has actually been encapsulated in another JSON object, where the value of the "d" property contains the actual data returned). Then you create one list item (<li> HTML element) per link and append it to the page. Figure 25-13 shows the result in the browser.

FIGURE 25-13

image

LISTING 25-18: An ASMX service to be consumed via Ajax

VB

<%@ WebService Language="VB" Class="Listing_25_18" %>
 
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
 
<System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
Public Class Listing_25_18
    Inherits System.Web.Services.WebService
    
    <WebMethod()> _
    Public Function getLinks() As List(Of Link)
        Dim links = New List(Of Link)()
        links.Add(New Link With {.Url = "http://jquery.com/", .Text = "jQuery"})
        links.Add(New Link With {.Url = "http://jqueryui.com/", .Text = "jQuery UI"})
        links.Add(New Link With {.Url = "http://juiceui.com/", .Text = "Juice UI"})
        Return links
    End Function
    
End Class
 
Public Class Link
    Private _url As String
    Public Property Url() As String
        Get
            Return _url
        End Get
        Set(ByVal value As String)
            _url = value
        End Set
    End Property
 
    Private _text As String
    Public Property Text() As String
        Get
            Return _text
        End Get
        Set(ByVal value As String)
            _text = value
        End Set
    End Property
 
End Class

C#

<%@ WebService Language="C#" Class="Listing_25_18" %>
 
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Collections.Generic;
 
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class Listing_25_18  : System.Web.Services.WebService {
 
    [WebMethod]
    public List<Link> getLinks() {
        var links = new List<Link>() {
            new Link() { Url="http://jquery.com/", Text="jQuery"},
            new Link() { Url="http://jqueryui.com/", Text="jQuery UI"},
            new Link() { Url="http://juiceui.com/", Text="Juice UI"}
        };
        return links;
    }
    
}
 
public class Link
{
    public string Url { get; set; }
    public string Text { get; set; }
}

LISTING 25-19: Sending a POST request

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
<html>
<head runat="server">
    <title>jQuery</title>
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $.ajax({
                url: "Listing%2025-18.asmx/getLinks",
                contentType: "application/json",
                dataType: "json",
                type: "POST",
                success: function (result) {
                    var links = result.d;
                    $.each(links, function (key, value) {
                        $("<li>").append(
                            $("<a>").attr("href", value.Url).text(value.Text)
                        ).appendTo("ul");
                    });
                }
            });
        });
    </script>
</head>
<body>
    <ul></ul>
</body>
</html>

JQUERY UI

So far you have “just” worked with JavaScript features of jQuery, but you still have to actually code behaviors and the user interface. However, there is a sister project of jQuery called jQuery UI, with its homepage at http://jqueryui.com/. It describes itself as “a curated set of user interface interactions, effects, widgets, and themes.” And indeed: The feature set of jQuery UI is not huge, but the quality is very high. Think of jQuery UI to jQuery as ASP.NET Web Controls to ASP.NET: The latter is the framework, and the former builds upon that framework to provide UI controls. This section briefly demonstrates one of the widgets to show the general approach for using the library.

When you look at the top-right corner of the jQuery UI homepage (see Figure 25-14), you see that you can download the full jQuery UI package (we usually recommend the “stable” version), or you can click Custom Download and then pick only those components you need (Figure 25-15). For the sake of simplicity, this example uses the full package. You can also use the package manager to install jQuery UI. Listing 25-20 installs the complete package.

FIGURE 25-14

image

FIGURE 25-15

image

LISTING 25-20: Installing jQuery UI using NuGet

Install-Package jQuery.UI.Combined

WARNING The jQuery UI NuGet package also installs jQuery. Shortly after a new jQuery release, the jQuery UI package might reference an outdated jQuery version, so installation might fail. In that case, we recommend a manual installation.

Depending on how you install jQuery, some of the paths used later in this section may be different, so make sure you adapt the code to your local system. We assume that the jQuery and jQuery UI JavaScript files are residing in the Scripts folder, and the css folder of the jQuery UI distribution was placed in the website’s Content folder.

Using jQuery UI is really simple, because the widgets are completely integrated into the jQuery API. Essentially, you are first loading the jQuery library, then the jQuery UI library, and also the jQuery CSS file that is shipped with the package.

This is demonstrated in Listing 25-21 by using the datepicker control of jQuery UI. To do so, you place a simple textbox on the page. Then, you use $() to select this textbox. The returned jQuery object supports the datepicker() method, which you execute. And as Figure 25-16 shows, once you click into the textbox, the datepicker appears.

FIGURE 25-16

image

LISTING 25-21: Using the jQuery UI datepicker

<%@ Page Language="C#" %>
 
<!DOCTYPE html>
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link href="Content/css/smoothness/jquery-ui-1.10.0.custom.css" rel="stylesheet" />
    <script type="text/javascript" src="Scripts/jquery.js"></script>
    <script type="text/javascript" src="Scripts/jquery-ui-1.10.0.custom.js"></script>
    <script type="text/javascript">
        $(function () {
            $(".dp").datepicker();
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <input type="text" class="dp" />
    </div>
    </form>
</body>
</html>

As mentioned before, jQuery UI tries to achieve a similar thing as ASP.NET Web Controls. There is a way to combine both technologies. The Juice UI project has created web controls for each jQuery UI element. The project homepage is http://juiceui.com/ (Figure 25-17), and the installation is done via NuGet (see Listing 25-22).

FIGURE 25-17

image

LISTING 25-22: Installing Juice UI

Install-Package JuiceUI

Afterwards it’s quite easy to port Listing 25-21 to Juice UI: The <Juice:Datepicker> control represents the datepicker widget. Similar to the API of the Ajax Control Toolkit (see Chapter 24), the TargetControlID property is used to reference the textbox that receives the datepicker. Listing 25-23 shows the (short) code.

LISTING 25-23: Using the jQuery UI datepicker, with Juice UI

<asp:TextBox ID="TextBox1" runat="server" />
 
<Juice:Datepicker TargetControlID="TextBox1" runat="server" />

SUMMARY

This concludes your whirlwind tour through jQuery. This chapter discussed adding jQuery to a website or web application, and you then worked your way through the common approach for most Ajax applications: selecting elements, modifying them, listening to events, and doing Ajax requests. jQuery UI is jQuery’s widget library, which can be used as web controls thanks to the third-party Juice UI project.

There is a good reason why jQuery currently is the number one JavaScript library: It is compact, concise, easy to learn, yet powerful. Thanks to the good integration into Visual Studio (including the VSDOC files provided), no one really misses the Microsoft Ajax Library. Maybe, one day, its remains — currently still in heavy use by the controls introduced in Chapter 23 — will be replaced, too.