Course Content‎ > ‎

Section 08: Ajax

Asynchronous JavaScript and XML (AJAX)


What is AJAX?

Asynchronous JavaScript and XML (Ajax) is a technique making the user interfaces of web applications more responsive and interactive.   At the emergency of AJAX it became a hotly debated topic from many angles - this is because it introduces something that is new into web application development.  The functionality that is newly available to end-users is "in-page replacement".  In-page replacement is the ability of a web page to change elements of that web page, using data from a web server, without the need to totally redraw itself. 

Consider the technologies we have used for web pages in this module to date.  These are all based around the principle that the client makes a request, the server generates a response and the whole page is redrawn in line with the response (Note: HTML Frames might seem different, but they are not, the entire frame is redrawn each time and each frame is just a seperate page).  So far, we have not introduced any functionality which would allow us to replace only certain elements of a web page.

Ajax provides this functionality.  Ajax is asynchronous in that extra data is requested and transferred from the server, without any interference with the display and behaviour of the current page.

Let us consider this using an example of perhaps the most recognised Ajax application at the time of writing these notes - Google Maps.

Google maps works using a grid of images each representing a "square" of map information.  On the first request to Google Maps, map information is downloaded with the request for whatever default location has been specified (or a map of the US if none has been previously specified).  The information for the immediate square and a number of adjacent squares are also downloaded, allowing the user to "scroll" around the map.  However, it is not practical for the entire world map at maximum resolution to be downloaded to every user.  Hence, map information is passed as the client user requests it.   As you use Google Maps you will notice that even as you scroll the Google server is regularly contacted and occasionally you will get load lag while the map information is downloaded and displayed.  This is because the application is regularly contacting the Google server to get map information relative to the current location to allow the user to browse freely.

So where does Ajax come into play?  As we stated above, Ajax provides the functionality of "in-page replacement" to web sites.  This is exactly what we are witnessing inthis situation.  As we use the map facility, the map data is being constantly updated from the server, without the full page being redrawn.  As we navigate the map, the top and left banners remain exactly as they were previously and only the actual map facility is redrawn.  This is the functionality that Ajax provides for us.


What can we do with Ajax?

From the time of its inception, Google Maps has been considered to be impressive technology.  However, what other uses could we have for Ajax in our sites?

  • Improve our Search Facility - occasionally users are not 100% certain of exactly what they are searching for.  Perhaps they partially know a name or a code or perhaps they just wished to be prompted with suggestions from a usability point of view.  This can be seen on sites such as http://www.ask.com and http://www.google.com where, as you type in search words, a suggestion box is provided prompting with possible searches.
  • Draggable Content - people familiar with myYahoo or myGoogle will have already encountered such content.  Using Ajax content, such as Windows, can be dragged around the HTML window in accordance with the preference of the client user.
  • Automatic Updating of Prices - consider a situation where a user is speccing a computer and wishes to see how the changing of selection of motherboard, memory, monitor etc. will affect the overall price of the computer.  In traditional websites, the user might have selected to change the motherboard from a drop-down list - the page would reload with the new price and selection made.  However, now with Ajax the price could be dynamically updated without affecting the rest of the HTML page. 
  • Asynchronous Server-Side Validation - using Ajax we could perform server-side validation of form fields without refreshing the client html pages.  While you might ask, "But JavaScript needs to run anyway for Ajax, so why not just do client-side validation?" , there are a number of advantages in server-side validation.  Perhaps you wish to check that the Invoice number a user has entered actually exists in your database.  Why make the user submit the whole form in order to find out that they have submitted an invalid number - simply inform them beside the Invoice Number box ("You have entered an invalid invoice number").
  • Many, many, many other uses

How does Ajax work?

Firstly, we need to consider the technologies that combine together to make it all work.

1. XHTML and CSS

XHTML (or HTML) is used for providing the markup tags, as used in any typical web site.  In addition, we utilise CSS for extra styling functionality in relation to presentation and layout.  Both of these technologies have been covered in earlier chapters - although more emphasis was placed on HTML.  For our purposes, it is enough to consider that XHTML is a stricter and more standardised form of HTML, which follows the rules of XML such as the requirement for well-formedness and validity against a schema or DTD. 


2. Document Object Model (DOM)

