By Mark Bierbeck:

Ajax, Hard Facts, Brass Tacks ... and Bad Slacks

A number of people have contacted me recently about Ajax [1] -- a catchy name -- coined to provide an umbrella term for a particular group of technologies used to build web applications. The use of the word comes from Jesse James Garrett in a recent blog [2], and describes a class of internet applications written using JavaScript in a browser. By using JavaScript these apps have full access to the DOM, and as a consequence are able to make all sorts of changes to the page that the user is interacting with, without having to go back to the server.

When the application does need to go back to the server -- to deliver some data and get a response -- the idea is to keep the DOM intact so that the user has a smooth experience. This means that all communication with the server needs to take place outside of the normal HTML form mechanism, since this would obviously replace the current page.

Ajax addressed this, with what it calls 'asynchronous-JavaScript' -- retrieve only the data you need, and then directly manipulate the DOM to get the effect you want. 'Asynchronous-JavaScript' accounts for the first few letters of the name, with the remainder being the obligatory 'X' for XML (although XML is not really key to this technology, and many of the applications that are often cited as Ajax-apps don't use XML as the data medium).

Buzzing

The response to Ajax has been pretty positive. In fact the only negatives have been either to suggest a change of name or to moan a little that "I've been doing this for years, why hasn't anyone noticed me?" (I won't put any links to those sort of articles, since they are a little embarassing -- after all, everyone has been doing this for years!)

Anyway, despite a couple of sour-pusses, the software community is almost universally excited, and the blog wires have glowed over the last few months with descriptions of Google Maps, GMail, and so on.

Just about everyone who has asked me about Ajax has expected me to be disappointed. Surely, they say, this makes the case for XForms weaker? But my answer is the exact opposite -- XForms and standards-based web applications are in every way superior to the techniques described as Ajax, since the whole raison d'être of XForms and XHTML 2 is to address the very problems that Ajax-like techniques suffer from.

That may come across as a little bold...so perhaps I should explain.

From Workaround to Feature

We've all been using HTML mark-up for years now, and the language hasn't changed much in that time. As a consequence, the increasing demand for more complex web-pages has meant that the balance in our documents has shifted increasingly from vanilla mark-up to 'the workaround'.

Whether it's providing tooltips, dynamic/repeating data sections, or small portions of our page that change without having to request a new document, we've generally had to dive into script. But the shift from mark-up to script has meant that the mark-up language itself has been relegated to a mere carrier for programs.

Unfortunately this means that no-one gains -- it's annoying for the programmer to have to produce ever more convoluted spaghetti JavaScript to meet the demands of their audience, but it's also annoying for the non-programmer, who probably only wants a tooltip. And its particularly annoying for those who want to use documents on the web for more ambitious applications to find that most of the important stuff in a document is hidden away in script.

All is not lost, however, since this collection of 'workarounds' provides a rich source of real-life patterns that appear for authors and programmers, time and again. They may be workarounds, but they are much-needed ones.

The aim of the new generation of languages like XForms and XHTML 2 is to take these 'common patterns' and turn them into mark-up. Just like the HTML elements <a> and <form> pack an enormous amount of functionality into deceptively simple tags, so too can new declarative mark-up capture patterns that have emerged 'in the wild'.

(Note that this is the opposite of so-called folksonomies, where popular practice that occurs in the wild is left it the wild, and codification is regarded as a dirty word.)

The XML HTTP Request Object

Let's take the much talked about XML HTTP Request Object (XMLHttpRequest). If you are not familiar with it, it was originally part of Microsoft's XML parser, and allows you to send and receive data outside of the normal HTML form processing. Since it's a handy feature to have in a client, other browsers have followed suit and it's now becoming the 'standard' way to communicate with servers without messing up your page. It's a corner-stone of Ajax. (A good summary with examples is on Jim Ley's jibbering.com site [3].)

But...we need to be clear that we're using XMLHttpRequest to get round a weakness in HTML forms. The problem we have is that even if you know that a server is about to give you some data, and the server knows it's about to give you some data, there's no way to tell your form that -- instead your page will be wiped out and replaced with whatever the server sends back.

Of course, constant round-tripping doesn't make it completely impossible to produce applications, and a lot of books and airline tickets are bought every day without the facility to get 'just the data'. But we all know it would reduce network traffic and create a smoother user experience if we could just send a list of books or seats, rather than a whole new page.

Over the years applications such as Microsoft's Outlook Web Access (OWA), have had to step around the HTML form to get just the data they need. But, whilst OWA considerably predates GMail, until the advent of XMLHttpRequest, the techniques used were quite difficult to manage. (Google Suggest is often cited as a good example of an Ajax-app, but interestingly merges old and new techniques; XMLHttpRequest is used to obtain a piece of JavaScript from a server, and this script contains a call to a client-side function, but using server-provided parameters. It's one of the techniques you might have used in the past with a hidden frame.)

