Getting Started with Ajax
Getting Started with Ajax
BorisVM The start of 2005 saw the rise of a relatively new technology, dubbed “Ajax” by Jesse James Garrett of Adaptive Path. Ajax stands for Asynchronous JavaScript and XML. In a nutshell, it is the use of the nonstandard XMLHttpRequest() object to communicate with server-side scripts. It can send as well as receive information in a variety of formats, including XML, HTML, and even text files. Ajax’s most appealing characteristic, however, is its “asynchronous” nature, which means it can do all of this without having to refresh the page. This allows you to update portions of a page based upon user events and provides one of the cornerstones of Rich Internet Applications (RIA) referred to in discussions of “Web 2.0.” The DOM plays into Ajax in a number of ways. How you use the DOM depends a good deal on how you handle the content returned from the server. You can treat the con­tent as simple text using the responseText property of the server response, or you can treat it as XML using responseXML. Assuming the content you pull back from the server is an (X)HTML snippet and you’ve gotten it as responseText, you could drop that content into a particular spot on the page using innerHTML. On the flip side, if the content you pull back is XML and you’ve gotten it as responseXML, you can traverse its DOM, cherry-picking or performing functions on the elements, attributes, and text nodes. This probably sounds very confusing, but it is pretty easy once we go over a few simple examples. For these examples, we are using the XHConn library for simplifying our interaction with XMLHttpRequest(). The XHConn library is freely available at xkr.us/code/javascript/XHConn/ and allows simple access to XMLHttpRequest() by creating a new XHConn object and then initiating its connect() method as you will soon see. As with the DOM Scripting examples (above), for a blow-by-blow of what the script is doing, read the JavaScript comments. 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.): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" » "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" » xml:lang="en" lang="en"> <head> <title>Ajax Address Book</title> <meta http-equiv="content-type" content="text/html; » charset=iso-8859-1" /> <meta http-equiv="Content-Language" content="en-us" /> <script type="text/javascript" src="XHConn.js"></script> <script type="text/javascript" src="addressBook.js"></script> </head> <body> <h1>Simple Ajax Address Book</h1> <form action="getAddress.php" method="POST"> <fieldset> <legend>Please Choose a Person</legend> <select id="person" name="person"> <option value="">Choose Someone</option> <option value="1">Bob Smith</option> <option value="2">Janet Jones</option> </select> <input type="submit" id="submit" name="submit" » value="Get the Address" /> </fieldset> </form> <pre id="address"></pre> </body> </html> 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: <file> <name> <first>Bob</first> <last>Smith</last> </name> <address> <street>123 School Street</street> <city>Anytown</city> <state>NY</state> <zip>12345</zip> </address> </file> 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. You may be wondering, why do both examples do the exact same thing? It shows how you can work with two completely different backend systems and still get the results you want. In Ajax, as in many things, flexibility is important to get the job done. Want to read more? [url="http://www.amazon.com/exec/obidos/ASIN/0596009879/virtualmacedo-20"]Web Design in a Nutshell[/url], by Jennifer Niederst Robbins and featuring contributions from Darek Featherstone and Aaron Gustafson, has been completely rewritten to reflect the best practices of the web standards world and is on shelves now.
OooOo Iinteresno e da se prochita i za RoR (Ruby on Rails) ustvari da se znae od kade poteknuva AJAX. Iskreno nema da me iznenadi ako ova nabrzo stane sledniot standard za web. http://www.rubyonrails.org/
achtung_panzer
quote:
Originally posted by OooOo
Iinteresno e da se prochita i za RoR (Ruby on Rails) ustvari da se znae od kade poteknuva AJAX.
Za volja na vistinata, AJAX ne poteknuva samo od edno mesto i ne e EDNA nova tehnologija tuku spojot porano poznat kako DHTML na kogo mu e dodadena implementacijata na XMLHttpRequest objektot. Vo sushtinata na AJAX (Asynchronous JavaScript And XML) e asinhronata komunikacija so serverot, t.e. izvrshuvanje na kodot bez da se cheka celosniot odgovor od serverot. Ova znachitelno go zabrzuva izvrshuvanjeto na web aplikaciite i istovremeno go namaluva tovarot shto serverot treba da go nosi. Vakviot metod na asinhrono izvrshuvanje postoi i pred implementacijata na XMLHttpRequest, so koristenje na skriena ramka (hidden frame) so velichina 0x0 pikseli koja se koristi za istata cel: asinhrona komunikacija so serverot. Asinhronite tehniki go vidoa svetloto na denot otkako lugjeto vo Google dosta efektno gi primenija na nivnite GoogleMaps i Gmail. Skoro sekoj ajax tutorial gi posochuva tie dve aplikacii kako svetol primer za primenata na ajax, iako niedna od niv ne koristi XMLHttp za komunikacija tuku seushte se potpiraat na tehnikata na skrienata ramka... Ne e zlato se' shto e open source niti e sranje se' shto e Microsoft: XMLHttp objektot so godini nanazad e dostapen kako ActiveX kontrola so istata namena kaj Outlook samo publicitet dobi otkako e napishana implementacija za Mozila i voopshto site Gecko- bazirani listachi. Koga se raboti za komunikacija so serverot, AJAX mozhe da se koristi so site povazhni tehnologii: PHP, ASP/ASP.NET, JSP/servlet. POstojat brojni gotovi biblioteki so funkcii (frameworks) za rabota so Ajax na serverskata strana za site od prethodno spomenative tehnologii (Sajax/Xajax i Ajax.Net kako najinteresni). Na stranata na klientot isto taka ima dosta shiroka ponuda: Dojo, Scriptacolous, dragNdropDOM so koi mozhat da se postignat dosta interesni efekti. Interesni sajtovi za zapoznavanje so AJAX: [url]http://www.w3schools.com/DOM/dom_http.asp[/url] [url]http://ajaxpatterns.org/wiki/index.php?title=Main_Page[/url] [url]http://www.adaptivepath.com/publications/essays/archives/000385.php[/url]