dotMobimobiThinkingmobiForgemobiReadyDeviceAtlasgoMobi
background image

Getting started with Mobile AJAX

Section Feature Image
Posted by ruadhan - 21 Aug 2007
Twitter share icon Facebook share icon Google Plus share icon

Mobile AJAX is a term that's hot right now in the industry - we are seeing it mentioned more and more every day. This article will give an overview AJAX from a mobile web point of view. But before we talk about mobile AJAX in particular, we should say a little about what AJAX means.

The term AJAX was coined by Jesse James Garrett about a new approach to web applications. The AJAX acronym stands for Asynchronous JavaScript And XML. AJAX isn't a new technology in itself; instead, the AJAX term refers to the collection of existing and proven web technologies, which are being used together in a new way to create a new generation of responsive, interactive web application. Pioneering examples of the AJAX approach include Google Maps and Gmail. The building blocks of AJAX applications are:

  • standards-based presentation in the browser using XHTML and CSS
  • use of the Document Object Model (DOM) for dynamic display and interaction within the browser
  • data interchange and manipulation using XML and XSLT
  • asynchronous data retrieval from a server application using XMLHttpRequest, and
  • JavaScript to glue everything together

Since AJAX facilitates interaction with parts of a webpage, rather than the good old-fashioned click-and-reload-whole-page paradigm we grew up with, the approach results in a more responsive application with lower bandwidth usage, and better user experience overall. Its is worth noting that all of these factors are burning issues in mobile, which perhaps underscores the interest in AJAX for mobile applications.

"The power of an AJAX application over traditional software development is the fact that the code is relatively portable across operating systems, versioned and distributed from a central location, and authored in a high-level scripting language."

Put simply, mobile AJAX is the application of the AJAX approach to mobile. As with many things mobile, the reality is not that simple, for mobile AJAX has to deal with all the typical constraints of mobile devices, browsers, and data bandwidth. However, if AJAX can work the same magic on mobile web UI as it has done for desktop web UI then things could get very sexy. Applications from companies such as Soonr have already given us a glimpse of what is possible. It is worth mentioning too that some other efforts that have been made toward improving the mobile browsing experience e.g SVG (Scalable Vector Graphics) and Flash Lite. Some also believe that due to the ubiquity of the browser, mobile AJAX has the potential to become the technology of preference for mobile (surpassing even J2ME), just as it has on the desktop

Mobile Widgets are also topical right now and relevent to this discussion. Mobile widgets are narrowly focussed standalone (web) apps, which are installed onto the mobile device. The main advantages over traditional mobile web applications are that the code-base (and usually any required resources such as images) are already on the device (less data to download and more cash in your pocket), and also that they are usually invoked by a friendly easily-identifiable icon (no messing about with mobile browsers and bookmarks). So widgets help overcome two prominent barriers for user adoption. This has led some to claim that mobile widgets hold the key to true mobile web ubiquity - most users just won't realise they're using it! On the other hand, widgets typically need to be installed on the phone by the user, whereas the browser is likely to be already there. In summation, mobile widgets often use components of AJAX, namely the asynchronous data transfer. Also, with the coming of the iPhone which makes use of widgets, their usage is sure to grow.

So, now we have a rough idea of what mobile AJAX is, let's look at some of the details. What about support for mobile AJAX and what are the minimum browser requirements? Fundamentally, mobile AJAX is no different from its desktop counterpart. The XMLHttpRequest object (or equivalent MS ActiveX implementation) is used for asynchronous data transfer, and Javascript DOM manipulation handles the rendering on the browser.

So, at a minimum, the mobile browser must support the XMLHttpRequest object, and must have at least some basic Javascript support so that it can modify parts of the current document without a page reload being required (the innerHTML property can facilitate this). So, what current mobile browsers meet these requirements?

The following browsers are known to support AJAX to some degree:

  • Opera Mobile (>= 8.x, not Opera Mini)
  • Internet Explorer Mobile (WM 5.0/2003)
  • S60 3rd edition (WebKit/KHTML core)
  • Minimo (Gecko-based)
  • OpenWave (>=Mercury)
  • NetFront (>=3.4)
  • Safari Mobile (iPhone)

So, support for AJAX is become more widespread within in mobile browsers. Indeed, some authors believe that AJAX may well become the preferred UI technology for mobile, perhaps even surpassing J2ME as a framework. However there are still many device/browser combinations which fail on one or other of the requirements. Thus, developers should proceed with caution! A good practice is to start off with a minimal non-AJAX interface, and to incrementally add gracefully degrading AJAX into the mix.

Writing AJAX applications


Ajax coding for desktop web has become much less of a black art than it used to be. This is largely due to the number of AJAX-supporting frameworks that have been written. For instance Prototype, and the Yahoo! User Interface Library (YUI) are but two such libraries that abstract away the fine details and enable the user to make high-level AJAX invocations by supplying functions and classes such as the Prototype AJAX class, and the YUI AJAX class. For example, a cross-browser AJAX request can be generated with the following code using the Prototype library:

new Ajax.Request(URL [,options])

where options allow you to configure how the request, and how the response will be handled.

