Ajax Hacks: Tips & Tools for Creating Responsive Web Sites
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.
Here is this hack's sequence of events for sending text to the server:
This hack includes a text field and a textarea that send HTTP requests with their values when the user is finished with them. Figure 2-1 shows the web page loaded into a browser window. Figure 2-1. No buttons need apply
The user types some information into the text field or textarea (the larger data-entry box) and then exits the control, and the application automatically sends what the user typed to a server component. Here is the HTML code for this 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="/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" > <div > Enter a few words for submitting to our server: <input type="text" name="tfield" size="35" /> </div> <div > <span >Enter a phrase for submitting to our server:</span> <textarea name="tarea" rows="20" cols="20"> </textarea> </div> </form> </body> </html>
Instead of a user clicking a button to send the form information, each text control sets the action in motion itself. When the user presses Tab or clicks outside of one of the text widgets, the code specified by the widget's onblur event handler is executed. The upcoming code sample shows how this event handler is set up after the browser has finished loading the page. The script tag in the HTML imports a JavaScript file, hacks_2_1.js. This file contains all the code necessary for running this hack. The following sample includes all the code for sending a request and handling the return value (in the handleResponse( ) function). "Display Text Field or textarea Values Using Server Data" [Hack #13] explains the related technique of inserting the server's response into text controls, but that shouldn't prevent you from peeking at handleResponse( ) if you want! Here's the relevant JavaScript code: var formObj = null; var formObjTyp = ""; var request=null; //input field's event handlers window.onload=function( ){ var txtA = document.getElementById("tarea"); if(txtA != null){ txtA.onblur=function( ){if (this.value) { getInfo(this);}}; } var tfd = document.getElementById("tfield"); if(tfd != null){ tfd.onblur=function( ){if (this.value) { getInfo(this);}}; } } 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); } //event handler for XMLHttpRequest function handleResponse( ){ try{ if(request.readyState == 4){ if(request.status == 200){ var resp = request.responseText; 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("It does not appear that the server is available "+ "for this application. Please"+ " try again very soon. \\nError: "+err.message); } } /* Initialize a request object that is already constructed */ function initReq(reqType,url,bool){ try{ /* Specify the function that will handle the HTTP response */ request.onreadystatechange=handleResponse; request.open(reqType,url,bool); request.send(null); } catch (errv) { alert( "The application cannot contact the server "+ "at the moment. "+ "Please try again in a few seconds." ); } } /* 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. */ function httpRequest(reqType,url,asynch){ //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"); } } //the request could still be null if neither ActiveXObject //initialization succeeded if(request){ initReq(reqType,url,asynch); } else { alert("Your browser does not permit the use of all "+ "of this application's features!");} } The code declares two top-level JavaScript variables: formObj and formObjTyp. The former variable holds the input or textarea object (other functions in the code will need access to it later), and the latter holds a string representing a form object tag name, such as "INPUT" or "TEXTAREA." This string is one of the parameters that the server component requires (see the formatted URL that appears at the end of the next section, "Get the First Serve In").
As mentioned previously, the code sets up the text widgets' onblur event handlers when the browser finishes loading the page. You can accomplish this task in JavaScript by assigning a function to the window's onload event handler. Using the window.onload code, as follows, is an alternative to calling the JavaScript functions from within an HTML element's onblur attribute: window.onload=function( ){ var txtA = document.getElementById("tarea"); if(txtA != null){ txtA.onblur=function( ){if (this.value) { getInfo(this);}}; } var tfd = document.getElementById("tfield"); if(tfd != null){ tfd.onblur=function( ){if (this.value) { getInfo(this);}}; } }
These text fields are now hot. Once the user types a value and exits a control, the information entered is off and running to the server; the user doesn't have to click another button to send it.
Get the First Serve In
The main job of the text-field event handlers is to call the getInfo( ) function. This function grabs whatever the user typed into the text widget and sends this value to the server: 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); } The getInfo( ) function takes as a parameter an object that represents the text field or textarea. We pass in references to the input or textarea objects so that the JavaScript code can use them to handle the server return value.
The last part of the previous code, httpRequest("GET",url,true), is the function call that actually sends the user's information to the server. However, a few things have to occur before the code calls that function, such as putting together a proper URL (the server's address on the Internet). The server component is expecting a string describing the kind of form object from which the data derives. In this application, the string is formulated from the tagName property of the Element object (returning INPUT or TEXTAREA).
The code further refines the input object's description by what input subtype it represents (text input, radio button, etc.). This is accomplished by appending the value of the input object's type property (text, in this case) to the string input, which creates the final string input text. In other words, this type property returns "text" only if the object represents an <input type="text" ...> HTML element. Then the string is forced to lowercase and submitted to the server with the user's content: 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(val); httpRequest("GET",url,true);
The global JavaScript function encodeURIComponent( ) is a method for ensuring that certain characters, such as spaces, are encoded when they are included in URLs. Otherwise, your program may send a partial or truncated URL to the server and generate an error. The entire URL might look like this in a real case: http://www.parkerriver.com/s/webforms?objtype=input%20text& val=Hello%20There!
What's Next?
The httpRequest( ) function wraps the code that initializes and uses the request object, which works behind the scenes so that the user doesn't have to manually send the data. "Use the Request Object to POST Data to the Server" [Hack #2], among others, describes this function in detail. So what happens to the submitted data next? That depends on your application. The next hack explores a related but different topic: using JavaScript and Ajax to take an HTTP response and insert data into an existing text field or textarea.
|
Категории