Monday, June 1, 2009

AJAX EXAMPLES

Example 1: Ajax with innerHTML

For a simple innerHTML-based Ajax example, we’ll create a quasi-functional address book application. We’ll start with the XHTML page (line wraps marked » —Ed.):

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
xml:lang="en" lang="en">

Ajax Address Book







Simple Ajax Address Book





Please Choose a Person

value="Get the Address" />








As you can see, we have a simple form with a select, from which to choose a person. Again, we are providing a fallback action for the form, in case our JavaScript cannot run. Below the form, we have a simple pre element that will be displaying the address information from the database.

And now for the JavaScript. Basically, we will be commandeering the select and using its onchange event handler to trigger an XMLHttpRequest() call to obtain the address information for the selected individual. The server will be returning this information as a string like this:

Bob Smith
123 School Street
Anytown, NY 12345

We will take this return as a string and dump it into the pre element using innerHTML. Take a look at the code (line wraps marked » —Ed.):

var addressBook = {
myConn: false, // the XMLHttpRequest
body: false, // the body element
target: false, // the target container
loader: false, // the loader
init: function(controlId, sbmtBtnId, targetId){
/* init() takes three arguments:
* the id of the controller (select)
* the id of the submit button
* the id of the target container */
// test for methods & elements
if(!document.getElementById ||
!document.getElementsByTagName ||
!document.getElementById(controlId) ||
!document.getElementById(sbmtBtnId) ||
!document.getElementById(targetId)) return;
// set and test XHConn, quitting silently if it fails
addressBook.myConn = new XHConn();
if(!addressBook.myConn) return;
// get the body
addressBook.body = document.getElementsByTagName('body')[0];
// get the controller
var control = document.getElementById(controlId);
// get the submit button
var sbmtBtn = document.getElementById(sbmtBtnId);
// remove the submit button
sbmtBtn.parentNode.removeChild(sbmtBtn);
// get the target
addressBook.target = document.getElementById(targetId);
// add the onchange event to the controller,
addressBook.addEvent(control,
'change',
function(){
if(this.value != ''){
/* if there's a value,
trigger getAddress */
addressBook.getAddress(this.value);
} else {
// otherwise empty the target
addressBook.target.innerHTML = '';
}
});
},
getAddress: function(id){ // the Ajax call
// let's let the user know something is happening (see below)
addressBook.buildLoader();
/* this is the function that is run
once the Ajax call completes */
var fnWhenDone = function(oXML) {
// get rid of the loader
addressBook.killLoader();
// insert the returned address information into the target
addressBook.target.innerHTML = oXML.responseText;
};
// use XHConn's connect method
addressBook.myConn.connect('index.php', 'POST',
'id='+id, fnWhenDone);
},
buildLoader: function(){ // builds a loader
// create a new div
addressBook.loader = document.createElement('div');
// give it some style
addressBook.loader.style.position = 'absolute';
addressBook.loader.style.top = '50%';
addressBook.loader.style.left = '50%';
addressBook.loader.style.width = '300px';
addressBook.loader.style.lineHeight = '100px';
addressBook.loader.style.margin = '-50px 0 0 - 150px';
addressBook.loader.style.textAlign = 'center';
addressBook.loader.style.border = '1px solid #870108';
addressBook.loader.style.background = '#fff';
// give it some text
addressBook.loader.appendChild( »
document.createTextNode( »
'Loading Data, please wait\u2026'));
// append it to the body
addressBook.body.appendChild(addressBook.loader);
},
killLoader: function(){ // kills the loader
// remove the loader form the body
addressBook.body.removeChild(addressBook.loader);
},
addEvent: function(obj, type, fn){ // the add event function
if (obj.addEventListener) »
obj.addEventListener(type, fn, false);
else if (obj.attachEvent) {
obj["e"+type+fn] = fn;
obj[type+fn] = function() {
obj["e"+type+fn](window.event);
};
obj.attachEvent("on"+type, obj[type+fn]);
}
}
};
/* run the init() method on page load, passing it
the required arguments */
addressBook.addEvent(window, 'load',
function(){
addressBook.init('person',
'submit',
'address');
});

See this script in action.
Example 2: Ajax with Nodes

Let’s alter the example, and instead of returning a string from the server, this time, make it XML:



Bob
Smith



123 School Street
Anytown
NY

12345



The XHTML page remains the same, but we need to make some minor adjustments to the JavaScript. To highlight the differences, I will touch on each change individually.

The first change, to the onchange event handler of the select, is pretty simple (line wraps marked » —Ed.):


addressBook.addEvent(addressBook.control,
'change',
function(){
if(this.value != ''){
addressBook.getAddress(this.value);
} else {
addressBook.target.removeChild( »
addressBook.target.firstChild);
}
});


Instead of setting the content of the target to empty using innerHTML, the DOM is removing the node that is the target’s first child.

Next up is the getAddress() method (line wraps marked » —Ed.):


getAddress: function(id){
addressBook.buildLoader();
var fnWhenDone = function(oXML) {
addressBook.killLoader();
if(addressBook.target.hasChildNodes()){
addressBook.target.removeChild( »
addressBook.target.firstChild);
}
xml = oXML.responseXML;
var name = addressBook.getNodeValue(xml, 'first')+' '+
addressBook.getNodeValue(xml, 'last');
var address = addressBook.getNodeValue(xml, 'street');
var csz = addressBook.getNodeValue(xml, 'city')+', '+
addressBook.getNodeValue(xml, 'state')+' '+
addressBook.getNodeValue(xml, 'zip');
var txt = document.createTextNode(name + "\ n" +
address + "\n" + csz);
addressBook.target.appendChild(txt);
};
addressBook.myConn.connect('getAddress.php', 'POST',
'id=' + id, fnWhenDone);
},


As we are working with XML, we can use the responseXML property to get the return from the server as a node tree. Then we can traverse that tree, collecting the tidbits of information we need. In this example, we added a new method (getNodeValue()) that makes working with XML returns easier:


getNodeValue: function(tree, el){
return tree.getElementsByTagName(el)[0].firstChild.nodeValue;
},


This method takes two arguments: the node tree (tree) and the element (el) whose content is wanted. It returns the nodeValue of the firstChild of the first el within tree or, in other words, the text value of the node requested from the node tree.

Once we have collected all of the requested contents from the XML, the text string is rebuilt and generated with the DOM before being appended to the target. The end result can be seen here.

0 comments:

Post a Comment