The Document Object Model is a platform and language independent standard object model for representing HTML or XML.  The W3C introducted the DOM Level 1 specification as a recommendation in 1998.  This was followed in 2000, by the DOM Level 2 specification.   However, it was a number of years before browsers provided an effective implementation for the W3C DOM.  By 2005, large aspects of the W3C DOM were supported by the majority of browsers, including Microsoft Internet Explorer (Version 5), Firefox, Opera and Safari.  At the time of writing these notes, the last specification was DOM Level 3, released in 2004.   The primary use of DOM within Ajax is that the model allows us to explicitly specifiy objects in web pages which we wish to target for "in-page replacement".

More details on DOM has been provided in the XML content for this module.  


3. XML

XML is typically used as the format for transferring data between the server and the client.  Using XML we can represent any applicable data object structure we might wish to represent.  In our example above, we make a request for some map information using a URL of the form:  http://maps.google.com/maps?f=q&hl=en&geocode=&q=dublin+city+university&sll=53.344104,-6.267494&sspn=0.285723,0.570602&ie=UTF8&z=16&iwloc=addr  (q is our query, z is the zoom factor, sll is longitude and latitude etc.).  Google will then return back an XML response which contains the information we have requested. 

It should be noted that XML is not our only option for transferring data.  It is possible to return preformatted HTML, plain text or any alternative text format. 


4. XMLHttpRequest (XHR) and JavaScript

The XMLHttpRequest is the core of the Ajax model - without it the model would not exist*.  The XMLHttpRequest JavaScript object is the enabling technology which is used to exchange data asynchronously with the web server.  In short, XMLHttpRequest lets us use JavaScript to make a request to the server and process the response without blocking the user.  Naturally, as we are using this JavaScript object, the providing technology is JavaScript and hence some knowledge of JavaScript is required to get Ajax applications to function. 

This was alluded earlier in the course, when we discussed how Ajax was providing new life to the JavaScript language, which was increasingly waning for a number of years due to poor implementations of standards and end-user disabling of JavaScript. 

* Note: It should however, be noted that some Ajax frameworks use IFrame objects to handle this exchange.  However, the core concepts remain the same. 


Ajax Considerations

  • JavaScript Disabled - Many clients will disable JavaScript due to reasons of personal preference.  These reasons are perfectly valid, where users are attempting to avoid exploits such as cross-site scripting and keylogger scripts.  Many (including myself) use Addons for Firefox like NoScript which allow you to enable or disable JavaScript on an individual site basis.  What happens to our Ajax applications in this situation?  Typically we're talking about full failure, combined with a message to the user to enable JavaScript, which may not be an option to your end user.
  • Accessibility - Providing support for accessibility is not only a noble goal - it is also required by law in many countries and environments.  For example, in Ireland the following is applicable "The Disability Act 2005 also provides a statutory basis for accessible public services.  Sections 26,27 and 28 of the Act place obligations on public bodies to make their services and information accessible to people with disabilities".  Developers need to use caution, particularly with dynamic web applications that they meet the requirements of accessibility for individual user groups.
  • Usability Issues - Navigation - Consideration needs to be taken as to what the expected behaviour should be of the back,forward, refresh and bookmark buttons in your application design.  For example, if we have a number of subsections of a page with dynamic content, should the back button send us to the previous overall page, or simply the previous state of one of the subsections of the page.

Ajax or Applet

Around 2005-2015, there were times when it was more suitable to use an applet instead of Ajax.  Applets provided an advanced set of user interface possibilities on the client side and they could achieve many things that an AJAX application could not do.  These included: custom data streaming, graphic manipulation, threading and advanced graphical user interfaces.  

However, recent years have seen applets essentially start fading into in-existence (although there are still plenty of enterprise applications still on applet based systems!).  There are two main reasons for this:

  1. Browsers have started to deprecate their support for applets for security and other reasons
  2. HTML5, Canvas and other newer browser functionality means that applet functionality can be replicated now without the need for JVM plugins



An Example Ajax Application

Most of the module focuses around providing practical implementations of technologies and this chapter is no different.  Here we will provide an Ajax example, which you can modify and use for your own purposes.

The purpose of this example is to mimic the same type of occurance that we had in the example video above.  We will create a text box which will provide some suggestions as we type.  We will keep it quite simple and we won't get involved with interaction with a database - instead we will create a Vector of strings which will contain all of the suggestions we might have.  In reality you would typically integrate this sort of application with a database.


