CHAPTER 9

image

jQuery AJAX

AJAX (Asynchronous JavaScript and XML) is a JavaScript-based communication technique between the client (browsers) and the server (web servers) that can be used with other technologies like jQuery, JavaScript, HTML5, and CSS3 to create faster, dynamic, user-friendly, and highly interactive web sites. Conventional web applications are synchronous, which means when users submit a form or send a request for information, they have to wait for the server to complete the process and send the information back to the browser. When the information is received by the browser, the complete page is refreshed with the updated information. In the case of web applications developed using AJAX, while users are working on a web page, data entered by the user or request for the new information is sent to the server seamlessly without any interruption in the workflow. When data is returned from the web server, only a portion of the web page is updated with the new information. Figure 9-1 displays the request and response flow between the client and the server in a conventional web application.

9781430264330_Fig09-01.jpg

Figure 9-1. Request and response model of a conventional web application

Figure 9-2 displays the request and response flow between the client and the server via jQuery AJAX APIs and the AJAX engine in a web application.

9781430264330_Fig09-02.jpg

Figure 9-2. Request and response model of the web application using AJAX

The advantages of using AJAX are:

  • Reduced network bandwidth use because only a portion of the page is refreshed instead of the complete page.
  • Highly interactive web pages.
  • Better user experience.
  • Increased productivity.
  • Eliminates the need for writing different code for different browsers.

The disadvantages are:

  • Dependency on enabling JavaScript settings in the browsers.
  • Additional JavaScript code on the client side to integrate returned data with HTML and CSS code.

The following are some examples of the web applications using AJAX:

  • Stock ticker web application whereby the latest market value of each stock is updated regularly without impacting the user’s interaction with the page.
  • Forms-based web application that contains fields like address. Based on the information entered by the user, a web page can provide the list of valid values for the other fields. For example, if a user enters/selects data in the State field, the browser can request all valid cities in the state by making an AJAX call to the server without any need to refresh the whole page and without losing or caching data already entered by the user.
  • Web applications that require complex data and business rules validations on the server side. While the user is entering the data, simultaneous calls can be made to the server to validate entered data. If there is any issue, it can be reported back to the user immediately instead of waiting for the user to submit the completed form.

jQuery AJAX methods make the code simpler and the web applications more interactive and dynamic. This chapter covers recipes that use jQuery AJAX-related methods and events to simplify the implementation of AJAX calls and processing of the returned data on the client (browser) side. It covers requesting and receiving the data in the following five formats—plain text, HTML, XML, JSON, and Script.

Since Chrome and Safari browsers have stricter security policies related to accessing local resources and different versions of Internet Explorer behave differently for AJAX calls, it’s best to test all the recipes in this chapter using the Firefox browser. In order to test on other browsers, deploy the code on a web server and then test them. Refer to the Appendix C for deploying web applications on Apache Tomcat and IIS.

You can monitor the content of the request, request header, response, and response header by opening the network tab of the browser’s developer tool or console.

9-1. Using jQuery AJAX API Calls to Get Plain Text Data from the Server

Problem

You want to use jQuery API calls to get plain text data from the server.

Solution

The following is the most commonly used syntax for making a jQuery AJAX API call:

$.ajax(settingsMapObject)

where, settingsMapObject is
     {
       type: "GET",
       url: "requestUrl",
       dataType: "text", // html, xml, json
       success: successCallbackFunction,
       error: errorCallbackFunction
     }

function successCallbackFunction(returnedData, status) { ... }
function errorCallbackFunction(request, status, errorMsg) { ... }

The available settings of an AJAX API call are outlined next.

The type Setting

type sets the type of the request (GET or POST) you are making to the server. Communication between clients and servers uses HTTP (Hypertext Transfer Protocol) by initiating requests from clients and getting back responses from servers. GET and POST are two commonly used request methods.

GET Request

  • Requests data from a specified URL resource
  • Has a limitation on length
  • Within a page a GET request can be specified as:
    <a href="http://domainName/resource?param1=paramVal1&param2=paramVal2">

POST Request

  • Submits data for processing to a specified URL resource
  • Has no length limit
  • Within a page a POST request can be specified as:
    <form method="POST" action="resourceURL">
        <!-- Data entry fields HTML form elements -->
    </form>

The url Setting

url sets the URL to which you are sending the request and expecting the response back. It can be relative to the current page or an absolute URL path. The URL can be either an absolute or relative path. Generally, the URL contains the resource name, which programmatically gets the data from some source (such as a database, file, business logic, and so on) and sends it back to the client (browser). Since writing server-side code is out of the scope of this book, all the recipes in this chapter use data files to provide the response content to the browser.  

If the current page and this URL have different domain names, the browser will throw an error about the cross-domain security. If you want to force a cross-domain request, set the crossDomain setting to true in the ajax() method.

The dataType Setting

The dataType setting sets the type of the data you are expecting back from the server. If it is not specified, the dataType from the Content-type in the response header will be used. The data type of the returnedData (the parameter in the success callback function) will be set as the specified data type.

The following are the commonly used data types:

  • text—Returns a plain text string.
  • xml—Returns an XML document.
  • html—Returns HTML as plaintext. Script tags will be executed when the HTML is added to the DOM.
  • json—Returns data in JSON format.

The success Setting

The success setting specifies which event handler (callback function) to execute when data is returned successfully from the server.

The error Setting

error specifies which event handler (callback function) to execute when there is an error while sending the request or upon getting the response back.

Other ajax() Settings

Some of the other less frequently used settings of the ajax() method include:

  • async—All AJAX requests are sent asynchronously (default). If this is set as false, the AJAX request will block the execution of the code and the user is not allowed to perform any action.
  • cache—This indicates whether to use the cached response (if available) or not. By default, it is true for all dataTypes except for script and jsonp. JSONP stands for “JSON with padding.” It is a way to get data from other domains by bypassing cross origin resource sharing rules.
  • timeout—This indicates after how many milliseconds a request is considered a failure if no response is received by that time.

Using the ajax() Method

Listing 9-1 demonstrates the use of the jQuery ajax() method to get text from the server and Listing 9-2 shows the employees.txt file.

Listing 9-1. Using the ajax() method to make an AJAX call to the server

<!DOCTYPE html>
<html lang="en">
<head>
     <meta charset="utf-8">
     <script src="scripts/jquery-2.1.0.min.js"></script>
     <style>
       div {
            border:3px double green;
            width: 300px;
            background-color: lightcyan;
       }

       table {
            border:0px;
       }

       td {
            padding-right: 10px;
            padding-left: 10px;
       }

       .header {
            font-weight: bold;
            background-color: lightgray;
       }

       .evenRow {
            background-color: lightyellow;
       }

       .oddRow {
            background-color: lightblue;
       }

       .errMsg {
             background-color: orange;
             color: white;
             font-weight: bold;
             width: 600px;
       }
     </style>

     <script>
          function processData(returnedData, status) {
            $("#ajaxStatusMessage").append("Status: " + status + "<br>");

            var records = returnedData.split(" ");
            for (var i=0; i<records.length; i++) {
              var fields = records[i].split(",");

              $("#tblEmployee").append("<tr><td>" + fields[0] +
                    "</td><td>" + fields[1] +
                    "</td><td>" + fields[2] + "</td></tr>");
            }

            $("tr").eq(0).addClass("header");
            $("tr:even:gt(0)").addClass("evenRow");
            $("tr:odd").addClass("oddRow");
          }

       function reportError(request, status, errorMsg) {
            $("#ajaxStatusMessage").append("Status: " + status + "<br>Error Message: " + errorMsg);
            $("#ajaxStatusMessage").addClass("errMsg");
       }


       $(function () {
            $.ajax({
              type: "GET",
              url: "employees.txt",
              dataType: "text",
              success: processData,
              error: reportError
            });
       });
     </script>