So as many have said on their blogs, XMLHttpRequest is not a newly devised technique, but rather a generally accepted replacement for a very old technique. But ultimately that technique is a workaround since the real problem is that HTML forms will always replace the current page.


Beyond HTML Forms

Whilst XMLHttpRequest gives us a way to get data to and from the server without losing our document, we've unfortunately thrown the baby out with the bath-water; whatever the weaknesses of HTML forms, you have to acknowledge that they are pretty simple to use. Here's an abbreviated version of Google's search form (note that the mark-up is HTML, not XML):

<form action=/search name=f>
<input type=hidden name=hl value=en>
<input maxLength=256 size=55 name=q value="">
<input type=submit value="Google Search" name=btnG>
</form>

As you can see, the simple problem with HTML forms is that we don't say anything about where the data should go when we've received it from the server. The assumption in HTML of old is that we are just doing a kind of 'super-navigation', and no matter what we send to the server, it will only ever give us back a new web-page. (To put it a different way, you could say that <a> and <form> are pretty much the same thing.)

To see how this problem is resolved, let's code the same Google search in XForms:

<xf:submission id="sub-search"
action="http://www.google.com/complete/search?hl=en"
method="get" separator="&"
replace="all"
/>

<xf:input ref="q">
<xf:label>Query:</xf:label>
</xf:input>

<xf:submit submission="sub-search">
<xf:label>Google Search</xf:label>
</xf:submit>

Although it will do exactly the same -- right down to replacing the current page -- it's a little different to the HTML mark-up. But the changes in structure have given us some major benefits, from accessible labels on our form controls, to the possibility of many different submissions for the same data.

But what it has also given us is the possibility of solving our data update problem. The replace attribute is actually optional in XForms, but I showed it in the previous mark-up so that you can compare it to this:

<xf:submission id="sub-search"
action="http://www.google.com/complete/search?hl=en"
method="get" separator="&"
replace="instance"
/>

In this example the data returned from the server will just replace the instance that was sent, and our page will remain completely intact. (The replace attribute can take the values all, instance, or none.)

I won't show the full equivalent using XMLHttpRequest since it's pretty large, but I'll give a flavour of it. (Jim Ley's page -- referenced earlier -- shows how to search Google with XMLHttpRequest.)

The Script Version

First we need to create an XMLHttpRequest object, but we need to do it in such a way that it will work on both Mozilla and IE:

var req;

function loadXMLDoc(url) {
// native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = readyStateChange;
req.open("GET", url, true);
req.send(null);
// IE/Windows ActiveX version
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = readyStateChange;
req.open("GET", url, true);
req.send();
}
}
}

When a document is loaded via this function, the readyStateChange() method is invoked:

function readyStateChange() {
// '4' means document "loaded"
if (req.readyState == 4) {
// 200 means "OK"
if (req.status == 200) {
// do something here
} else {
// error processing here
}
}
}