Step 1: Build our HTML Form

For the HTML form, we aren't going to do anything particularly special.  But here are a few points worth noting:

  • We are including a seperate file containing our Javascript source code (we will talk about this in the next step however)
  • The "action" of our form is irrelevant since we never actually submit the form in the traditional sense.  In a full application this would likely point at an application returning the data on the search.  The action of the form is not the Ajax action - the Ajax action is defined in the JavaScript file.
  • The reason we set autocomplete="off" is because browsers regularly make suggestions in form boxes on your behalf.  We are essentially "turning off" the browser suggestions and implementing our own suggestion system.
  • onKeyup is the JavaScript method we will be using.  Essentially, every time we press a key (and release) the showHint(this.value) method is called in our JavaScript file.
  • Finally, we have a div and a span (just consider them as invisible boxes with an ID if you are not familiar with them).  The span with id="txtHint" is the section of the HTML page which we are going to dynamically change as we type in the box.
<html> <head> <title>Example Ajax Form</title> <script src="ajax_javascript.js"></script> </head> <body> <h2>Search for Names</h2> <p>Type in the box to search for names of lecturers in the School of Electronic Engineering:</p> <form id="searchNames" method="GET" action="Path-to-the-target-of-the-form-which-we-are-not-currently-concerned-with"> <b>Search : </b> <input type="text" autocomplete="off" onkeyup="showHint(this.value)" name="searchString" size="20" maxlength="30" /> <br/> <input type="submit" value="Search" /> </form> <br/> <div class="box" id="autodiv1"> <span id="txtHint">No Suggestions</span> </div> </body> </html>

Source: ajaxform.html 


Step 2: Write the JavaScript

As mentioned previously in the JavaScript section of the module, this course is not a JavaScript module and as such you are not expected to be able to write JavaScript code.  However, you should have a basic understanding of how it works and some of the simple functionality.  For this explanation, we will only provide some basic pointers as to what happens - this is sufficient for our purposes:

  • We have a function called 'showHint(str)' which you should recognise as being the method called from the form, each and every time we release a key in the input text box.  Hence, this function is being called every time we type a key in that box.  The function checks to see if one or more characters had been typed in the box and if so, it generates a URL which will point at the servlet we will use in Step 3, passing the main parameter of 'q' which will be the value currently contained in the input box of the form.  
  • The purpose of Math.random() is to avoid caching of particular URLs by the browser.  By generating a unique URL each time, we ensure that the browser won't attempt to read from browser cache instead of contacting our servlet.
  • So now we need to create the XMLHttpRequest object  which performs the asynchonous data transfer with the server.   This is performed in the function GetXmlHttpObject(handler).    As you can see, this function is more complicated than it should be, due to browser compatibility issues.   For the purpose of this module, there is no need to examine this function in more detail - if you are writing a beginners Ajax application just re-use this function in your own code.
  • So now, using we use that XMLHttpRequest object to send a "GET" request to the URL pointing at our servlet application. 
  • Now taking a look at our "stateChanged()" function - this has been set up as a "handler" for processing requests which have been completed.  We can see how the function firstly does a check for xmlHttp.readyState==4.  If this value is equal to 4, it means that a request had been completed.  So once the servlet had sent us back a completed response to our request then we execute the JavaScript line 
    document.getElementById("txtHint").innerHTML=xmlHttp.responseText
  • This is where the DOM gets involved.  The JavaScript code looks for the element in our HTML document which matches to an ID 'txtHint" and replaces the HTML in this element with the response which has come back from the servlet from Step 3. 
