BUY THIS BOOK
Add to Cart

Print Book $29.99


Add to Cart

Print+PDF $38.99

Add to Cart

PDF $23.99

Safari Books Online

What is this?

Add to UK Cart

Print Book £20.99

What is this?

Looking to Reprint or License this content?


Ajax Hacks
Ajax Hacks Tips & Tools for Creating Responsive Web Sites By Bruce W. Perry
March 2006
Pages: 438

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Ajax Basics
Remember when users called the Internet the “world wide wait?” Way back in the Neolithic era of the Web? With some applications, that aspect of the Web hasn’t really changed that much: fill out form, click button, web page goes away, wait, page refreshes, correct mistake, click, wait, wait... You’ve been stuck in this limbo before.
A number of recent web sites, however, such as many of the cool mapping applications that have evolved of late, require much greater responsiveness in the way they interact with users. The old, conventional way of handling user interaction is to have the entire page “go away” with every click, with the new page reappearing in the browser view only when the server’s response is finally complete. However, some new applications require small pieces of the web page to change instantaneously, without the entire page reloading.
For example, if you have ever used Google Maps, the way you can drag outlying regions into your view conveys the impression that you have all of the maps stored locally on your computer, for your effortless manipulation. Imagine how unpopular this application would be if every time you tried to “drag” the map the page disappeared for a few (long) moments while the browser waited for another server response. The application would be so sluggish that no one would use it. So what’s the magic that makes this work?
A blend of well-known technologies and a nifty JavaScript tool form the basis of a snappier and more powerful application model for the Web. If you’re afraid of acronym overload, don’t worry—this one’s easy. It’s called Ajax, which stands for Asynchronous JavaScript and XML.
Ajax is neither a floor wax nor a desert topping (nor, indeed, a lemon-scented cleaning product!). It’s a blend of a number of standard technologies already familiar to developers and designers:
  • JavaScript, a programming language that adds dynamic scripting to web pages. JavaScript code can be embedded in a web page to allow the page to implement cool new behaviors with a technique called
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
It’s Not a Floor Wax
A blend of well-known technologies and a nifty JavaScript tool form the basis of a snappier and more powerful application model for the Web. If you’re afraid of acronym overload, don’t worry—this one’s easy. It’s called Ajax, which stands for Asynchronous JavaScript and XML.
Ajax is neither a floor wax nor a desert topping (nor, indeed, a lemon-scented cleaning product!). It’s a blend of a number of standard technologies already familiar to developers and designers:
  • JavaScript, a programming language that adds dynamic scripting to web pages. JavaScript code can be embedded in a web page to allow the page to implement cool new behaviors with a technique called client-side scripting. This technique is almost as old as the Web itself.
  • XMLHttpRequest, a JavaScript object with an application programming interface (API) that can connect with a server using the HyperText Transfer Protocol (HTTP). A lot of the Ajax magic is propelled by this piece of code, which all the major browsers (such as Mozilla Firefox, Internet Explorer 6, Safari 1.3 and 2.0, and Opera 7.6) support. The asynchronous part of Ajax derives from this object’s characteristics.
  • Extensible Markup Language (XML), a language designed to define other languages. The XMLHttpRequest object can handle the server response in standard XML format as well as plain text.
  • HTML and Cascading Style Sheets (CSS), which control what the user sees on a web page. Web developers can use JavaScript to make dynamic changes to the visual interface by programming HTML elements and CSS styles.
  • The Document Object Model (DOM), a model that represents an XML file or web page as a set of related objects that can be dynamically manipulated, even after the user has downloaded the page. The web page view is structured as a
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Handle with Care
Of course, Ajax is not for everyone (particularly those dessert topping fans!). Because Ajax technology can dynamically alter a web page that has already been downloaded, it may interfere with certain functions near and dear to many users, such as creating bookmarks for browser views. For example, in the absence of fancy scripting solutions, the dynamic changes you make with DOM in an existing web page cannot be linked to with a URL that you can send to your friends or save for later. (Both “Fix the Browser Back Button in Ajax Applications” [Hack #68] and “Handle Bookmarks and Back Buttons with RSH” [Hack #69] should help shed light on these issues and provide some hackable solutions.)
A number of the cool Ajax tips described in this book alter the behavior of many familiar web widgets, such as select lists, textareas, text fields, and radio buttons that submit their own data and talk to servers behind the scenes. However, bear in mind that Ajax-powered widgets should be first and foremost usable, and always avoid confusing and irritating web users.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
XMLHttpRequest
At the center of many of the hacks in this book is the XMLHttpRequest object, which allows JavaScript to fetch bits of server data while the user is happily playing with the rest of your application. This object has its own API, which we will summarize in this introduction.
“Detect Browser Compatibility with the Request Object” [Hack #1] covers setting up the request object in JavaScript. Once the object is initialized, it has several methods and properties that you can use in your own hacks.
A common practice among programming types is to call the functions that are associated with particular JavaScript objects “methods.” The XMLHttpRequest object’s methods include open(  ), send(  ), and abort(  ).
The following list shows the properties supported by the request objects defined by most of the major browsers, such as Internet Explorer 5.0 and later, Safari 1.3 and 2.0, Netscape 7, and Opera’s latest releases (such as Opera 8.5). Mozilla Firefox’s request object has additional properties and methods not shared by the request objects of other major browsers, but it also supports all of the following:
onreadystatechange
Callback function; the function assigned to this property is called whenever readyState changes.
readyState
Number; 0 means uninitialized, open(  ) has not yet been called; 1 means loading, send(  ) has not been called; 2 means loaded, send(  ) has been called, and headers/status are available; 3 means interactive, responseText holds partial data; 4 means completed.
responseText
string
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Detect Browser Compatibility with the Request Object
Use JavaScript to set up Microsoft’s and the Mozilla-based browsers’ different request objects.
Browser compatibility is an important consideration. You have to make sure the “engine” behind Ajax’s server handshake is properly constructed, but you can never predict which browsers your users will favor.
The programming tool that allows Ajax applications to make HTTP requests to a server is an object that you can use from within JavaScript code. In the world of Firefox and Netscape (as well as Safari and Opera), this object is named XMLHttpRequest. However, continuing with the tradition established by IE 5.0, recent vintages of Internet Explorer implement the software as an ActiveX object named Microsoft.XMLHTTP or Msxml2.XMLHTTP.
Microsoft.XMLHTTP and Msxml2.XMLHTTP refer to different versions of software components that are a part of Microsoft XML Core Services (MSXML). Here’s what our contributing IE expert says on this matter:
“If you use Microsoft.XMLHTTP, the ActiveXObject wrapper will try to initialize the last known good version of the object that has this program (or “prog”) ID. This object, in theory, could be MSXML 1.0, but almost no one these days has that version because it has been updated via Windows Update, IE 6, or another means. MSXML 1.0 was very short-lived. If you use MSXML2.XMLHTTP, that signifies to the wrapper to use at least MSXML 2.0 libraries. Most developers do not need to use a specific version of MSXML, such as MSXML2.XMLHTTP.4.0 or MSXML2.XMLHTTP.5.0.”
Although Microsoft and the engineers on the Mozilla project have chosen to implement this object differently, we will refer to the ActiveX and XMLHttpRequest objects simply as “request objects” throughout this book, because they have very similar functionality.
As a first step in using Ajax, you must check if the user’s browser supports either one of the Mozilla-based or ActiveX-related request objects, and then properly initialize the object.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Use the Request Object to POST Data to the Server
Step beyond the traditional mechanism of posting your user’s form values.
This hack uses the POST HTTP request method to send data, communicating with the server without disrupting the user’s interaction with the application. It then displays the server’s response to the user. The difference between this hack’s approach to posting data and the typical form-submission method is that with Ajax, the page is not altered or refreshed when the application connects with the server to POST it the data. Thus, the user can continue to interact with the application without waiting for the interface to be rebuilt in the browser.
Imagine that you have a web portal in which several regions of the page or view provide the user with a variety of services. If one of these regions involves posting data, the entire application might have a more responsive feel if the POST request happens in the background. This way, the entire page (or segments of it) does not have to be refreshed in the browser.
The example web page used in this hack is a simple one. It requests users to enter their first and last names, gender, and country of origin, and then click a button to POST the data. Figure 1-1 shows what the web page looks like in a browser window.
Figure 1-1: Please Mister POST man
Here’s the code for the HTML page:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
    <script type="text/javascript" src="/parkerriver/js/hack2.js"></script>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Send a data tidbit</title>
</head>
<body>
<h3>A Few Facts About Yourself...</h3>
<form action="javascript:void%200" onsubmit="sendData(  );return false">
    <p>First name: <input type="text" name="firstname" size="20"> </p>
    <p>Last name: <input type="text" name="lastname" size="20"> </p>
    <p>Gender: <input type="text" name="gender" size="2"> </p>
    <p>Country of origin: <input type="text" name="country" size="20"> </p>
    <p><button type="submit">Send Data</button></p>
</form>
</body>
</html>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Use Your Own Library for XMLHttpRequest
Break out the code that initializes the request object and sends requests to its own JavaScript file.
To cleanly separate the concerns of big Ajax applications, create a separate file that manages the XMLHttpRequest object, then import that file into every web page that needs it. At the very least, this ensures that any necessary changes regarding how the code sets up the request object have to be made only in this file, as opposed to every JavaScript file that uses Ajax-style requests.
This hack stores all the request object–related code in a file called http_request.js. Any web page that uses XMLHttpRequest can then import this file in the following way:
<script type="text/javascript" src="js/http_request.js"></script>
Here’s the code for the file, including all the comments:
var request = null;
/* Wrapper function for constructing a request object.
 Parameters:
  reqType: The HTTP request type, such as GET or POST.
  url: The URL of the server program.
  asynch: Whether to send the request asynchronously or not.
  respHandle: The name of the function that will handle the response.
  Any fifth parameters, represented as arguments[4], are the data a
  POST request is designed to send. */
function httpRequest(reqType,url,asynch,respHandle){
    //Mozilla-based browsers
    if(window.XMLHttpRequest){
        request = new XMLHttpRequest(  );
    } else if (window.ActiveXObject){
        request=new ActiveXObject("Msxml2.XMLHTTP");
        if (! request){
            request=new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    //very unlikely, but we test for a null request
    //if neither ActiveXObject was initialized
    if(request) {
        //if the reqType parameter is POST, then the
        //5th argument to the function is the POSTed data
        if(reqType.toLowerCase(  ) != "post") {
            initReq(reqType,url,asynch,respHandle);
        }  else {
            //the POSTed data
            var args = arguments[4];
            if(args != null && args.length > 0){
                initReq(reqType,url,asynch,respHandle,args);
            }
        }
    } else {
        alert("Your browser does not permit the use of all "+
              "of this application's features!");
    }
}
/* Initialize a request object that is already constructed */
function initReq(reqType,url,bool,respHandle){
    try{
        /* Specify the function that will handle the HTTP response */
        request.onreadystatechange=respHandle;
        request.open(reqType,url,bool);
        //if the reqType parameter is POST, then the
        //5th argument to the function is the POSTed data
        if(reqType.toLowerCase(  ) == "post") {
            request.setRequestHeader("Content-Type",
                    "application/x-www-form-urlencoded; charset=UTF-8");
            request.send(arguments[4]);
        }  else {
            request.send(null);
        }

    
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Receive Data as XML
Ajax and server programs provide a DOM Document object that’s ready to go.
Many technologies currently exchange data in Extensible Markup Language format, mostly because XML is a standardized and extensible format widely supported by the software world. Thus, different parties can use existing, well-known technologies to generate, send, and receive XML, without having to adapt to the software tools used by the parties with whom they are exchanging the XML data.
An example is a Global Positioning System (GPS) device that can share the data it has recorded about, say, a hike or a bike ride with a location-aware web application. You just stick the USB cable attached to the GPS device into a USB computer port, launch software that sends the device data to the Web, and that’s it. The data format is usually an XML language that has been defined already for GPS software. The web application and the GPS device “speak the same language.”
Although this book is not the place for an extensive introduction to XML, you have probably seen these text files in one form or another. XML is used as a “meta” language that describes and categorizes specific types of information. XML data starts with an optional XML declaration (e.g., <?xml version="1.0" encoding="UTF-8"?>), followed by a root element and zero or more child elements. An example is:
<?xml version="1.0" encoding="UTF-8"?>
<gps>
<gpsMaker>Garmin</gpsMaker>
<gpsDevice>
Forerunner 301
</gpsDevice>
</gps>
Here, gps is the root element, and gpsMaker and gpsDevice are child elements.
Ajax and the request object can receive data as XML, which is very useful for handling web-services responses that use XML. Once the HTTP request is complete, the request object has a property named responseXML. This object is a DOM Document object that your Ajax application can use. Here’s an example:
function handleResponse(  ){
    if(request.readyState == 4){
        if(request.status == 200){
            var doc = request.responseXML;
...
}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Get Plain Old Strings
Manage weather readings, stock quotes, web page scrapings, or similar non-XML data as plain old strings.
The request object has the perfect property for web applications that do not have to handle server return values as XML: request.responseText. This hack asks the user to choose a stock symbol, and the server returns the stock price for display. The code handles the return value as a string.
A variation to this program in the next hack requires the stock prices to be handled as numbers. These are old prices that a server component stores for certain stock symbols, not live quotes that you would obtain from a commercial web service or by HTML scraping. For an example of that mechanism, see “Use XMLHttpRequest to Scrape a Energy Price from a Web Page” [Hack #39].
First, here is the HTML for the web page. It imports JavaScript code from a file named hack9.js:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
    <script type="text/javascript" src="js/hack9.js"></script>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Choose a stock</title>
</head>
<body>
<h3>Stock prices</h3>
<form action="javascript:void%200" onsubmit=
        "getStockPrice(this.stSymbol.value);return false">
    <p>Enter stock symbol: <input type="text" name=
            "stSymbol" size="4"><span id="stPrice"></span></p>
    <p><button type="submit">Get Stock Price</button></p>
</form>
</body>
</html>
Figure 1-5 shows the web page as displayed in Firefox. The user enters a symbol such as “GRMN” (case insensitive) and clicks the Get Stock Price button; the JavaScript then fetches the associated stock price and displays it within a span element to the right of the text field.
Figure 1-5: Instantaneously displaying a stock price
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Receive Data as a Number
Do numerical calculations that depend on the request object’s return value as a number.
This hack receives a stock quote as a number, then dynamically displays the total value of a stock holding based on the number of shares a user enters. If the server does not send a valid number, the application displays an error message to the user.
The great advantage of Ajax technology is in receiving discrete values rather than entire web pages from a server. Sometimes, that discrete information has to be used as a number, rather than as a string (as discussed in the last hack) or some other object. JavaScript is usually pretty smart about converting values to number types without your intervention, but still, you don’t want your application to multiply an innocent investor’s share quantity by undefined or some other weird data the server returns!
This hack checks that the user has entered a proper number for a “number of shares” value. The code also checks the server return value to make sure it is numerically valid. It then dynamically displays the stock price and total value of the shares in the user’s browser.
Figure 1-6 shows what the browser form looks like.
Figure 1-6: Discover a total share value
The following code shows the HTML for the web page:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
    <script type="text/javascript" src="/parkerriver/js/hack4.js">
    </script>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Tally your stocks</title>
</head>
<body>
<h3>Your total Stock Holdings</h3>
<form action="javascript:void%200" onsubmit=
        "getStockPrice(this.stSymbol.value,this.numShares.value);return false">
<p>Enter stock symbol: <input type="text" name="stSymbol" size="4">
            <span id="stPrice"></span></p>
<p>Enter share amount: <input type="text" name="numShares" size="10"></p>
<p><button type="submit">Get Total Value</button></p>
<div id="msgDisplay"></div>
</form>
</body>
</html>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Receive Data in JSON Format
Ajax can receive data in efficient and powerful JavaScript Object Notation.
How would you like to use Ajax and receive data from the server as plain old JavaScript objects? Well, you can, using a format called JavaScript Object Notation (JSON). This hack takes information entered by a web user and initiates a server round trip, which returns the data in JSON syntax for the web page’s use.
JSON is simple and straightforward, which is probably why a lot of developers like it. JSON-formatted data is appropriate for simple objects that are bundles of properties and values. An example is a server program that pulls product information from a database or cache and returns it to a retail web page in JSON format. Data in JSON format is represented by:
  • An opening curly brace ( {)
  • One or more property names, separated from their values by colons, with property/value pairs separated by commas
  • A closing curly brace (})
The values of each property in the object can be:
  • Simple strings, such as "hello"
  • Arrays, such as [1,2,3,4]
  • Numbers
  • The values true, false, or null
  • Other objects, as in a composition, or an object containing one or more objects
See http://www.json.org for further details.

This is exactly the format of an Object literal in JavaScript. As an example, here is what the information requested of the user in “Use the Request Object to POST Data to the Server” [Hack #2] looks like in JSON format:
{
firstname:"Bruce",
lastname:"Perry",
gender:"M",
country:"USA"
}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Handle Request Object Errors
Design your Ajax application to detect any server errors and provide a friendly user message.
Much of the oomph behind Ajax technology is that it allows JavaScript to connect with a server program without the user intervening. However, JavaScript developers often have no control over the server component itself (which could be a web service or other software designed outside their organizations). Even if your application involves your organization’s server component, you cannot always be sure that the server is behaving normally or even that your users are online at the moment they trigger your request object. You have to make sure that your application recovers in the event that the backend program is unavailable.
This hack traps errors and displays a meaningful error message, in the event that the Ajax application loses server contact.
This hack addresses the following exceptional events, and recommends ways for the application to recover from them:
  • The web application or server component you are connecting with is temporarily unavailable.
  • The server your application is connecting with is down, or its URL has changed unbeknownst to you.
  • The server component you connect with has one or more bugs, and it crashes during your connection (yeech!).
  • When you call the open(  ) method with the request object, your code uses a different host address than the address from which the user downloaded the web page. The request object throws an exception in this case when you try to call its open(  ) method.
You can use this hack’s exception-handling code in any application. This hack uses the stock calculation code from “Receive Data as a Number” [Hack #6]. We’ll take a look at the code that initializes the request object and the exception-handling mechanism in a moment, but first, here’s the HTML file that imports the JavaScript code from
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Dig into the HTTP Response
Display the values of various HTTP response headers in addition to or in lieu of a typical server return value.
An HTTP response header is descriptive information, laid out by the HTTP 1.1 protocol, that web servers send requestors along with the actual web page or data. If you have already coded with the XMLHttpRequest object (discussed at the beginning of this chapter), you know that the request.status property equates to an HTTP response status code sent from the server. This is an important value to check before your page does anything cool with the HTTP response.
Status values can include 200 (the request went through okay), 404 (the requested file or URL path was not found), or 500 (internal server error).
However, you might want to see some of the other response headers associated with the request, such as the type of web server software associated with the response (the Server response header) or the content type of the response (the Content-Type header). This hack requests the user to enter a URL in a text field. When the user tabs out of or clicks outside of the text field, the browser displays various HTTP response headers. As usual with Ajax, this happens without a page refresh.
This request object method returns only a subset of the available response headers, including Content-Type, Date, Server, and Content-Length.
Here is the HTML page code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
    <script type="text/javascript" src="js/hack7.js"></script>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>view response headers</title>
    <link rel="stylesheet" type="text/css" href="/parkerriver/css/hacks.css" />
</head>
<body onload="document.forms[0].url.value=urlFragment">
<h3>Find out the HTTP response headers when you "GET" a Web page</h3>

<form action="javascript:void%200">
    <p>Enter a URL: 
        <input type="text" name="url" size="20" onblur="getAllHeaders(this.value)"> 
        <span class="message">::press tab when finished editing the 
             field::</span></p>
    <div id="msgDisplay"></div>
</form>
</body>
</html>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Generate a Styled Message with a CSS File
Let the users choose predesigned styles for the messages they see.
This hack sends a request to a server, which returns a text message. The user’s choices determine the actual message content and appearance. The HTML for the page includes a select tag listing the styles the users can choose for the display of the results and a text field containing a partial URL they can complete and submit to a server.
The information returned relates to the response headers returned by the server [Hack #9]. However, what we are interested in here is this hack’s dynamic message generation and style assignment. Here’s the HTML code for the page:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd">
<html>
<head>
    <script type="text/javascript" src="js/hack8.js"></script>
    <script type="text/javascript">
    function setSpan(  ){
        document.getElementById("instr").onmouseover=function(  ){
            this.style.backgroundColor='yellow';};
        document.getElementById("instr").onmouseout=function(  ){
            this.style.backgroundColor='white';};
    }
    </script>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>view response headers</title>
    <link rel="stylesheet" type="text/css" href="/parkerriver/css/hacks.css" />
</head>
<body onload="document.forms[0].url.value=urlFragment;setSpan(  )">
<h3>Find out the HTTP response headers when you "GET" a Web page</h3>
<h4>Choose the style for your message</h4>
<form action="javascript:void%200">
    <p>
        <select name="_style">
            <option label="Loud" value="loud" selected>Loud</option>
            <option label="Fancy" value="fancy">Fancy</option>
            <option label="Cosmopolitan" value="cosmo">Cosmopolitan</option>
            <option label="Plain" value="plain">Plain</option>
        </select>
    </p>
    <p>Enter a URL: <input type="text" name="url" size="20" onblur=
            "getAllHeaders(this.value,this.form._style.value)">
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Generate a Styled User Message on the Fly
Dynamically define and assign CSS styles to web page content.
JavaScript and DOM programming allow you to define CSS style attributes and apply them to page elements from scratch. An example of where you may want to implement these methods is a Wiki page that permits users to develop their own page designs and styles.
In most cases, separating the style definitions from the JavaScript code is the way to go. Separating application concerns or tiers in this manner allows each element to evolve independently and makes web development less complex and more efficient.
This hack, like the one before it, dynamically displays server information based on the user’s choice of style categories. Unlike the previous hack, this one formulates the styles in code, then applies the chosen style to an HTML element. Here is the code, with the style information highlighted:
var request;
var urlFragment="http://localhost:8080/";
var st;

function getAllHeaders(url,styl){
    if(url){
        st=styl;
        httpRequest("GET",url,true);
    }
}

/*  Set one or more CSS style attributes on a DOM element 
CSS2Properties Object.
 Parameters:
  stType stands for a style name, as in 'plain,''fancy,''loud,' or 'cosmo'.
  stylObj is the HTML element's style property, as in div.style. */

function setStyle(stType,stylObj){
    switch(stType){
        case 'plain' : 
            stylObj.maxWidth="80%";
            stylObj.border="thin solid black"; 
            stylObj.padding="5%";
            stylObj.textShadow="none";
            stylObj.fontFamily="Arial, serif";
            stylObj.fontSize="0.9em";
            stylObj.backgroundColor="yellow"; break;
        case 'loud' : 
            stylObj.maxWidth="80%";
            stylObj.border="thin solid black"; 
            stylObj.padding="5%";
            stylObj.fontFamily="Impact, serif";
            stylObj.fontSize="1.4em";
            stylObj.textShadow="0 0 2.0em black";
            stylObj.backgroundColor="rgb(181,77,79)"; break;
        case 'fancy' :
            stylObj.maxWidth="80%";
            stylObj.border="thin solid black"; 
            stylObj.padding="5%";
            stylObj.fontFamily="Herculanum, Verdana, serif";
            stylObj.fontSize="1.2em";
            stylObj.fontStyle="oblique";
            stylObj.textShadow="0.2em 0.2em grey";
            stylObj.color="rgb(21,49,110)";
            stylObj.backgroundColor="rgb(234,197,49)"; break;
        case 'cosmo' :
            stylObj.maxWidth="80%";
            stylObj.border="thin solid black"; 
            stylObj.padding="1%";
            stylObj.fontFamily="Papyrus, serif";
            stylObj.fontSize="0.9em";
            stylObj.textShadow="0 0 0.5em black";
            stylObj.color="aqua";
            stylObj.backgroundColor="teal"; break;
        default : 
            alert('default');
       
    }
}

//event handler for XMLHttpRequest
function handleResponse(  ){
    try{
        if(request.readyState == 4){
            if(request.status == 200){
                /* All headers received as a single string */
                var headers = request.getAllResponseHeaders(  );
                var div = document.getElementById("msgDisplay");
                if(st){
                    setStyle(st,div.style);
                } else {
                    setStyle("plain",div.style);
                }
                div.innerHTML="<pre>"+headers+"</pre>";
            
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Web Forms
Hacks 12–21
Almost everyone who has used the Web has encountered an HTML form. When users buy books or DVDs online, or log into discussion lists or other web communities, inevitably they are typing information into text fields or choosing options in select lists, and then submitting the forms by clicking a button. The purpose of these forms is to upload user- or client-related data to a server component, which then implements a task such as logging the user into an application.
Web applications that use Ajax-related techniques, however, can provide a different mechanism for submitting web-form information. JavaScript code can submit discrete values from only certain widgets or fields, for instance, without requiring the user to click the classic Submit button. This application model has transformed the web form into a “rich user interface” similar to a desktop application, where the code can send data over the network in response to click or blur events without refreshing the entire web page. The following hacks illustrate how to send selection and text-field values using XMLHttpRequest, and how to dynamically generate the content of display widgets from server data.
Create a smooth transition between entering information into a textarea or text field and instantly transferring the data to the server.
Ajax applications can automatically send to a server program the information that the user has entered into a text field or textarea. The application code waits for the text widget’s onblur event to occur, then uses the request object to send just the data from that field or textarea. In many applications, this technique is preferable to requiring the user to click a Submit button, then sending all of the form’s values to the server in a big clump. It is also much snappier in terms of the application’s responsiveness. For example, an online quiz or teaching application can fetch and display the correct answer to a question as soon as the user has moved away from the field, instead of requiring the user to click a button and refresh the page just to see specific answers. Real-time language translation is another possible application for this user-interface behavior.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Submit Text Field or textarea Values to the Server Without a Browser Refresh
Create a smooth transition between entering information into a textarea or text field and instantly transferring the data to the server.
Ajax applications can automatically send to a server program the information that the user has entered into a text field or textarea. The application code waits for the text widget’s onblur event to occur, then uses the request object to send just the data from that field or textarea. In many applications, this technique is preferable to requiring the user to click a Submit button, then sending all of the form’s values to the server in a big clump. It is also much snappier in terms of the application’s responsiveness. For example, an online quiz or teaching application can fetch and display the correct answer to a question as soon as the user has moved away from the field, instead of requiring the user to click a button and refresh the page just to see specific answers. Real-time language translation is another possible application for this user-interface behavior.
The onblur event is triggered when a web form control such as a text field loses the keyboard focus, which is typically caused by the user pressing the Tab key or clicking outside of the field. You can also use the onkeypress, onkeydown, or onkeyup event handlers to respond to user interaction with a text widget.
Here is this hack’s sequence of events for sending text to the server:
  1. The user tabs into the field or clicks in a textarea.
  2. The user types some text.
  3. The user then presses Tab or clicks on another part of the page to exit the text field or textarea.
One issue with intervention-less form sending is that users are not accustomed to this kind of behavior from web forms. A user might be put off or confused by web-form controls such as text fields that dynamically submit their own data. The user interface should make it clear that “something is going to happen” when the user is finished with the text field, or display a message or progress indicator when the request object is sending the data. In addition, depending on the sensitivity of the task, you may want to add another layer of communication with the user, such as an
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Display Text Field or textarea Values Using Server Data
Have server information magically appear in text boxes without the web page refreshing.
You can have a server component interact with information that the user enters in a text box, without the jarring effect of the page reconstituting every time the user enters new information. A typical example is a spell checker or auto-complete field [Hack #78]. Using the request object as an intermediary, a server component can respond in real time to what the user types.
This hack displays an automatic server response, so that the response appears as if by magic in the text control, without anything else changing in the web page. The hack is an extension of “Submit Text Field or textarea Values to the Server Without a Browser Refresh” [Hack #12], which used the request object to submit textarea or text field values to a server component behind the scenes.
This hack takes the information the user has submitted and displays a character count and word count in the same field. You can accomplish the same thing with client-side JavaScript, of course, but just to prove that a server component is doing the work, the hack displays some information about the server in the textarea.
Figure 2-2 shows the web page after the user has entered some data into the text field.
Figure 2-2: Enter data and elicit a response
Figure 2-3 shows the browser window after the user has entered data in both fields and then clicked Tab.
Figure 2-3: Real-time data updates
The following code is the HTML for the page. It imports a JavaScript file named hacks_2_1.js, which contains the code that does most of the work:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="js/hacks_2_1.js"></script>
    <link rel="stylesheet" type="text/css" href="/css/hacks.css" />
    <title>Submit your information</title>
</head>
<body>
<h3>Get stats from textareas and textfields using Ajax</h3>
<form action="javascript:void%200" >
<table border="0"><tr>
<td>Enter a few words for submitting to our server: 
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Submit Selection-List Values to the Server Without a Round Trip
Whisk the user’s multiple list choices off to the server without delay.
Many web developers will see the advantage of sending a user’s multiple choices in a radio button or select list directly to a server program using the request object, rather than requiring the user to click a button and send the entire form. This gives the application greater responsiveness and increases efficiency by sending discrete values rather than clumps of information.
This hack sends the user’s choices of U.S. states to a server program when the keyboard focus is moved away from the select list. The select element looks like this in the HTML code that underlies the web page:
<select name="_state" multiple="multiple" size="4">
This is a selection list that allows the user to choose more than one item. When the keyboard focus moves from the select list (because the user presses the Tab key or clicks elsewhere on the page), the code defined by the element’s onblur event handler executes. (This code is shown in an upcoming section.) The size=4 part indicates that four state names can be displayed at a time in the select list. Figure 2-4 shows the page loaded into the Safari browser.
Figure 2-4: Multiple choices for immediate delivery
A JavaScript file named hacks_2_4.js declares all the code this hack needs. Here is the HTML for the web page, which imports this file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="js/hacks_2_4.js"></script>
    <link rel="stylesheet" type="text/css" href="/css/hacks.css" />
    <title>Alter select lists</title>
</head>
<body>
<h3>Create or Alter a Select List</h3>
<form action="javascript:void%200" >
    <table border="0">
        <tr><td>Choose one or more states: </td><td> 
        <select name="_state" multiple="multiple" size="4">
            <option value="al">Alabama</option>
            <option value="ak">Alaska</option>
            <option value="az">Arizona</option>
            <option value="ar">Arkansas</option>
            <option value="ca">California</option>
            <option value="co">Colorado</option>
            <option value="ct">Connecticut</option>
            <option value="de">Delaware</option>
            <option value="dc">District of Columbia</option>
            <option value="fl">Florida</option>
            <option value="ga">Georgia</option>
            <option value="hi">Hawaii</option>
            <!—snipped...-->
        </select></td></tr>
        <tr><td>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Dynamically Generate a New Selection List Using Server Data
Create a list of choices on a web page that automatically branches into a new selection list without the entire page being refreshed.
Sometimes a choice in a user interface naturally leads to a subsequent set of choices. An example is a support page for computer hardware, where one select list has a choice for hardware platform, such as Apple or HP, which generates (when the user makes a choice) a second list of related operating systems, and so on. Ajax can shine in these situations where the user interface can automatically be customized for the browser user, as well as where the content for the select list must come from a server.
You could set up this page using only dynamic HTML, with JavaScript creating the new select list. However, the choices for the new list would have to be hardcoded into the JavaScript. Ultimately, this content for new lists will change, creating an awkward situation in which developers have to constantly add persistent lists to an existing JavaScript file. Without being able to store these values in a sensible location such as a database or other persistent store, this application model becomes unwieldy.
This hack displays two radio buttons on a web page, offering users the choice of displaying either European countries or South American countries. Either choice results in the display of a new selection list with different content. Figure 2-6 shows the web page for the hack.
Figure 2-6: Dynamically generate a list widget by selecting a radio button
Here is the HTML code underlying the web page. I removed most of the long select list above the radio buttons because that code appears in the previous hack:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="js/hacks_2_4.js"></script>
    <link rel="stylesheet" type="text/css" href="/css/hacks.css" />
    <title>Alter select lists</title>
</head>
<body>
<h3>Create or Alter a Select List</h3>
<form action="javascript:void%200" >
    <table border="0">
        <tr><td>Choose one or more states: </td>
        <td><select name="_state" multiple="multiple" size="4">
            <option value="al">Alabama</option>
            <!—more options... -->
        </select></td></tr>
        <tr><td><span id="select_info" class="message">
        The server reports that you have chosen the following abbreviated
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Extend an Existing Selection List
Give browser users the option to modify an existing list before making and submitting their choices.
Imagine that you have a list of U.S. states, as in the select element used in “Submit Selection-List Values to the Server Without a Round Trip” [Hack #14]. As part of the customer-registration process, you ask what state your customers live in (for sales-tax purposes, say). However, you want to be able register customers from other countries too, because your product can now be distributed overseas. You do not want to include every country on earth in the select list, though, both for geo-political reasons (countries frequently change, as in the case of the former Yugoslavia) and because the select list would be too big to fit nicely on the page. Thus, you want your users to be able to choose (when applicable) a continent, making a selection that adds a subset of select options to the page. Your application will pass the name of the selected continent to the server program and query the server for the specific countries associated with that continent.
To begin with, you’ll provide a select list of continents. When the user makes a selection, the names of the countries within that continent are derived from the server and automatically added to an existing select list, without the page being refreshed. Figure 2-8 shows the web page for this hack, which is based on the previous hack containing the select list of U.S. states.
Figure 2-8: Add options to a list
The user selects a continent in the top-level select list. This action triggers the onclick event for the select element. Here is the HTML code for the page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="js/hacks2_6.js"></script>
    <link rel="stylesheet" type="text/css" href="/css/hacks.css" />
    <title>Alter select lists</title>
</head>
<body>
<h3>Add Entries to a Select List</h3>
<form action="javascript:void%200">
    <table border="0">
        <tr><td>Add your country: <select id="cts" name="_continents">
            <option value="southam">South America</option>
            <option value="euro">Europe</option>
        </select></td></tr><tr><td>Choose one or more states: </td>
        <td> <select id="sts" name="_state" multiple="multiple" size="4">
            <option value="al">Alabama</option>
            <option value="ak">Alaska</option>
            <option value="az">Arizona</option>
            <option value="ar">Arkansas</option>
            <option value="ca">California</option>
            <option value="co">Colorado</option>
            <option value="ct">Connecticut</option>
            <option value="de">Delaware</option>
            <option value="dc">District of Columbia</option>
            <option value="fl">Florida</option>
            <option value="ga">Georgia</option>
            <option value="hi">Hawaii</option>
            <!--snipped here...-->
        </select></td></tr>

    </table>
</form>
</body>
</html>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Submit Checkbox Values to the Server Without a Round Trip
Generate immediate interaction with a server program when the browser user clicks a checkbox.
Checkboxes are those little squares or buttons that allow users to make choices among multiple options. The conventional setup is for users to check one or more checkboxes as part of a form that they have to submit later. But what if you want your application to submit only the checkbox values, rather than the whole form, and have that submission take place when the user clicks the checkbox and not at some indeterminate time in the future?
This hack represents a poll in which users vote for their favorite team and individual sports. When the browser user selects any of the checkboxes, this action triggers an event that submits this value to a server program and then displays the poll results. Figure 2-10 shows what the page looks like in a browser.
Figure 2-10: Choose your favorite sports
The server program has a database that captures the poll results; the program updates and then returns those results. This hack uses the XMLHttpRequest object to send the sport choices and handle the server’s response, and it uses DOM programming and CSS to display the poll results. Here is the HTML code for the page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="js/hacks2_5.js"></script>
    <link rel="stylesheet" type="text/css" href="/css/hacks2_5.css" />
    <title>submit checkbox values</title>
</head>
<body>
<h3>Choose your favorite sports</h3>
<h4>Team sport</h4>
<form id="team" action="javascript:void%200" method="get">
<div id="team_d" class="team">
<input type="checkbox" name="team_sports" id=
"baseball" value="baseball" /> Baseball <br />
<input type="checkbox" name="team_sports" id=
"soccer" value="soccer"  /> Soccer  <br />
<input type="checkbox" name="team_sports" id=
"football" value="football"  /> Football  <br />
<input type="checkbox" name="team_sports" id=
"basketball" value="basketball"  /> Basketball  <br />
<input type="checkbox" name="team_sports" id=
"lacrosse" value="lacrosse" />Lacrosse  <br />
<input type="checkbox" name="team_sports" id=
"hockey" value="hockey" /> Hockey  <br />
<input type="checkbox" name="team_sports" id=
"tennis" value="tennis" /> Tennis  <br />
</div>
</form>
<div id="team_poll" class="poll">
    <span id="t_title" class="p_title"></span>
    <span id="t_results" class="p_results"></span></div>
<h4>Individual sport</h4>
<form  id="ind" action="javascript:void%200" method="get">
<div id="ind_d" class="ind">
<input type="checkbox" name="individual_sports" id=
"cycling" value="cycling" /> Cycling  <br />
<input type="checkbox" name="individual_sports" id=
"running" value="running"  /> Running  <br />
<input type="checkbox" name="individual_sports" id=
"swimming" value="swimming"  /> Swimming <br />
<input type="checkbox" name="individual_sports" id=
"nordic_skiing" value="nordic_skiing"  />Nordic Skiing  <br />
<input type="checkbox" name="individual_sports" id=
"inline_skating" value="inline_skating"  />Inline Skating <br />
&l