From a programming point of view, I guess you could say that there isn't a lot wrong with this, but then from a programming point of view there wasn't a lot wrong with Z80 or 6502 assembly languages -- I just wouldn't want to go back to them!

But the most important issue is that we have lost the very thing that was responsible for HTML's success -- the use of simple, clear, declarative mark-up, in which we simply state our intent, without having to write a program to do it for us. After all, the web took off because authors only had to master <a> in order to enter the exciting new world of 'hypertext' -- but XMLHttpRequest raises the bar again, and takes us right back into the heart of geek-world.

Beyond XMLHttpRequest

But in keeping with the principle that I outlined above -- that XForms and XHTML 2 try to provide mark-up for commonly existing design patterns -- let's see if there are any other patterns that XMLHttpRequest has thrown up.

You will have noticed in the earlier script that we had tests for success and failure:

if (req.status == 200) {
// do something here
} else {
// error processing here
}

XForms provides the same functionality through the use of events -- on success do this, on failure do that. This is far more powerful, since it hides the protocol-specific aspects of this code ("200" may be 'success' for HTTP, but it isn't 'success' when saving data to the hard-drive or sending an email).

XForms uses declarative mark-up to express those events, which again dramatically reduces coding:

<xf:action ev:observer="sub-search" ev:event="xforms-submit-error">
<xf:message level="modal">
Submission failed
</xf:message>
</xf:action>

But there's lots, lots more in the submission part of XForms:

  • it can provide full XML Schema validation before submitting the data;

  • there is built in support for numerous types of serialisation, such as multipart/related;

  • abstract methods are used so the code is independent of protocol. For example, since put means the same thing whether the target URL begins http: or file:, a form with relative paths will run unchanged on a local machine or a web server;

  • it's extensible -- in formsPlayer 2.0 we have used the submission element to read and write from an ADO database, allowing programmers to convert forms from using the web to using a local database by doing nothing more than changing a single target URL. (Try doing that with XMLHttpRequest!)



The submission part of XForms is in fact so powerful that it will eventually form a separate specification, for use in other languages.

From Patterns to Mark-up

And there are plenty more patterns out there that were crying out to be turned into mark-up, and which are now incorporated into XForms and XHTML 2. Do you remember the days when if we wanted a tooltip that contained mark-up -- perhaps an image, or bold text -- we had to use a carefully placed <div>, a CSS display: none;, a mouseover event handler and a timer? Nowadays the programmer with better things to do than work with spaghetti-JavaScript just uses the XForms <hint> element, and for free they get platform independence (and therefore accessibility), as well as the ability to insert any mark-up.

And what about the days when we had to write code to open up a text-to-speech engine, and then invoke the various methods on the object to get it to speak its mind? Nowadays who wouldn't just use a CSS property on their XForms' messages?

Bad Slacks

And do you remember...I'm sorry, this one always makes me laugh...do you remember how we used to write lots of JavaScript to recalculate the shopping-cart when a new item was added? I know it's hard to believe -- it's like looking at old photos of us all wearing flares. Anyway, thank God for straight trousers and the XForms dependency-engine.


But enough of the good old days, the days of assembly language, C and JavaScript...let's stick with the new.

Do Try This at Home


To round all of this off, we'll take a look at Google Suggest, and we'll use XForms to implement it. I'll walk through the demo in a separate blog [4] so that this one doesn't get too cluttered -- and hopefully by disecting this simple but useful application, we can show how declarative mark-up scores over scripting.


[1] Will AJAX help Google clean up?, c|net, http://news.com.com/Will+AJAX+help+Google+clean+up/2100-1032_3-5621010.html

[2] Ajax: A New Approach to Web Applications, Jesse James Garrett, Adaptive Path blog, http://www.adaptivepath.com/publications/essays/archives/000385.php

[3] Using the XML HTTP Request object, http://jibbering.com/2002/4/httprequest.html

[4] "Google Suggest" Using XForms, http://internet-apps.blogspot.com/2005/04/google-suggest-using-xforms.html

Tags: | | | |