var xmlHttp function showHint(str) {             if (str.length >= 1)     {         var url="/student/Search?sid=" + Math.random() + "&q=" + str         xmlHttp=GetXmlHttpObject(stateChanged)         xmlHttp.open("GET", url , true)         xmlHttp.send(null)     }     else     {         document.getElementById("txtHint").innerHTML="No Suggestions";     } } function stateChanged() {     if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")     {         document.getElementById("txtHint").innerHTML=xmlHttp.responseText     } } function GetXmlHttpObject(handler) {     var objXmlHttp=null     // Just going to deal with MSIE and Mozilla for the sake of brevity     if (navigator.userAgent.indexOf("MSIE")>=0)     {         var strName="Msxml2.XMLHTTP"         if (navigator.appVersion.indexOf("MSIE 5.5")>=0)         {             strName="Microsoft.XMLHTTP"         }         try         {             objXmlHttp=new ActiveXObject(strName)             objXmlHttp.onreadystatechange=handler             return objXmlHttp         }         catch(e)         {             /** This gets caught if Scripting for ActiveX isn't enabled as a possibility **/             return         }     }     if (navigator.userAgent.indexOf("Mozilla")>=0)     {         objXmlHttp=new XMLHttpRequest()         objXmlHttp.onload=handler         objXmlHttp.onerror=handler         return objXmlHttp     } }

Source: ajax_javascript.js 


Step 3: Write the Server Application

The application we will use is a simple Java Servlet which will contain a Vector (similar to an Array) of names.  When a request comes to the servlet it will return any names which contain a substring of the parameter 'q'.  Hence, for a parameter q=da it will return names like 'David', 'Damien', 'Brenda', 'Breda' etc.  The exact functionality of this servlet is not particularly important - having the servlet generate any response whatsoever is enough to demonstrate the principals of Ajax.  However, it was decided to demonstrate something at least marginally useful.  In reality this servlet would likely perform a check against a database rather than a hardcoded Vector of names.  To do this, you would just introduce the database logic and JDBC code you should already be familiar with.  A few points of note:

  • This servlet is not different in any way than servlets you have already encountered.  The only change in this application is that the servlet is being called asynchonously from within a HTML page - but there is no change in the servlet code.
  • toLowerCase() is used so that we're not doing any upper and lower case comparisons on String objects.  Everything is compared in lower case characters.
package org.dcu; import java.io.*; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.util.Enumeration; import java.util.Vector; @WebServlet("/Search") public class Search extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse res) throws ServletException, IOException { Vector<String> dVector = new Vector<String>(); dVector = setupLecturerVector(dVector); res.setContentType("text/html"); PrintWriter out = res.getWriter(); String typed = request.getParameter("q").toLowerCase(); String responsetext = new String(""); for (Enumeration<String> e = dVector.elements() ; e.hasMoreElements() ;) { String name = ((String) e.nextElement()).toLowerCase(); if (name.indexOf(typed)!=-1) { responsetext = responsetext + name + "<br/>"; } } out.println(responsetext); out.close(); } private Vector<String> setupLecturerVector(Vector<String> dVector) { dVector.addElement("David Molloy"); dVector.addElement("Damien O Rourke"); dVector.addElement("Derek Molloy"); dVector.addElement("Jennifer Bruton"); dVector.addElement("Jennifer McManus"); dVector.addElement("Pascal Landais"); dVector.addElement("Robert Sadleir"); dVector.addElement("Paddy McNally"); dVector.addElement("Liam Barry"); dVector.addElement("Martin Collier"); dVector.addElement("Gabriel Muntaen"); dVector.addElement("Ovidiu Ghito"); dVector.addElement("Noel Murphy"); dVector.addElement("Noel O'Connor"); dVector.addElement("Stephen Daniels"); dVector.addElement("Ronan Scaife"); dVector.addElement("Anthony Holohan"); dVector.addElement("Marissa Condon"); dVector.addElement("Conor Brennan"); dVector.addElement("Paul Whelan"); dVector.addElement("Lisa O Reilly"); dVector.addElement("Sean Marlow"); dVector.addElement("Xiaojun Wang"); dVector.addElement("John Mallon"); dVector.addElement("Jim Dowling"); return dVector; } }

 Source: Search.java 


Step 4: Deployment

The deployment steps involve nothing new to anyone who has already deployed HTML and Java Servlets.  Simply put the HTML and JavaScript files into the root of your web application.  Create a new Java class in the WEB-INF/src directory as per normal for creating the Java Servlet.  Then compile, restarting Tomcat and test your Ajax application.  Type in the box and watch the application in action!

Note: In this example we have seen the involvement of HTML, DOM, JavaScript and the XMLHttpRequest objects.  However, we have had no real involvement with XML.  This is because we sent the raw HTML response back from our servlet.  In reality, for more complicated data structures XML would be used as the communicative approach.  However, for this introductory Ajax application, raw HTML works just fine and reduces some coding complication.


Deploying the Example Ajax Application Video

The following short video details the steps involved in deploying the Ajax application and the resulting output from the application.

