A little Ajax library that makes a difference

It is a typical situation in the web developing arena that when a new technology emerges so strongly as Ajax or the so called Web 2.0 have done, programmers tend to use it to their last consequences. So we may go from a nearly 100% server side-processing-with-pages-refresh paradigm to establish multiple HTTPRequest petitions on every little interaction between the visitors and our application, to better serve their user experience.

But as some people have warned us before (on uk.builder.com, on the wikipedia, or dhtmlnirvana.com), there are some trade-offs in abusing from these technologies, so we should better stay in middle ground, picking accurately where to put the magic.

One of my favourite scenarios for implementing some Ajax stuff is when I have to render a tabulated list of elements. Depending on the number of properties that compose a given row, we may have to show a great number of columns, which compromises the layout of our site and also forces the user to visually parse the information all at once.

An elegant solution to this problem could be to show only the most relevant columns, and when the user clicks on an element we make a background call to our server and show the rest of the information, expanding the row of the object to accommodate it.

By using Ajax this call is transparent to the user, providing him with an agile way to focus on the stuff he is most interested in. You can find a lightweight library that implements this functionality at dhtmlgoodies.com, along with lots of other amazing stuff. Let's see how it works: This is a showNode() javascript function, when called loads the content of some_url.html and displays it onto the initially hidden div:

<a href="http://www.harecoded.com/wp-admin/post.php#" mce_href="http://www.harecoded.com/wp-admin/post.php#" tal:content="item/filename"
title="${item/shortname}" onclick="showNode('${item/ref_object}','${item/href}details')" />
<div id="window_${item/ref_object}" class="hidden" class2="${item/class}"></div>

Please bear with the screwed html, it's wordpress' fault and my lack of energy right now to search for the workaround :-)

//Useful for loading content via ajax
//Afterwards it changes the div container from hidden to visible
function showNode(id,url){
var id ='window_'+id;
obj= document.getElementById(id);
if(class2 = obj.getAttribute('class2')) {
alterClass = class2;
}else {
alterClass = "";
}
if (obj.className == 'hidden') {
obj.className = alterClass;
}else {
obj.className = 'hidden';
}
loadAjaxContent(url,id);
}

The following javascript code comes directly from the dhtmlgoodies library, and creates the Ajax connection:

var peticion = false;
try {
peticion = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
peticion = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
peticion = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
peticion = false;
}
}
}
if (!peticion) alert("Ajax error");

function loadAjaxContent(fragment_url, element_id) {
var element = document.getElementById(element_id);
element.innerHTML = '__img xsrc="/themes/Default/img/animated/loading.gif" mce_src="/themes/Default/img/animated/loading.gif" alt="loading..." /__';
peticion.open("GET", fragment_url);
peticion.onreadystatechange = function() {
if (peticion.readyState == 4) {
element.innerHTML = peticion.responseText;
}
}
peticion.send(null);
}

So let's keep moving. The following code is the xhtml view (some_url.html) that is requested from the HTTPRequest call, extracted from an app I am developing right now with Albert. In case you wonder what are exactly these strange tal:content and tal:condition tags, they belong to the PHPTAL templating system, which you can find here.

< -- ?xml version="1.0" encoding="ISO-8859-1"?>
< --!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
< --html xmlns="http://www.w3.org/1999/xhtml">
< --body>

< --div id="fileproperties" metal:define-macro="render">

< --table summary="sampleContent" width="100%" style="font-size:1em;" tal:condition="task_updates">

< --tbody>

< --tr valign="top">
< --td colspan="2">
< --tal :block repeat="item task_updates">
< --img xsrc="${theme_path}img/buttons/updates.gif" mce_src="${theme_path}img/buttons/updates.gif" />
< --span tal:content="item/update_time"> - < --/span>
< --br />
< --/tal>
< --/td>
< --/tr>

< --/tbody>
< --/table>
< --/div>

< --/body>
< --/html>

The very first thing we should do to enhace this exercise should be to implement some visual notification mechanism with CSS to better grab the attention from the users that something has changed on the screen with their operations, maybe remorselessly copying the famous basecamp. I assure you this way of dinamically loading content is infectious, you only have to implement it once to start thinking you can take profit from this library in a lot of situations, almost immediately. But keep in mind it is easy to fall on the dark side, don't just use all the dhtmlgoodies libraries all at once :-)