Ajax Hacks: Tips & Tools for Creating Responsive Web Sites

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="/books/4/254/1/html/2/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: <input type="text" name="tfield" size="35"/></td></tr> <tr><td valign="top">Enter a phrase for submitting to our server: <textarea name="tarea" rows="20" cols="20"> </textarea></td> </tr> </table></form> </body> </html>

The last hack explained how the code submits the user's information without refreshing the web page. In other words, after the user has typed in some information and pressed Tab or clicked outside of the field, just the piece of data that user added to the text field or textarea is sent in an HTTP request to the server.

An onblur event handler calls the getInfo( ) function, passing in the text field or textarea object as a parameter.

The entire code for this behavior appears in "Submit Text Field or textarea Values to the Server Without a Browser Refresh" [Hack #12], so it's not reproduced in full here. However, I will show the code for the getInfo( ) and handleResponse( ) functions, which do the work of sending the server component the information it needs and then handling the server's response. First, let's take a look at the getInfo( ) function:

function getInfo(obj){ if (obj == null ) { return; } formObj=obj; formObjTyp =obj.tagName; if(formObjTyp == "input" || formObjTyp == "INPUT"){ formObjTyp = formObjTyp + " "+formObj.type; } formObjTyp = formObjTyp.toLowerCase( ); var url = "http://www.parkerriver.com/s/webforms?objtype="+ encodeURIComponent(formObjTyp)+"&val="+ encodeURIComponent(obj.value); httpRequest("GET",url,true); }

This function passes along to the server component the user's typed-in information as part of the val parameter. In addition, the obj parameter holds a reference to the text control in which the information was entered, such as a text field or textarea. The reference is specifically a DOM object, such as an HTMLInputElement or HTMLTextAreaElement.

You do not have to worry about the DOM object tree at this point (although it is interesting!). The HTML code for this hack refers to the particular text control using the this keyword in the onblur event handler. The getInfo( ) function can determine exactly what kind of text control the user is interacting witha text field or a textareaby accessing the object's tagName property. You can learn more about DOM object programming in David Flanagan's JavaScript: The Definitive Guide (O'Reilly).

Instant Server Messaging

The server program takes the information typed in by the user and sends back the associated number of characters and words. To make this response information palatable to our receiving code, the server returns its information in JavaScript Object Notation (JSON) format [Hack #7]. JSON is similar to XML in that it structures data to make it easier for software to digest and work with.

Your own program could simply return data in XML format or as a simple string. Using JSON for the return value is this programmer's personal preference. It is particularly useful if the server client is composed of JavaScript code.

This code shows a typical JSON server return value, if the user typed 55 words into a textarea:

{ Form_field_type: "textarea", Text_length: "385", Word_count: "55", Server_info: "Apache Tomcat/5.0.19" }

This code represents a JavaScript object with four different properties: Form_field_type, Text_length, Word_count, and Server_info. An explanation of how these properties are used is provided after the next code sample.

Now the hack takes this information and plugs it back into the textarea. This is the job of the handleResponse( ) function:

//event handler for XMLHttpRequest function handleResponse( ){ try{ if(request.readyState == 4){ if(request.status == 200){ var resp = request.responseText; if(resp != null){ var func = new Function("return "+resp); var objt = func( ); if(formObjTyp == "textarea"){ if(formObj != null){ formObj.value = objt.Form_field_type + " character count: "+objt.Text_length+ "\\nWord count: "+ objt.Word_count+"\\nServer info: "+ objt.Server_info; } } else if(formObjTyp == "input text"){ if(formObj != null){ formObj.value = objt.Form_field_type + " # characters: "+objt.Text_length+ " Word count: "+objt.Word_count; } } } } else { //request.status is 503 //if the application isn't available; //500 if the application has a bug alert( "A problem occurred with communicating "+ "between the XMLHttpRequest object and "+ "the server program."); } }//end outer if } catch (err) { alert(err.name); alert("It does not appear that the server "+ "is available for this application. Please"+ " try again very soon. \\nError: "+err.message); } }

This code grabs the response as text. Since the text is already formatted in JSON syntax (as an object literal in JavaScript), the code uses the special technique described in "Receive Data in JSON Format" [Hack #7]. A Function constructor returns the text as a JavaScript object. In this case, the variable objt now refers to the server component's response in an object-centric way, so you can access the server information with syntax such as objt.Server_info.

The latter code piece accesses the Server_info property of the object referred to by the variable objt:

var resp = request.responseText; var func = new Function("return "+resp); //call the function and return the object to which //the objt variable now points var objt = func( );

The rest of the code goes about inserting this information back into the textarea using this syntax:

if(formObjTyp == "textarea"){ if(formObj!= null){ formObj.value = objt.Form_field_type + " character count: "+objt.Text_length+ "\\nWord count: "+ objt.Word_count+"\\nServer info: "+ objt.Server_info; } }

To see what the textarea looks like after the information is placed inside it, refer back to Figure 2-3.

You can access the textarea because a top-level JavaScript variable, formObj, refers to it. One of the keys to this code is setting the value of a textarea or text field with the "dot property-name" syntax common to JavaScript, as in formObj.value.

The server program sends more information back to a textarea than it does to a text field, including line breaks (\\n in JavaScript) because the textarea is a big box that can hold more text. You cannot include line breaks in a text field, for instance, because it holds only one line (even if that line can have numerous characters).

The code formats the value of the textarea by connecting strings to the properties of the object the server returned, as in " character count: "+objt.Text_length.

Although in a conventional web interface users expect textareas and text fields to be reserved for their own data entry, this hack demonstrates how to provide direct feedback related to what the user types into a particular field.

Категории