AJAX In Action [101]
Listing 5.11 submitData() function
function addParam(form,key,value){
var input=document.createElement("input");
input.name=key;
input.value=value;
form.appendChild(input);
}
Licensed to jonathan zheng Writing to the server 195 function submitData(url,data){ var form=document.createElement("form"); form.action=url; form.method="POST"; for (var i in data){ addParam(form,i,data[i]); } form.style.display="none"; document.body.appendChild(form); form.submit(); } submitData() creates the form element and iterates over the data, adding to the form using the addParam() function. We can invoke it like this: submitData( "myFormHandlerURL.php", {username:"dave",password:"letmein"} ); This technique is concise but has a significant drawback in that there is no easy way of capturing a server response. We could point the form at an invisible IFrame and then parse the result, but this is rather cumbersome at best. Fortunately, we can achieve the same effect by using the XMLHttpRequest object. 5.5.2 Using the XMLHttpRequest object We’ve already seen the XMLHttpRequest object in action in chapter 2 and earlier in this chapter. The differences between reading and updating are minor from the client code’s point of view. We simply need to specify the POST method and pass in our form parameters. Listing 5.12 shows the main code for our ContentLoader object developed in section 3.1. We have refactored it to allow parameters to be passed to the request, and any HTTP method to be specified. Listing 5.12 ContentLoader object net.ContentLoader=function (url,onload,onerror, method,params,contentType){ b Extra arguments this.onload=onload; this.onerror=(onerror) ? onerror : this.defaultError; this.loadXMLDoc(url,method,params,contentType); } net.ContentLoader.prototype.loadXMLDoc Licensed to jonathan zheng 196 CHAPTER 5 The role of the server =function(url,method,params,contentType){ if (!method){ method="GET"; } if (!contentType && method=="POST"){ contentType="application/x-www-form-urlencoded"; } if (window.XMLHttpRequest){ this.req=new XMLHttpRequest(); } else if (window.ActiveXObject){ this.req=new ActiveXObject("Microsoft.XMLHTTP"); } if (this.req){ try{ this.req.onreadystatechange=net.ContentLoader.onReadyState; this.req.open(method,url,true); HTTP method if (contentType){ Content type this.req.setRequestHeader("Content-Type", contentType); } this.req.send(params); Request parameters }catch (err){ this.onerror.call(this); } } } We pass in several new arguments to the constructor b. Only the URL (corresponding to the form action) and the onload handler are required, but the HTTP method, request parameters, and content type may be specified, too. Note that if we’re submitting key-value pairs of data by POST, then the content type must be set to application/x-www-form-urlencoded. We handle this automatically if no content type is specified. The HTTP method is specified in the open() method of XMLHttpRequest, and the params in the send() method. Thus, a call like this var loader=net.ContentLoader( 'myFormHandlerURL.php', showResponse, null, 'POST', 'username=dave&password=letmein' ); will perform the same request as the forms-based submitData() method in listing 5.11. Note that the parameters are passed as a string object using the form-encoded style seen in URL querystrings, for example: name=dave&job=book&work=Ajax_In+Action Licensed to jonathan zheng Writing to the server 197 This covers the basic mechanics of submitting data to the server, whether based on textual input from a form or other activity such as drag and drop or mouse movements. In the following section, we’ll pick up our ObjectViewer example from chapter 4 and learn how to manage updates to the domain model in an orderly fashion. 5.5.3 Managing user updates effectively In chapter 4, we introduced the ObjectViewer, a generic piece of code for browsing complex domain models,