Note: This video is slightly older and the new @WebServlet approach is taken.  The only changes are the inclusion of @WebServlet and the modification of the ajax_javascript.js file to make sure it is pointing at the correct URL  (now updated to /student/Search)

jQuery and Ajax

The code in the example above could be considered a little cumbersome, particularly in relation to the ajax_javascript.js file.  This becomes more apparently when it comes to applications with a considerable amount of Ajax functionality built into it.  Hence, it would be beneficial to be able to build Ajax based applications in a more streamlined and optimally coded manner.  For this purpose, let us introduce an old friend from earlier chapters: jQuery.
The jQuery library has a range of functionality which can aid with the deployment of Ajax applications.  Developers using Ajax may then used the jQuery approach for building Ajax applications and assume that all the underlying "plumbing" (handling the XmlHttpRequest object etc.) is handled transparently by jQuery.  

To demonstrate this, let us rewrite the above Ajax application using jQuery.  We will not touch the server-side application (search.java) as this is independent of jQuery being on the server-side.

To do this we will take our example from the jQuery section previously and modify it to add in the new functionality.  Let's take a look at our base "Hello World"  jQuery code again.
<html> 
<head>
<title>JQuery UI Example</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript"> 
$(document).ready(function()  
     alert("Page has loaded and is ready!"); 
}); 
</script> 

</head> 
<body> 
This is the body!
</body> 
</html> 
Source and Output: jquery_example.html

This is the only file we will be editing, so let us add in the HTML form and the new Ajax code.  
<html> 
<head>
<title>JQuery UI Example</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript"> 
$(document).ready(function()  
{
   // Removed the alert as it served no purpose for this app  
});

function showHint(str) {
if (str.length >= 1) {
$.get(
   "/student/Search?q=" + str,
            "",
   function(data) { 
    document.getElementById("txtHint").innerHTML=data;
   },
   "html"
);
} else 
document.getElementById("txtHint").innerHTML="No Suggestions";
}
</script> 

</head> 
<body> 
<h2>Search for Names</h2>
<p>Type in the box to search for names of lecturers in the School of Electronic Engineering:</p>

<form id="searchNames" method="GET" action="Path-to-the-target-of-the-form-which-we-are-not-currently-concerned-with">
<b>Search : </b>
<input type="text" autocomplete="off" onkeyup="showHint(this.value)" name="searchString" size="20" maxlength="30" />
<br/>
<input type="submit" value="Search" />
</form>

<br/>
<div class="box" id="autodiv1">
<span id="txtHint">No Suggestions</span>
</div>
</body> 
</html>

Essentially, to build this application we copied/pasted the code in the <body> section of the previous ajaxform.html example.  We also added the code shown in orange below.  As can be seen, this code is very similar to the showHint method in the previous javascript file.  Here we introduce the jQuery $.get function call, which facilitates the loading of a remote page using the GET request.  (Note: There is a similar call $.post to obviously facilitate POST requests).

$.get is normally formatted in the following way:
$.get({
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

url: (String) The URL of the page to load.  In our case, our server side application 'Search'
data (Optional): (Map) Key/value pairs that will be sent to the server.  We embedded the search data in the URL in our example, so did not use this option.
callback (Optional): (Function) A function to be executed whenever the data is loaded successfully.  This was where we set the contents of our suggestions.
type (Optional): (String) Type of data to be returned to callback function: “xml”, “html”, “script”, “json”, “jsonp”, or “text”.  In our example, we used HTML but a range of options are available.  For example, JSON would be a more suitable type of data to use in this example (however, we don't cover it and it would be a little more complicated).

While we don't see major coding reduction in the HTML page (if anything we've added some lines), we have entirely gotten rid of the need for the large JavaScript file we had previously.  Overall, jQuery provides us with the facility to shorten our Ajax code and make the code more robust, particularly in a cross-browser manner.

In Closing on Ajax

For the purpose of this module, you should be familiar with Ajax, the terminology and functionality of the technology. You should have an understanding of the code involved but will not be expected to reproduce the Ajax JavaScript code from memory.

You could however be provided with the majority of the JavaScript code and asked to write a HTML form calling a server-side application using Ajax. An example of such a question can be found from the EE448 2009 Exam Paper (Question 3(b)) 

You will not be asked to reproduce or memorise any Ajax jQuery code, but should have an understanding of it.


Comments