</head>

<body>
     <table id="tblEmployee"></table><br>
     <div id="ajaxStatusMessage"></div>
</body>
</html>

Listing 9-2. Content of the employees.txt file

Employee Name, Department, Salary
Jane Smith, Marketing, $95000
John Smith, Technology, $90000
Brian Adam, Sales, $72000
Mary Jones, Support, $60000
Michael Jefferson, Technology, $85000

How It Works

The HTML file with the AJAX call that’s loading a local file (for example, file:///C:/myWebApp/ajax.htm) can be viewed only in Firefox. Browsers like Chrome, Internet Explorer, and Safari have more restrictive default security features and they don’t permit local files to be loaded. To test with these browsers, you need to deploy the web application on a web server. Refer to the Appendix C for deploying a web application on Apache Tomcat and IIS.

In this code, after the DOM is ready, the following code is executed:

$.ajax({
         type: "GET",
         url: "employees.txt",
         dataType: "text",
         success: processData,
         error: reportError
         });

The jQuery ajax() method is executed with the following settings:

  • The request type is GET
  • The URL resource is employees.txt
  • The expected data type of the returned data is text
  • If sending the request and receiving the response is successful, execute the callback function processData
  • If there is an error sending the request or receiving the response, execute the callback function reportError

$.ajax() returns a jqXHR (jQuery XMLHttpRequest) object. jqXHR extends the browser’s native XMLHttpRequest object’s functionalities by adding properties and APIs to it. The .ajax() method call sets its properties and then returns it. It manages all the aspects of the request and the response, including a request header, data being sent to the server, callback function names, the status of the request, the response header from the server, and the data returned from the server. This object is also passed as an argument to most of the callback functions, such as success and error callback functions.

The ajax() method execution sends the request to the server asynchronously—the program execution doesn’t wait for the response to come back. When a response is received from the server, depending on the status, either processData or reportError is executed.

If there is a successful response, the processData() function is called. It executes the following code:

$("#ajaxStatusMessage").append("Status: " + status + "<br>");

       var records = returnedData.split(" ");
       for (var i=0; i<records.length; i++) {
              var fields = records[i].split(",");

       $("#tblEmployee").append("<tr><td>" + fields[0] +
              "</td><td>" + fields[1] +
              "</td><td>" + fields[2] + "</td></tr>");
         }

       $("tr").eq(0).addClass("header");
       $("tr:even:gt(0)").addClass("evenRow");
       $("tr:odd").addClass("oddRow");

The returnedData argument contains data from the response. $("#ajaxStatusMessage").append("Status: " + status + "<br>") appends the status message to the div tag with the ajaxStatusMessage ID.

var records = returnedData.split(" ") creates an array of records by splitting the returned data using a newline character as a delimiter. If you want to see the content of the records array, you can add the following line to your code, after the records variable is set:

console.dir(records)

console.dir(objName) displays the content of the specified object objName in the browser’s console. Figure 9-3 displays the content of the records array in the Firefox browser.

9781430264330_Fig09-03.jpg

Figure 9-3. Content of the records array

for (var i=0; i<records.length; i++) { ... } iterates over the each record specified in Figure 9-3.

var fields = records[i].split(",") creates an array of fields by splitting each record using , as a delimiter. If you want to see the content of the fields array, you can add the following line to your code, after the fields variable is set: console.dir(fields). Figure 9-4 displays the content of the fields array for the third element in the browser console.

9781430264330_Fig09-04.jpg

Figure 9-4. Content of the records array

$("#tblEmployee").append("<tr><td>" + fields[0] + "</td><td>" + fields[1] + "</td><td>" + fields[2] + "</td></tr>") builds the <tr> record for the table using elements from the fields array and appends it to the <table> with the ID tblEmployee.

After all the records are built and appended to the table, the following code is executed to set the CSS properties:

  • $("tr").eq(0).addClass("header")—For the first record, add the CSS class header.
  • $("tr:even:gt(0)").addClass("evenRow")—For all even-numbered rows that have an index of greater than 0, add the CSS class evenRow.
  • $("tr:odd").addClass("oddRow")—For all odd-numbered rows, add the CSS class oddRow.

Note that in this code, HTML and CSS are added using JavaScript on the client (browser) side. In a conventional web application, HTML and CSS are specified on the server side.

Figure 9-5 displays the page after data is returned from the server and after the HTML tags and CSS classes are added to the returned data.

9781430264330_Fig09-05.jpg

Figure 9-5. Data has been returned and formatted using HTML and CSS

If there is an error sending the request or receiving the response, the reportError() callback function is executed. It has the following arguments—request (which contains information about the request), status (which in this case is “error”), and errorMsg (which contains details about the error).

  • $("#ajaxStatusMessage").append("Status: " + status + "<br>Error Message: " + errorMsg) appends the status and error message to the div tag with the ID ajaxStatusMessage.
  • $("#ajaxStatusMessage").addClass("errMsg") adds the CSS class errMsg to the div tag.

In order to simulate an error, make a small change in the code in the Listing 9-1. Update the value of the url to employeeY.txt (for example) and view the page in the browser. Due to the error in the request, the error callback function will be executed and an error message will be displayed, as shown in the Figure 9-6.

9781430264330_Fig09-06.jpg

Figure 9-6. An error message is displayed

About the Convenience Methods

jQuery has provided some convenience (shorthand) methods that you can be use in place of using the ajax() method. For this recipe, you can replace the ajax() method call with the following convenience method:

$.get("employees.txt", processData, "text");

The following is the syntax for the .get() convenience method:

$.get(url, data, successCallbackFunction, dataType)

where data is the data you want to send to the server. In the current recipe, it is null and hence there is no need to pass it. successCallbackFunction is the callback function, and its called when there’s a successful response from the server. The data, successCallbackFunction, and dataType arguments are optional. You can handle error conditions by setting the global error handler using $(document).ajaxError(errorHandler). These are covered in Recipes 9-9 and 9-10.

Handling Runtime Errors

JavaScript runtime errors are not reported in the Firefox console log if the error is in the callback functions. In order to catch the runtime error, use JavaScript exception handling statement try {...} catch (error) {...}. Refer to Appendix D for details about implementing exception handling in your code.

9-2. Using jQuery AJAX API Calls to Get HTML Text from the Server

Problem

You want to use jQuery API calls to get HTML text from the server. This functionality can be used to get HTML code from various sources in order to display a complete view in a single HTML file.

Solution

Refer to Recipe 9-1 for the syntax for making a jQuery AJAX call. Listings 9-3 and 9-4 provide the changes to the code in Recipe 9-1 needed to demonstrate the use of the jQuery AJAX API ajax() method in order to get HTML content from the server. Listing 9-5 shows the employees.htm file.

Listing 9-3. Using the ajax() method to get HTML data: changes to the callback function of the success event

function processData(returnedData, status) {
     $("#ajaxStatusMessage").append("Status: " + status + "<br>");

     $("#tblEmployee").append(returnedData);
       }

Listing 9-4. Using the ajax() method to get HTML data: changes to the ajax() call

$.ajax({
  type: "GET",
  url: "employees.htm",
  dataType: "html",
  success: processData,
  error: reportError
});

Listing 9-5. Content of the employees.htm file

<table>
<tr class="header"><td>Employee Name</td><td>Department</td><td>Salary</td></tr>
<tr class="oddRow"><td>Jane Smith</td><td>Marketing</td><td>$95000</td></tr>
<tr class="evenRow"><td>John Smith</td><td>Technology</td><td>$90000</td></tr>
<tr class="oddRow"><td>Brian Adam</td><td>Sales</td><td>$72000</td></tr>
<tr class="evenRow"><td>Mary Jones</td><td>Support</td><td>$60000</td></tr>
<tr class="oddRow"><td>Michael Jefferson</td><td>Technology</td><td>$85000</td></tr>
</table>

How It Works

After the DOM is ready, the following code is executed:

$.ajax({
       type: "GET",
       url: "employees.htm",
       dataType: "html",
       success: processData,
       error: reportError
});

The jQuery ajax() method is executed with the following settings:

  • Request type is GET
  • URL resource is employees.htm
  • Expected data type of the returned data is html
  • If sending the request and receiving the response is successful, execute the callback function processData
  • If there is an error sending the request or receiving the response, execute the callback function reportError

The ajax() method execution sends the request to the server asynchronously. When a response is received from the server, depending on the status, the processData or reportError callback function is executed.

If there is a successful response, the processData() function will be called, and it will execute the following code:

$("#ajaxStatusMessage").append("Status: " + status + "<br>");

       $("#tblEmployee").append(returnedData);

$("#ajaxStatusMessage").append("Status: " + status + "<br>") appends the status message to the div tag with the ajaxStatusMessage ID.

$("#tblEmployee").append(returnedData) appends the returned HTML data to the <table> with the tblEmployee ID.

Figure 9-5 displays the page after the data is returned from the server and appended to the <table> tag. Figure 9-6 displays the error message when an error occurs when sending the request to the server or when receiving the response from the server.

For this recipe, you can replace the ajax() method call using the following convenience method:

$.get("employees.htm", processData, "html");

There is another convenience method called load() that attaches the HTML data directly to the specified selector:

$("#tblEmployee").load("employee.htm");

In this case, you don’t have to define a success callback function like processData. The following is the syntax to use the load() method:

load(url, data, completeCallbackFunction)
load(url, data, function(returnedData, status) {...})

where data is the data you want to send to the server. In the current recipe, it is null and hence there is no need to pass it. completeCallbackFunction is the callback function that’s executed upon completing the request. returnedData is the data returned from the server and status is the status of the request and the response. data and completeCallbackFunction are optional arguments.

9-3. Using jQuery AJAX API Calls to Get Data in XML Format from the Server

Problem

You want to use jQuery API calls to get data in XML format from the server.

Solution

Refer to Recipe 9-1 for the syntax of making a jQuery AJAX call. Listings 9-6 and 9-7 shows the changes to the code in Recipe 9-1 needed to demonstrate the use of the jQuery AJAX API ajax() method to get employees data in the XML format from the server. Listing 9-8 shows the employees.xml file.

Listing 9-6. Using the ajax() method to get XML data: changes to the callback function for the success event

function processData(returnedData, status) {
$("#ajaxStatusMessage").append("Status: " + status + "<br>");

var tableRecord="";

$("#tblEmployee").append("<tr><td>Employee Name</td><td>Department</td><td>Salary</td>");

$(returnedData).find('employee').each(function(){
  $("#tblEmployee").append(
    "<tr><td>" + $(this).find("employeeName").text() +
    "</td><td>" + $(this).find("department").text() +
    "</td><td>" + $(this).find("salary").text() + "</td></tr>");

  });

$("tr").eq(0).addClass("header");
$("tr:even:gt(0)").addClass("evenRow");
$("tr:odd").addClass("oddRow");
}

Listing 9-7. Using the ajax() method to get XML data: changes in the ajax() call

$.ajax({
     type: "GET",
     url: "employees.xml",
     dataType: "xml",
     success: processData,
     error: reportError
});

Listing 9-8. Content of the employees.xml file

<employees>
     <employee>
       <employeeName>Jane Smith</employeeName>
       <department>Marketing</department>
       <salary>$95000</salary>
     </employee>

     <employee>
       <employeeName>John Smith</employeeName>
       <department>Technology</department>
       <salary>$90000</salary>
     </employee>

     <employee>
       <employeeName>Brian Adam</employeeName>
       <department>Sales</department>
       <salary>$72000</salary>
     </employee>

     <employee>
       <employeeName>Mary Jones</employeeName>
       <department>Support</department>
       <salary>$60000</salary>
     </employee>

     <employee>
       <employeeName>Michael Jefferson</employeeName>
       <department>Technology</department>
       <salary>$85000</salary>
     </employee>
</employees>

How It Works

After the DOM is ready, the following code is executed:

$.ajax({
         type: "GET",
         url: "employees.xml",
         dataType: "xml",
         success: processData,
         error: reportError
});

The jQuery ajax() method is executed with the following settings:

  • The request type is GET
  • The URL resource is employees.xml
  • The expected data type of the returned data is xml
  • If sending the request and receiving the response is successful, execute the callback function processData
  • If there is an error sending the request or receiving the response, execute the callback function reportError

The ajax() method execution sends the request to the server asynchronously. When a response is received from the server, depending on the status, the processData or reportError callback function is executed.

If there is a successful response, the processData() function will be executed, which will in turn execute the following code:

$("#ajaxStatusMessage").append("Status: " + status + "<br>");

 var tableRecord="";

  $("#tblEmployee").append("<tr><td>Employee Name</td><td>Department</td><td>Salary</td>");

  $(returnedData).find('employee').each(function(){
     $("#tblEmployee").append(
         "<tr><td>" + $(this).find("employeeName").text() +
         "</td><td>" + $(this).find("department").text() +
         "</td><td>" + $(this).find("salary").text() + "</td></tr>");

  });

  $("tr").eq(0).addClass("header");
  $("tr:even:gt(0)").addClass("evenRow");
  $("tr:odd").addClass("oddRow");

Note the following items about this code example:

  • $("#ajaxStatusMessage").append("Status: " + status + "<br>") appends the status message to the div tag with the ajaxStatusMessage ID.
  • $("#tblEmployee").append("<tr><td>Employee Name</td><td>Department</td><td>Salary</td>") appends the table header to the <table> tag.
  • $(returnedData).find('employee').each(function(){...}); finds all the <employee> nodes and iterates over each <employee> node in the XML document.
  • $(this).find("employeeName").text() within the <employee> node finds the <employeeName> node and gets its text.
  • $(this).find("department").text() within the <employee> node finds the <department> node and gets its text.
  • $(this).find("salary").text() within the <employee> node finds the <salary> node and gets its text.
  • $("#tblEmployee").append("<tr><td>" + $(this).find("employeeName").text() + "</td><td>" + $(this).find("department").text() + "</td><td>" + $(this).find("salary").text() + "</td></tr>") builds the <tr> record for the table using the text() of the respective XML nodes and appends it to the <table> with the id tblEmployee ID.
  • After all the records are built and appended to the table, classes are added to the table records to change their CSS properties. Refer to Recipe 9-1 for the code explanation.

Figure 9-5 displays the page after the data is returned from the server and appended to the <table> tag. Figure 9-6 displays the error message if an error occurs while sending the request to the server or while receiving the response from the server.

For this recipe, you can replace the ajax() method call with the following convenience method:

$.get("employees.xml", processData, "xml");

9-4. Using jQuery AJAX API Calls to Get Data in the JSON Format from the Server

Problem

You want to use jQuery API calls to get data in the JSON format from the server.

Solution

Refer to Recipe 9-1 for the syntax of making a jQuery AJAX call. Listings 9-9 and 9-10 provide the changes to the code in Recipe 9-1 to demonstrate the use of the jQuery AJAX API ajax() method to get the employees data in the JSON format from the server. Listing 9-11 shows the employees.json file.

Listing 9-9. Using the ajax() method to get JSON data: changes to the callback function for the success event

function processData(returnedData, status) {
$("#ajaxStatusMessage").append("Status: " + status + "<br>");

console.dir(returnedData);

var tableRecord="";

$("#tblEmployee").append("<tr><td>Employee Name</td><td>Department</td><td>Salary</td>");

for (var i=0; i < returnedData.employees.length; i++) {
     var employee = returnedData.employees[i];

     $("#tblEmployee").append("<tr><td>" + employee.employeeName +
            "</td><td>" + employee.department +
            "</td><td>" + employee.salary + "</td></tr>");
}

$("tr").eq(0).addClass("header");
$("tr:even:gt(0)").addClass("evenRow");
$("tr:odd").addClass("oddRow");
}

Listing 9-10. Using the ajax() method to get JSON data: changes to the callback function for the success event

$.ajax({
    type: "GET",
    url: "employees.json",
    dataType: "json",
    success: processData,
    error: reportError
});

Listing 9-11. Content of the employees.json file

{
  "employees":
   [
     {"employeeName":"Jane Smith", "department":"Marketing", "salary":"$95000"},
     {"employeeName":"John Smith", "department":"Technology", "salary":"$90000"},
     {"employeeName":"Brian Adam", "department":"Sales", "salary":"$72000"},
     {"employeeName":"Mary Jones", "department":"Support", "salary":"$60000"},
     {"employeeName":"Michael Jefferson", "department":"Technology", "salary":"$85000"}
   ]
}

How It Works

After the DOM is ready, the following code is executed:

$.ajax({
         type: "GET",
         url: "employees.json",
         dataType: "json",
         success: processData,
         error: reportError
       });

The jQuery ajax() method is executed with the following settings:

  • The request type is GET
  • The URL resource is employees.json
  • The expected data type of the returned data is json
  • If sending the request and receiving the response is successful, execute the callback function processData
  • If there is an error sending the request or receiving the response, execute the callback function reportError

ajax() method execution sends the request to the server asynchronously. When a response is received from the server, depending on the status, the processData or reportError callback function is executed.

If there is a successful response, processData() function will be executed, which will in turn execute the following code:

$("#ajaxStatusMessage").append("Status: " + status + "<br>");

         console.dir(returnedData);

         var tableRecord="";

         $("#tblEmployee").append("<tr><td>Employee Name</td><td>Department</td><td>Salary</td>");

         for (var i=0; i < returnedData.employees.length; i++) {
              var employee = returnedData.employees[i];

              $("#tblEmployee").append("<tr><td>" + employee.employeeName +
                     "</td><td>" + employee.department +
                     "</td><td>" + employee.salary + "</td></tr>");
         }

         $("tr").eq(0).addClass("header");
         $("tr:even:gt(0)").addClass("evenRow");
         $("tr:odd").addClass("oddRow");

Where:

  • $("#ajaxStatusMessage").append("Status: " + status + "<br>") appends the status message to the Div tag with the ajaxStatusMessage ID.
  • If the returnedData is in string format, you can convert it to the JSON object by using the following syntax:
    var jsonObj = $.parseJSON(returnedData);
  • If you want to convert the JSON object to the string format for displaying or logging it, you can use the following syntax:
    var jsonString = JSON.stringify(jsonObj);
  • console.dir(returnedData) is used for debugging purposes only to see the structure of the returned data in the JSON format. Figure 9-7 displays the structure of the returned JSON data.$("#tblEmployee").append("<tr><td>Employee Name</td><td>Department</td><td>Salary</td>") appends the table header to the <table> tag.

    9781430264330_Fig09-07.jpg

    Figure 9-7. Structure of the returned JSON data

  • for (var i=0; i < returnedData.employees.length; i++) { . . . } iterates over each array element in the array of employees objects.
  • var employee = returnedData.employees[i] gets an employee record from the array.
  • employee.employeeName gets the employeeName property of the current employee record.
  • employee.department gets the department property of the current employee record.
  • employee.salary gets the salary property of the current employee record.
  • $("#tblEmployee").append("<tr><td>" + employee.employeeName + "</td><td>" + employee.department + "</td><td>" + employee.salary + "</td></tr>") builds the <tr> record for the table using the employeeName, department and salary property values and appends it to the <table> with the tblEmployee ID.
  • After all records are built and appended to the table, classes are added to the table records to change their CSS properties. Refer to Recipe 9-1 for the code explanation.

Figure 9-5 displays the page after the data is returned from the server and appended to the <table> tag. Figure 9-6 displays the error message if an error occurs while the request is being sent or the response is being received.

Convenience Methods

For this recipe, you can replace the ajax() method call with the following convenience method:

$.get("employees.json", processData, "json");

You can also use another convenience method that’s available specifically for the JSON data type:

$.getJSON("employees.json", processData);

The following is the syntax to use the getJSON() method:

$.getJSON( url, data, successCallbackFunction)

where data is the data you want to send to the server and successCallbackFunction is the function that’s executed if the response is received successfully. data and successCallbackFunction are optional arguments.

9-5. Using jQuery AJAX API Calls to Get the Script from the Server

Problem

You want to use jQuery API calls to get the script from the server. This feature is useful when the JavaScript logic is dependent on the user interaction or on certain criteria that’s known at runtime. Instead of adding complex JavaScript code to the HTML file, the server can deliver the script to the browser at runtime.

Solution

Refer to Recipe 9-1 for the syntax of making a jQuery AJAX call. Listings 9-12 and 9-13 provide the changes to the code in Recipe 9-1 to demonstrate the use of the jQuery AJAX API ajax() method to get the script from the server. Listing 9-11 provides the content of the employees.json file. In the success callback function, another AJAX call is made by using the convenience method $.getScript(), which gets the JavaScript code from the server and executes it. Listing 9-14 shows the JavaScript code in the employees.js file.

Listing 9-12. Using the ajax() method to get JSON data and getScript() to get JavaScript code: changes to the callback function for the success event

function processData(returnedData, status) {
      $("#ajaxStatusMessage").append("Status: " + status + "<br>");

         var tableRecord="";

         $("#tblEmployee").append("<tr><td>Employee Name</td><td>Department</td><td>Salary</td>");

         for (var i=0; i < returnedData.employees.length; i++) {
              var employee = returnedData.employees[i];

              $("#tblEmployee").append("<tr><td>" + employee.employeeName +
                           "</td><td>" + employee.department +
                      "</td><td>" + employee.salary + "</td></tr>");
          }

          $.getScript("employees.js");
       }

Listing 9-13. Using the ajax() method to get JSON data and getScript() to get the JavaScript code: changes to the ajax() call

$.ajax({
  type: "GET",
  url: "employees.json",
  dataType: "json",
  success: processData,
  error: reportError
});

Listing 9-14. Content of the employees.js file

$("tr").eq(0).addClass("header");
$("tr:even:gt(0)").addClass("evenRow");
$("tr:odd").addClass("oddRow");

How It Works

Refer to Recipe 9-4 for the ajax() call code explanation for the JSON dataType and for the success callback function. In the processData() success callback function, another AJAX call gets the script by using the $.getScript("employees.js") code. The getScript method gets the JavaScript code from the server and executes it.

Figure 9-5 displays the page after the data is returned from the server and appended to the <table> tag. Figure 9-6 displays an error message if an error occurs when sending the request or when receiving the response.

9-6. Sending Data to the Server Using a GET Request Method

Problem

You want to use jQuery API calls to send data to the server so that the server can send the information back, based on the data received with the request.  

Solution

The following is syntax to send data to the server using the GET request method:

$.ajax(settingsMapObject)

where, settingsMapObject is
     {
       type: "GET",
       url: "requestUrl",
       data: "param1=paramValue1& param2=paramValue2&...",
       dataType: "text", // html, xml, json
       success: successCallbackFunction,
       error: errorCallbackFunction
     }

function  successCallbackFunction(returnedData, status) { ... }
function  errorCallbackFunction(request, status, errorMsg) { ... }

The data is the data to be sent to the server. Its value can be either a string in the querystring format, such as "param1=paramValue1&param2=paramValue2,...", or the map object in the key/value pairs form {param1:'paramValue1', param2:'paramValue2', ...}. If any parameter has multiple values, the same parameter name can be specified multiple times with the different parameter values. While sending the request to the server, the URL gets converted to requestUrl?param1=paramValue1& param2=paramValue2&...

If the data you want to send to the server is contained in form fields, you can use jQuery helper function serialize() to convert the form’s elements value to the query string format. Listing 9-15 provides an example to send form data to the server in the querystring format. Since server side coding to filter the data, based on the passed value, is out of the scope of this chapter, this recipe will get the response back from a file instead of from a processing resource (web service) on the server side. Listing 9-11 provides the content of the employees.json file.

Listing 9-15. Using the ajax() method to make an AJAX call with data using the GET request method

<!DOCTYPE html>
<html lang="en">
<head>
     <meta charset="utf-8">
     <script src="scripts/jquery-2.1.0.min.js"></script>
     <style>
       div {
            border:3px double green;
            width: 500px;
            background-color: lightcyan;
       }

       form {
            border:3px double green;
            width: 400px;
            padding: 20px;
            background-color: lightyellow;
       }

       table {
            border:0px;
       }

       td {
            padding-right: 10px;
            padding-left: 10px;
       }

       label {
            float:left;
            display:block;
            width: 250px;
            font-weight: bold;
       }

       .header {
            font-weight: bold;
            background-color: lightgray;
       }

       .evenRow {
            background-color: lightyellow;
       }

       .oddRow {
            background-color: lightblue;
       }

       .errMsg {
             background-color: orange;
             color: white;
             font-weight: bold;
             width: 600px;
       }
     </style>

     <script>
         function processData(returnedData, status) {
             $("#ajaxStatusMessage").append("Status: " + status + " <br>");

             var tableRecord="";
             var enteredDepartment = $("#txtDepartment").val().toLowerCase().trim();
             var enteredSalary = 0;

                 if ($("#txtSalary").val() != "") {
                 enteredSalary = parseFloat($("#txtSalary").val());
             }


            $("#tblEmployee").append("<tr><td>Employee Name</td><td>Department</td><td>Salary</td>");

            for (var i=0; i < returnedData.employees.length; i++) {
              var employee = returnedData.employees[i];

              var salary = parseFloat(employee.salary.replace("$",""));
              var department = employee.department.toLowerCase().trim();

               // Filter records
               if (salary >=enteredSalary && (enteredDepartment == "" || enteredDepartment == department)) {
                  $("#tblEmployee").append("<tr><td>" + employee.employeeName +
                      "</td><td>" + employee.department +
                      "</td><td>" + employee.salary + "</td></tr>");
               }
            }

            $("tr").eq(0).addClass("header");
            $("tr:even:gt(0)").addClass("evenRow");
            $("tr:odd").addClass("oddRow");
       }

       function reportError(request, status, errorMsg) {
            $("#ajaxStatusMessage").append("Status: " + status + "<br>Error Message: " + errorMsg);
            $("#ajaxStatusMessage").addClass("errMsg");
       }

       $(function () {
            $("#btnSubmit").click( function (eventObj) {
              eventObj.preventDefault();

              $.ajax({
                   type: "GET",
                   url: "employees.json",
                   data: $("form").serialize(),
                   dataType: "json",
                   success: processData,
                   error: reportError
              });

              $("#ajaxStatusMessage").append("Parameter Sent to the server: " + $("form").serialize() + "<br>");

            });
       });
     </script>
</head>

<body>
     <h4>Employee Search Criteria:</h4>
     <form id="frmSearch">
       <label for="txtDepartment">Department Name:</label>
       <input type="text" id="txtDepartment" name="txtDepartment"><br>

       <label for="txtSalary">Salary (greater than or equal to):</label>
       <input type="text" id="txtSalary" name="txtSalary"><br><br>

       <button id="btnSubmit">Submit</button>
     </form><br><br>

     <div id="ajaxStatusMessage"></div><br>

     Search Result:
     <table id="tblEmployee"></table><br><br>
</body>
</html>

How It Works

In this example, filtering is done at the client side in the JavaScript code. In the real-world application, filtering logic is implemented on the server side to reduce the network traffic between the server and the browser. Since server side coding is out of the scope of this book, this example uses client-side filtering.

Most of the code in these listings is explained in Recipe 9-4. The following are the only differences:

  • An AJAX call is made when the Submit button is clicked.
  • eventObj.preventDefault() is used to prevent the default form’s submission process.
  • data: $("form").serialize() is passed as a setting for the ajax() call. $("form").serialize() converts the form’s data entry elements in the querystring form, i.e., in the form txtDepartment=Technology&txtSalary=80000 if the data entered for the Department field is Technology and the Salary is 80,000. One point to remember is that form elements (such as input, select, and so on) will be used to build the querystring only if their name attribute is set.

    If you want to send data from few elements only instead of sending all data entry form fields, you can use the following syntax:

    $(selector).serialize()

    If you want to convert data from an object or an array into a querystring format, you can use the helper function $.param(objName). For example,

    var mapObj = {employeeName: "John Smith",  department: "Technology"};

    can be converted to a querystring by using:

    var querystring = $.param(mapObj)

    The value of the querystring will be:

    employeeName=John+Smith&department=Technology
  • The div tag with the ID ajaxStatusMessage is set to display the data being passed to the server.

Figure 9-8 displays the initial page when displayed in the browser.

9781430264330_Fig09-08.jpg

Figure 9-8. Displaying the initial page

Figure 9-9 displays the page when the Department name is Technology, the Salary is 85,000, and the Submit button is clicked.

9781430264330_Fig09-09.jpg

Figure 9-9. Displaying the search result

9-7. Sending Form Data to the Server Using a POST Request Method

Problem

You want to use jQuery API calls to send data to the server so that server can process the data and/or save it.

Solution

The following is syntax to send form data to the server using the POST request method:

$.ajax(settingsMapObject)

where, settingsMapObject is
     {
       type: "POST",
       url: "requestUrl",
       data: $(form).serializeArray(),
       dataType: "text",
       success: successCallbackFunction,
       error: errorCallbackFunction
     }

function  successCallbackFunction(returnedData, status) { ... }
function  errorCallbackFunction(request, status, errorMsg) { ... }

If the data you want to send to the server is contained in form fields, you can use jQuery helper function serializeArray() to convert the form’s elements’ values to an array of names and values, as so:

[ {name: "formFieldName1", value: "formFieldValue1"},
  {name: "formFieldName2", value: "formFieldValue2"},
.....]

Name/value pairs are sent in the HTTP message body for the POST request method. GET requests have length restrictions where as POST requests have no data length restrictions. POST requests are more secure than the GET method because name value pairs cannot be cached, bookmarked, saved in the browser history, or logged in the server logs. Listing 9-16 demonstrates the use of the POST request method and the use of the jQuery method serializeArray() to get the form’s data to be sent to the server. Listing 9-17 displays the content of the file createNewEmployee.json. In real-world applications, the request is sent to the processing resource (web service) on the server side. An appropriate status, based on the processing result, is sent back as a response.

Listing 9-16. Using the ajax() method to send form data using the POST request method

<!DOCTYPE html>
<html lang="en">
<head>
     <meta charset="utf-8">
     <script src="scripts/jquery-2.1.0.min.js"></script>
     <style>
       div {
            border:3px double green;
            width: 400px;
            background-color: lightcyan;
            padding: 10px;
       }

       form {
            border:3px double green;
            width: 400px;
            padding: 20px;
            background-color: lightyellow;
       }

       table {
            border:0px;
       }

       td {
            padding-right: 10px;
            padding-left: 10px;
       }

       label {
            float:left;
            display:block;
            width: 175px;
            font-weight: bold;
       }

       .header {
            font-weight: bold;
            background-color: lightgray;
       }

       .evenRow {
            background-color: lightyellow;
       }

       .oddRow {
            background-color: lightblue;
       }

       .errMsg {
             background-color: orange;
             color: white;
             font-weight: bold;
             width: 400px;
       }
     </style>

     <script>
       function processData(returnedData, status) {
            $("#ajaxStatusMessage").append("Status: " + status + "<br>");

            if (returnedData.processingStatus == "Successful") {
              $("#processingResult").append("New employee record is created successfully.");
            } else {
              $("#processingResult").append("Failed to create new employee record.");
              $("#processingResult").addClass("errMsg");
           }
       }

       function reportError(request, status, errorMsg) {
            $("#ajaxStatusMessage").append("Status: " + status + "<br>Error Message: " + errorMsg);
            $("#ajaxStatusMessage").addClass("errMsg");
       }

       $(function () {
            $("#btnCreateNew").click( function (eventObj) {
              eventObj.preventDefault();

              $.ajax({
                   type: "POST",
                   url: "createNewEmployee.json",
                   data: $("form").serializeArray(),
                   dataType: "json",
                   success: processData,
                   error: reportError
              });

              var fields = "";
              $.each( $("form").serializeArray(), function( i, field ) {
                   fields += "[Key: " + field.name + " Value: " + field.value + "]<br>";
              });

              $("#ajaxStatusMessage").append("Data Sent to the server: <br>" + fields + "<br>");

            });
       });
     </script>
</head>

<body>
     <h4>New Employee:</h4>
     <form id="frmSearch">
       <label for="txtEmployeeName">Employee's Name:</label>
       <input type="text" id="txtEmployeeName" name="txtEmployeeName"><br>

       <label for="txtDepartment">Department Name:</label>
       <input type="text" id="txtDepartment" name="txtDepartment"><br>

       <label for="txtSalary">Salary (greater than):</label>
       <input type="text" id="txtSalary" name="txtSalary"><br><br>

       <button id="btnCreateNew">Create New Employee Record</button>
     </form><br><br>

     <div id="ajaxStatusMessage"></div><br>

     Processing Result:
     <div id="processingResult"></div><br><br><br>
</body>
</html>

Listing 9-17. Content of the createNewEmployee.json file

{"processingStatus": "Successful"}

How It Works

If Create New Employee Record is clicked after the DOM is created, the following code is executed:

eventObj.preventDefault();
  $.ajax({
       type: "POST",
       url: "createNewEmployee.json",
       data: $("form").serializeArray(),
       dataType: "json",
       success: processData,
       error: reportError
});

var fields = "";
$.each( $("form").serializeArray(), function( i, field ) {
     fields += "[Key: " + field.name + " Value: " + field.value + "]<br>";
});

$("#ajaxStatusMessage").append("Data Sent to the server: <br>" + fields + "<br>");

Where:

  • eventObj.preventDefault() is used to prevent the default form’s submission process.
  • type: "POST" specifies that you want to send the request as POST.
  • data: $("form").serializeArray() serializes the form data-entry elements as an array with name/value pairs. In order to get the value of the data-entry form elements, elements should have a name attribute and a value.

If you want to send data from a few elements only instead of sending all the data-entry form fields, you can use the following syntax:

$(selector).serializeArray()

If you want to convert data from an object or an array into a querystring format, you can use the helper function $.param(objName). For example:

var mapObj = {employeeName: "John Smith",  department: "Technology"};

can be converted to a querystring by using:

var querystring = $.param(mapObj)

The value of the querystring will be:

employeeName=John+Smith&department=Technology

You can use any of the jQuery helper functions—$.param(mapObj), $.param(arrayObj), $(selector).serialize(), and $(selector).serializeArray()—to set the data in the ajax() method for the GET and POST request methods.

$.each( $("form").serializeArray(), function( i, field ) {
     fields += "[Key: " + field.name + " Value: " + field.value + "]<br>";
});

$("#ajaxStatusMessage").append("Data Sent to the server: <br>" + fields + "<br>");

This code iterates over the name/value pairs in the array, sets the fields variable with the pairs values, and displays it on the page.

When there is a successful response from the server, the processData() callback function is executed with the following code:

 $("#ajaxStatusMessage").append("Status: " + status + "<br>");

 if (returnedData.processingStatus == "Successful") {
   $("#processingResult").append("New employee record is created successfully.");
 } else {
   $("#processingResult").append("Failed to create new employee record.");
   ("#processingResult").addClass("errMsg");
}

Where:

  • $("#ajaxStatusMessage").append("Status: " + status + "<br>") displays the response status on the page.
  • If the returned JSON object (returnedData) has the processingStatus as "Successful", the message "New employee record is created succesfully" is displayed on the page; otherwise, "Failed to create new employee record." is displayed.

Figure 9-10 displays the initial page when displayed in the browser.

9781430264330_Fig09-10.jpg

Figure 9-10. Displaying the initial page

Figure 9-11 displays the page after new employee’s information is entered and the Create New Employee Record button is clicked.

9781430264330_Fig09-11.jpg

Figure 9-11. Displaying the data sent to the server and the successful response back from the server

For this recipe, you can replace the  ajax() method call with the following convenience method:

$.post("createNewEmployee.json",
                        $("form").serializeArray(),
                         processData,
                         "json");

   The following is the syntax for the post() convenience method:

$.post(url, data, successCallbackFunction, dataType)

where data is the data you want to send to the server. successCallbackFunction is the callback function that will be called when there’s a successful response from the server. The data, successCallbackFunction, and dataType arguments are optional. You can handle error conditions by setting the global error handler using ajaxError(errorHandler). These are covered in Recipes 9-9 and 9-10.

9-8. Using AJAX Events at the Request Level

Problem

You want to know how to use AJAX events at the request level.

Solution

The following is the list of events that you can handle at various stages of the AJAX request and response process. These events are triggered in the order specified in the following list:

  • beforeSend —This event is triggered before the AJAX request is started. jqXHR and settings are the arguments to the beforeSend callback function. This event allows you to make changes to the request settings before it is sent to the server. If a false is returned from the callback function, the request will be cancelled.

    For example, the following callback function (event handler) can be used to set the value of the URL based on the outcome of some processing logic:

    $.ajax({
         ....
         beforeSend: function(jqXHR, settings) {
         // Processing logic
         settings.url = "/process.asmx";
         }
    });
  • dataFilter—This event is triggered only if the request is successful. The raw data (as a string) is returned from the server and the dataType are the arguments to the dataFilter callback function. In the callback function you can clean up the data and return updated data.
    $.ajax({
         ....
         dataFilter: function(returnedData, dataType) {
         // Processing logic to update returnedData
         var updatedData = returnedData;
         return(updatedData);
         }
    });
  • success—This event is triggered only if the request is successful. The returned data (in the specified dataType format)—status as string and jqXHR object—are the arguments to the success callback function. For this event, multiple callback functions can be specified as an array of functions. Each callback function will be executed in the order specified. The following is the syntax for specifying multiple callback functions:
    success: [function1, function2, ...]

    In the callback function of this event, you process the returned data from the server. Some examples are:

  • Create/update HTML elements and CSS properties
  • Make another AJAX call:
    $.ajax({
         ....
         success: function(returnedData, status, jqXHR) {
         // Processing logic
         $(selector).append(returnedData);
         }
    });
  • error—This event is triggered only if the request is failed. jqXHR object, status, and errorMessage are the arguments to the error callback function. Possible values for status are error, abort, timeout, and parsererror. For this event, multiple callback functions can be specified as an array of functions. Each callback function is executed in the order specified.

    In the callback function of this event, you can display a message to the user with the user-friendly error message or retry the AJAX call if timeout occurred.

    $.ajax({
               ....
               error: function(jqXHR, status, errorMessage) {
        // Display error message
        $(selector).append("Status: " + status + " Error Message: " + errorMessage);
              }
    });
  • complete—This event is triggered when request is completed. The jqXHR object and status are the arguments to the error callback function. Possible values for status are success, error, notmodified, abort, timeout, and parsererror. For this event, multiple callback functions can be specified as an array of functions. Each callback function is executed in the order specified.

    In the callback function of this event, you can display the progress bar as 100% completed to indicate that the request has completed successfully or has failed.

    $.ajax({
         ....
         complete: function(jqXHR, status) {
         // Display message
         $(selector).append("Processing completed with the status: " + status);
         }
    });

If you want to list an object’s properties and values, you can use the console.dir(objName) statement. This will display an object’s content in the browser.

You will use all of these request-level events in Recipe 9-10.

9-9. Using AJAX Events at the Global Level

Problem

You want to know how to use AJAX events at the global level.

Solution

The following is the list of global AJAX events that you can use at various stages of AJAX request and response process in the document. Callback functions for these events are at the document (web page) level. By default, global event handler are called for all AJAX requests on the page. To prevent execution of these global event handlers, you can set global options as false in the ajax() method:

$.ajax({
     ....
     global: false;
});
  • ajaxStart—This event is triggered when the first AJAX request is started and there is no active AJAX request in progress. If all the AJAX requests are completed and a new AJAX request is about to be sent, the ajaxStart event will be triggered again. The event object is the only argument passed to the ajaxStart event handler. The following syntax is used to register an ajaxStart event handler:
    $(document).on("ajaxStart", startCallbackFunction)
    or
    $(document). ajaxStart(startCallbackFunction)
  • jaxSend—This event is triggered before an AJAX request is sent. The event object, jqXHR, and settings object are the arguments passed to the ajaxSend event handler. The following syntax is used to register an ajaxSend event handler:
    $(document).on("ajaxSend", sendCallbackFunction)
    or
    $(document). ajaxSend(sendCallbackFunction)
  • ajaxSuccess—This event is triggered only if an AJAX request is successful. The event object, jqXHR, and settings object are the arguments passed to the ajaxSuccess event handler. The following syntax is used to register an ajaxSuccess event handler:
    $(document).on("ajaxSuccess", successCallbackFunction)
    or
    $(document). ajaxSuccess(succesCallbackFunction)
  • ajaxError—This event is triggered only if an AJAX request fails. The event object, jqXHR, settings object, and an error message are the arguments passed to the ajaxError event handler. The following syntax is used to register an ajaxError event handler:
    $(document).on("ajaxError", errorCallbackFunction)
    or
    $(document). ajaxError(errorCallbackFunction)
  • ajaxComplete—This event is triggered when an AJAX request is completed, regardless of whether the request has completed successfully or failed. The event object, jqXHR, and settings object are the arguments passed to the ajaxComplete event handler. The following syntax is used to register an ajaxComplete event handler:
    $(document).on("ajaxComplete", completeCallbackFunction)
    or
    $(document). ajaxComplete(completeCallbackFunction)
  • ajaxStop—This event is triggered when all AJAX requests are completed. The event object is the only argument passed to the ajaxStop event handler. After the ajaxStop event is triggered, if a new AJAX request is started, the whole cycle of events will restart beginning with ajaxStart. The following syntax is used to register an ajaxStop event handler:
    $(document).on("ajaxStop", stopCallbackFunction)
    or
    $(document). ajaxStop(stopCallbackFunction)

If you want to list an object’s properties and their values, you can use console.dir(objName). This will display an object’s content in the browser.

You will use all of these request-level events in Recipe 9-10.

9-10. Order of AJAX Events at the Request and Global Levels

Problem

You want to know the order in which AJAX events are triggered during the lifecycle of an AJAX request.

Solution

Listing 9-18 demonstrates the order of AJAX events triggering. It shows all the global and request-level events that are triggered for a successful AJAX request as well as for a failed AJAX request. This code listing has event handlers (with arguments) for all AJAX events triggered at the document and request levels. Listing 9-19 shows the testMessage.txt file.

Listing 9-18. The order of triggering AJAX events

<!DOCTYPE html>
<html lang="en">
<head>
     <meta charset="utf-8">
     <script src="scripts/jquery-2.1.0.min.js"></script>
     <script>
       // Global AJAX events callbacks
       function ajaxSuccessCallback(eventObj, jqXHR, settingsObj) {
            $("#status").append("Global event - ajaxSuccess.<br>");
       }

       function ajaxSendCallback(eventObj, jqXHR, settingsObj) {
            $("#status").append("Global event - ajaxSend.<br>");
       }

       function ajaxStartCallback(eventObj) {
            $("#status").append("Global event - ajaxStart.<br>");
       }

       function ajaxStopCallback(eventObj) {
            $("#status").append("Global event - ajaxStop.<br>");
       }

       function ajaxErrorCallback(eventObj, jqXHR, settingsObj) {
            $("#status").append("Global event - ajaxError.<br>");
       }

       function ajaxCompleteCallback(eventObj, jqXHR, settingsObj) {
            $("#status").append("Global event - ajaxComplete.<br>");
       }

       // AJAX events callbacks at the request level
       function requestBeforeSendCallback(jqXHR, settingsObj) {
            $("#status").append("Request event - beforeSend.<br>");
       }

       function requestCompleteCallback(jqXHR, status) {
            $("#status").append("Request event - complete.<br>");
       }

       function requestDataFilterCallback(returnedData, dataType) {
            $("#status").append("Request event - dataFilter.<br>");
       }

       function requestErrorCallback(jqXHR, status, errorMessage) {
            $("#status").append("Request event - error.<br>");
       }

       function requestSuccessCallback(returnedData, status, jqXHR) {
            $("#status").append("Request event - success.<br>");
       }

       $(function () {
            $(document).on("ajaxSend", ajaxSendCallback);
            $(document).on("ajaxSuccess", ajaxSuccessCallback);
            $(document).on("ajaxError", ajaxErrorCallback);
            $(document).on("ajaxComplete", ajaxCompleteCallback);
            $(document).on("ajaxStart", ajaxStartCallback);
            $(document).on("ajaxStop", ajaxStopCallback);

            $("#btnSuccess").click(function () {
              $("#status").empty();

              $.ajax(
                  {
                     type: "GET",
                     url: "testMessage.txt",
                     beforeSend: requestBeforeSendCallback,
                     complete: requestCompleteCallback,
                     dataFilter: requestDataFilterCallback,
                     error: requestErrorCallback,
                     success: requestSuccessCallback,
                     data: null,
                     dataType: "text"
                 });

            });

            $("#btnFailed").click(function () {
              $("#status").empty();

              $.ajax(
                   {
                     type: "GET",
                     url: "incorrect.txt",
                     beforeSend: requestBeforeSendCallback,
                     complete: requestCompleteCallback,
                     dataFilter: requestDataFilterCallback,
                     error: requestErrorCallback,
                     success: requestSuccessCallback,
                     data: null,
                     dataType: "text" //script: execute response as a script.
                   });
            });
       });
      </script>
</head>

<body>

     <button id="btnSuccess">Start Successful Ajax Call</button>
     <button id="btnFailed">Start Unsuccessful Ajax Call</button><br><br>

     <div id="status"></div>
</body>
</html>

Listing 9-19. Content of the testMessage.txt file

Test Message

How It Works

After the DOM is created, event handlers for all global-level AJAX events are registered by using the following code:

$(document).on("ajaxSend", ajaxSendCallback);
$(document).on("ajaxSuccess", ajaxSuccessCallback);
$(document).on("ajaxError", ajaxErrorCallback);
$(document).on("ajaxComplete", ajaxCompleteCallback);
$(document).on("ajaxStart", ajaxStartCallback);
$(document).on("ajaxStop", ajaxStopCallback);

When the Start Successful Ajax Call button is clicked, the following AJAX code is executed to register request-level event handlers for the events—beforeSend, complete, dataFilter, error, and success.

$.ajax(
    {
       type: "GET",
       url: "testMessage.txt",
       beforeSend: requestBeforeSendCallback,
       complete: requestCompleteCallback,
       dataFilter: requestDataFilterCallback,
       error: requestErrorCallback,
       success: requestSuccessCallback,
       data: null,
       dataType: "text"
  });

When the Start Unsuccessful Ajax Call button is clicked, the following AJAX code is executed to register request-level event handlers for the beforeSend, complete, dataFilter, error, and success events. The only difference in this case is the URL setting, which uses a filename that doesn’t exist. This is to simulate an error condition.

$.ajax(
    {
       type: "GET",
       url: " incorrect.txt",
       beforeSend: requestBeforeSendCallback,
       complete: requestCompleteCallback,
       dataFilter: requestDataFilterCallback,
       error: requestErrorCallback,
       success: requestSuccessCallback,
       data: null,
       dataType: "text"
  });

In all the registered event handlers, the div tag with the ID status is set to display the message with the name of the event handler being executed using the code. For example, $("#status").append("Request event - success.<br>").

Figure 9-12 displays the list of event handlers that are executed when the user clicks the Start Successful Ajax Call button.

9781430264330_Fig09-12.jpg

Figure 9-12. Displaying a list of events that occurred during a successful AJAX request

Figure 9-13 displays the list of event handlers that are executed when the user clicks the Start Unsuccessful Ajax Call button.

9781430264330_Fig09-13.jpg

Figure 9-13. Displaying a list of events that occurred during a successful AJAX request

Figures 9-14 displays a flowchart of an AJAX events chain for a successful and a failed AJAX request.

9781430264330_Fig09-14.jpg

Figure 9-14. Flowchart of events triggered during successful and failed AJAX requests

Summary

This chapter covered topics related to jQuery AJAX methods and events. You learned:

  • The advantages and disadvantages of using AJAX calls.
  • How to make jQuery AJAX calls using the primary $.ajax() method and the convenience methods: $.get(), $.getJSON(), $.getScript(), $.post() and $(selector).load().
  • How to make GET and POST requests to the server.
  • How to send data to the server.
  • How to process data returned from the server in different formats—text, HTML, XML, and JSON.
  • How to handle error conditions.
  • How to use jQuery helper functions: $(selector).serialize(), $(selector).serializeArray(), and $.param(obj).
  • How to use $.parseJSON(jsonString) and JSON.stringify(jsonObj) to handle JSON data.
  • The purpose and order of AJAX event handlers at the document and request levels.
..................Content has been hidden....................

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