However, these libraries have been designed with desktop usage in mind, and for this reason are usually too bloated with complex features to be deployed for mobile usage. There is currently at least one framework in the pipeline (FROST), which can be included as a Javascript include in a web page. One of the goals of the authors of FROST is that the JS framework sent to the device dynamically adapts according to the level of AJAX support by the device. The authors also have plans to feed their data back into WURFL.

FROST also provides an AJAX support test page - if you point your mobile browser at http://pwmwa.com/frost, it will perform a number of tests, and report on whether they were successful or not.

There are a number of "AJAX platforms" which form another class of AJAX-enabled application. This class includes the platform known as "mojax" and another called "bling". While these applications use AJAX, they do not run in the web browser. Rather they run as an application on the device, and have access to the hardware APIs. They are more like widget platforms in this regard.

Getting started - the basics

Making an XMLHttpRequest

The XMLHttpRequest is at the core of AJAX - it allows the request of data without reloading the page. To make an XMLHttpRequest, an XMLHttpRequest object must be created. The code to do this is straightforward, but you should be aware that Microsoft has a different but equivalent implementation. To build an XMLHttpRequest object you use either the code below:

req = new XMLHttpRequest();
or use

req = new ActiveXObject(Microsoft.XMLHTTP);
For convenience we can wrap it all up in a Javascript function:
//Get an XMLHttpRequest, object
function getXHR() {
  if(window.XMLHttpRequest) {
    req = new XMLHttpRequest();
    return true;
  } else try {
    req = new ActiveXObject('Msxml2.XMLHTTP');
    return true;
  } catch(e) {
    try {
      req = new ActiveXObject("Microsoft.XMLHTTP");
      return true;
    } catch(e) {
      req = false;
      return false;
    }
  }
}
Having obtained an XMLHttpRequest object req, we can now open a HTTP connection with it:

req.open('POST', url, true);
The first argument specifies the HTTP request method to use (GET, POST, HEAD for example). The second argument is the URL to request. The third argument specifies if the request should be asynchronous, or if processing should halt until a response is received. In most cases you would want to set this to true. There are other variations of the open method which can specify authentication parameters (see reference below).

When we are ready to send the request, we use the send method e.g.

send('');
After we send the request, we must monitor its state so that we can tell if it has completed. We do this by defining a callback function to be invoked when a response is ready. Such a function checks that the readyState property of the XMLHttpRequest object contains a completion code, and then checks that the server returned an HTTP status code of 200. This function could look something like this:

function ajaxCallback() {
  if(req.readyState == 4) {
    if(req.status == 200) {
      //Do something with the response
    }
  }
}

To see what data the request object returned we can use the responseText or responseXml properties (see properties reference table below). The first is a string representation of the data returned from the server, and the second is a DOM-compatible version. Once we have made an XMLHttpRequest, we will often need to update XHTML page elements based on the data retrieved. To do this we can use the innerHTML property. For example, to change the HTML content of an element with id 'someElement' to display 'some text' we can use:

document.getElementById('someElement').innerHTML = 'some text';
So, putting these together we can update the contents of an element to reflect the data returned by the server using the following code:

document.getElementById('someElement').innerHTML = req.responseText;
Taking all the above together, we can write a simple AJAX application. We will write an application that updates an element on the webpage with the current server time when a link is clicked in the mobile browser. This consists of:
  • A webpage which contains the AJAX enabled link
  • When clicked, this link will make an AJAX request to the server - the server will retrieve some data and send it back to the device
  • When the device receives the data, it will update a page element with the data
  • If the device does not support AJAX, then it will automatically fall back to do a non-AJAX approach to fetch the data

So, first the webpage:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.1//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
       <script type="text/javascript" src="majax.js"></script>
       <title>mobiForge mAjax</title>
   </head>
   <body>
      <div> 
         <a href="fallbackTime.php"
             onclick="return updateElm('getTime.php', 'timeDiv');" >Get server time</a>
         <div id='timeDiv'>No ajax data yet</div>
      </div>
   </body>
</html>
This is straightforward - the main things to note are:
  • the inclusion of the "majax.js" javascript file - this contains the functions outlined above, namely the code to create and XMLHttpRequest object, and code to update an element based on data retrieved (see below)
  • the link: <a href="fallbackTime.php" onclick="return updateElm('getTime.php', 'timeDiv');" >Get server time</a>
    First note the onclick attribute - it calls an function updateElem() which is defined in majax.js. The onclick event invokes this function.

