Ajax and the true separation of presentation, content and behavior
Contrary to what some may argue, you can use Ajax technologies in web applications and keep your code clean and separated from your presentation markup and content.
To kick off this column on Web Application development, I am going to address this issue with the 3 simple rules I used while working on the Form Builder.
Note: cross-browser considerations intentionally left out.
Rule #1: Use unobtrusive javascript
Don’t embed javascript inside your tags.
<a href="..." onclick="dostuff();"> do stuff </a>
This is just as bad as inline CSS or font tags.
Instead, do:
<a href="..." id="stuffDoer"> do stuff </a>
and have a separate javascript file, linked from the <head> of your page, with something like this :
document.addEventListener ('load', function() {
document.getElementById('stuffDoer').onclick = doStuff; }, false);
See also these other recommendations.
Rule #2: Do not use javascript to generate markup
Or let me put it this way: build template driven applications. Use XMLHTTPRequest or XSLT to retrieve XHTML formatted strings, and insert them in your document.
The insertion point is identified by a placeholder, often an empty DIV element:
<div id="my_placeholder"></div>
For XHTML generated server side, use XMLHttpRequest:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", someResourceURI, true);
xmlhttp.onreadystatechange= function() {
if (xmlhttp.readyState==4) {
document.getElementById('my_placeholder').innerHTML = xmlhttp.responseText;
}
xmlhttp.send()
For XHTML generated client-side, use XSLT:
var processor = new XSLTProcessor();
processor.importStylesheet(your_xsl_template);
var xhtml = processor.transformToDocument(your_xml_data);
document.getElementById('my_placeholder').importNode(xhtml);
Note: The Sarissa wrapper provides a uniform syntax across browsers for all Ajax related coding.
Rule #3: Do not use javascript to style your content
Don’t do
document.getElementById('some_id').style.color = '#ff0000';
Instead do:
document.getElementById('some_id').className = 'some_class';
and set the color property in your CSS stylesheet
.some_class {
color: #ff0000;
}
If you are trying to achieve a visual effect, you may want to consider class switching:
document.getElementById('some_id').className.replace('old_class','new_class');
That’s it for today. What do you think?
Technorati Tags: Ajax, Web Development
April 11th, 2005 at 10:18 pm
I’m going to have to disagree on point #2, or at least argue with your solution.
It seems that if you’re trying to construct a ‘pure’ Ajax application, you’ll only be receiving XML data from the server and then manipulating that data into it’s final form. Granted, XSLT is the perfect tool for the job, but is simply isn’t supported on enough browsers (leaving Safari and Opera users out in the cold seems kind of harsh, considering their popularity). Constructing HTML on the server side is definitely not the best way to go about this, in my opinion.
April 12th, 2005 at 9:28 am
John, thanks for your comment. On the subject of receiving XML data from the server (even though xmlhttprequest is not limited to XML) you can very well receive XHMTL fragments that are valid XML. You just need to remove the xml prolog before you can ‘paste’ it in your page.
As for XSLT, I really hope Safari & Opera will support it soon. But they are still playing catch up on XMLHttpRequest..
I think that with 90+% of the browser market currently supporting XSLT, you have a solid base to build XSLT-based application. For the 10% left, I’m pretty sure one can set up a mechanism (via XMLHttpRequest or Iframes ?) to offload the XSL transformation to the server.
April 12th, 2005 at 7:57 pm
Nice list of dos and don’ts. Only thing I haven’t been using myself is XSLT-transformations, but it is obviously the leaner way to keep data and presentation separated when using AJAX. I’ll have to play around with XSLT a bit, I’m sure Opera and Safari will catch up on it.
Until then, one could write proprietary JavaScripts suited for doing the “XSLT” transformation for uncapable browsers… Or maybe it is cleaner to have the server-side script use a html-template (or a server side XSL transformer) for the data it sends, and just strip of the xml prolog on the client side.. That way you’ll keep most of the “template” idea for the presentational layer for browsers uncapable of XSLT..
July 26th, 2005 at 12:10 am
Good stuff.
About XSLT support: let XSLT+XML do their ‘magic’ job, the browser and the server side transformation should generate the same output, so with a browser sniffer script you can use *exactly* the same XSLT and XML stuff to be rendered in the side with XSLT support. So you don’t have to worry a lot about the support lack.
Thing are fitting better each day.
good luck.
August 14th, 2007 at 9:14 am
WOW!
I had no idea you could replace the class name so easily!
The only way I knew how was to use the setAttribute() thing.
AND, I would never have come up with the using a class switch to make a visual change!
10/10!!
February 28th, 2008 at 10:51 pm
Excellent! I was looking for a way to implement generic pages that contain lists of items and include filters for those lists (as in Mozilla Thunderbird, for example, where you can select mail messages from a particular person). Your ideas cover perfectly and cleanly this case and many more.
Thanks a lot for your beautiful idea!