function updateElm(url, id) {
  if(getXHR()) {
    req.open('POST', url, true);
    req.onreadystatechange = function() {
      if(req.readyState == 4) {
        if(req.status == 200) {
          document.getElementById(id).innerHTML = req.responseText;
        } else {
          document.getElementById(id).innerHTML = 'Could not retrieve data';
        }   
        req.send('');
      }
      else return true;
    return false;
  }
}
So when the user clicks the link on a AJAX suppoting device, the function updateElm is called, with the URL getTime.php, and the name of the element to update (in this case timeDiv).
Next updateElem gets a reference to an XMLHttpRequest object (getXHR()), opens a connection with the url, and specifies the callback function.
The callback function checks that the request has completed (req.readyState==4) and that the HTTP status code is 200.
This function also specifies that on success, the element with id 'id' is updated with the data contained in the response of the XMLHttpRequest.

And here's how the fallback for the AJAX-challenged device works. If the function invoked by the onlcik event returns false then the url specified in the href attribute WILL NOT be followed by the browser. Otherwise the browser will follow the link. So, if everything worked OK, then we return false - there is no need to follow the link (this is slightly counter-intuitive). Otherwise, if we return true (say if the XMLHttpRequest didn't work) then the link will be followed.

The href attribute simply points to a PHP page which loads a whole page that contains the desired data i.e. it does it the old fashioned way.

Next we have the pages that generate the data - the first is the url that is requested if AJAX DOES work:
getTime.php:

<?php
   echo date('l dS \of F Y h:i:s A');
?>
Not much explanation needed here - the page calls the PHP date() function to get the current date, and this is simply written to the response. Of course we could substitute this data with any kind of interesting data such as stock quotes, weather forecast, traffic reports etc.

Finally, the fallback is a PHP is an entire page, which looks like the original page, but contains the new data:

<?php echo '<?xml version="1.0" encoding="UTF-8"?>'?>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.1//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8" />
      <script type="text/javascript" src="majax.js"></script>
      <title>mobiForge mAjax</title>
   </head>
   <body>
      <div>
         <a href="fallbackTime.php?uid=<?php echo uniqid(); ?>" 
              onclick="return updateElm('getTime.php', 'timeDiv');" >Get server time</a>
         <div id='timeDiv'><?php echo date('l dS \of F Y h:i:s A'); ?></div>
      </div>
   </body>
</html>


This example is running on http://mobiforge.com/m/majax/1/t1.htm and is available to download at the end of this article.
So that's it - we demonstrated a very simple way to perform an AJAX update on a mobile webpage, and ensured that there is graceful degradation when AJAX is not supported by the client device.

But apart from the smaller data download, and the smoother update of the page element, maybe we could improve the visual benefit of the AJAX version. Enter the animated icon! We can achieve this by displaying a "loading..." image until we have retrieved the data, and then by removing this image and displaying the actual data when it has completed.

This is very simple to implement - we use innerHTML to display the animated image until the data has been loaded.
document.getElementById(id).innerHTML = '<img src="ajaxImage.gif" />';

When the XMLHttpRequest has completed we simply swap out the animated image and replace with the actual data as before - so our code becomes:

if(req.readyState == 4) {
  document.getElementById(id).innerHTML = req.responseText;
} else  {
  document.getElementById(id).innerHTML = '<img src="ajax-loader.gif" />';
}


This example is running on http://mobiforge.com/m/majax/2/t1.htm and is available to download below.

Good mobile AJAX practices

  • AJAH (asynchronous Javascript and XHTML), AHAH (Asynchronous HTML and HTTP)
    XML manipulation on mobile devices is quite processor-intensive. Such operations can have a significant drain on the battery life of a device. The developer should exercise prudence. One way to address this drain is to offload processor-intensive operations such as XML manipulation to the server. Only preformatted HTML is sent back to the client, thus reducing the amount of work required by the client. This approach has the added benefit that the page will render more quickly too since the result has been pre-formatted.

  • Plan to build a normal non-AJAX site, and iteratively add AJAX to it.



References

FROST framework project http://www.pavingways.com/frost-ajax-library/
mAJAX FAQ http://www.horizonchannel.com/archives/26

XMLHttpRequest API Reference

Methods of XMLHttpRequest Object

abort()
Aborts the current request
getAllResponseHeaders() Returns all response headers
getResponseHeader(headerName) Returns a single response header headerName
open(method, URI [,async] [,username] [,password])

Specifies parameters of a request:

method - the HTTP method to use e.g. GET, POST, HEAD
URI - the URI to request
async - boolean to specify if the request should be asynchronous
username - username for authentication
password - password for authentication

send(content)Makes the request
setRequestHeader(name, value) Specifies a request header to send



Properties of XMLHttpRequest Object

onreadystatechange
Reference to an event handler that is invoked every time the readyState changes
readyState

Represents the state of the XMLHttpRequest object. Possible values are:

0 - Unitialised
1 - Open
2 - Sent request
3 - Receiving response
4 - Completed

responseText String representation of the response
responseXML DOM representation of the response
status HTTP status code of the response
statusText String representation of HTTP status code of response

 

AttachmentSize
example1.tar.gz1.14 KB
example2.tar.gz2.76 KB

Posted by ruadhan - 21 Aug 2007

ruadhan's picture

Mobile Web Guy

@rodono
+RuadhanODonoghue

Posted by theo1985 6 years ago

Awesome article!
Thanks!

Posted by hadoken13 5 years ago

Great stuff!
Keep up the good work.

Posted by zaldip 4 years ago

Hi thanks man, u r doing gr8 job...
One question pls ...
How stable is Ajax on mobile?
I mean it would be gr8 If you can put some light on limitations of Ajax on mobile