Tuesday, January 27, 2009

Separating Behaviour and Structure

The main reasons for using Ajax are the user experience improvement, a quicker page load due to a smaller page size and an implicit need to separate content, normally delivered as XHTML, presentation, by means of embedded CSS, and behavior. The latter is assumed to integrate Javascript accessing the DOM, the XMLHttpRequest object for a bidirectional communication with the server and a server-side language that receives requests and responds accordingly to the client. If your XHTML page is free from behavior tags and attributes your javascript code in the head of that page is said to be unobtrusive.

This separation is the basis of a web design strategy labeled as progressive enhancement. In essence, a web page must work whether it has stylesheets (presentation) enabled or not, and whether it has javascript (behavior) enabled or not.

Let’s concentrate on the behavior layer as many drawbacks refrain developers from using this set of techniques called Ajax in their applications. One is reliability of Javascript in the present-day maremagnum of differents browsers and versions. However, this shortcoming is being solved through javascript libraries that are being gradually more cross-browser. In our examples you’ll see Prototype 1.6 in action. Another big concern about using Ajax is accessibility. Is it possible to write only one version of a site that is accessible as well as Ajax?

There are several techniques to apply unobtrusive javascript to a site in order to acomplish the “one version site only” target and I'll try to explain them in different posts.

Let’s state some of the conditions of our document structure to assure that we can have an unobtrusive ajax application.

Javascript triggers

It is assumed that using the class and id attributes is a standard practice to separate presentation and structure in an HTML page. We say that CSS triggers the presentation of a website. By doing so, we can forget about inline presentation tags such as <span style="font-"> because the stylesheet file deploys the presentation attached to the class and id attributes.

The behavior layer of a web page should work in a similar way. Instead of the inline event handlers mixed with HTML, such as <html_tag onclick="javascript_function()" />, we can add JavaScript triggers to the HTML. This triggers tell the script where to deploy the behavior from.

There are basically two methods to trigger javascript:

Both methods have their advantages and drawbacks. IMHO, whether you prefer one or the other, is a matter of conscience or a phylosophical issue. Depending on the situation I prefer one to the other, or a mixture of both. I'll tell you more about that in a moment.

To introduce an example, imagine we want to attach a behavior to an input field to avoid sending an empty string to the server.

Using the first technique, we could add a custom attribute to the input field called "required" with a value of "true". This will be the hook to the behavior in the js file.

<input type="text" name="email" required="true" />

Using the second technique, we add a valid class attribute to the input field with a value of required.

<input type="text" name="email" class="required" />

Other valid attributes to trigger javascript

There is another alternative to hook javascript to the HTML structure. Why not use the rel attribute instead of the class or id attributes to attach the JavaScript behavior?

We normally use the class/id attributes as a hook to the presentation layer (CSS). Mixing presentation and behavior in the same HTML attribute seems to be against the idea of separating presentation and behavior. But there is an alternative. We can use the rel attribute for the behavior (JavaScript). Here's an example of the markup required:

<a href="destination_url" rel="popup">

Is it acceptable to use the HTML rel attribute to accomplish our goal? What is the meaning of rel in HTML?

Rel stands for "relationship". When used in the a tag, the rel attribute is used to provide information about the relationship between the target url page and the actual page. This attribute can take any value, even a series of space separated values. The same happens with the class attribute but not the id which must have a unique value. Browsers don't use this attribute for any rendering effect or behavior change. It's pure semantic markup.

The real value of the rel attribute is mainly to add behavior via Javascript. However, it can only be used correctly in the a and link tags and that's a big difference from class and id which ara core attributes and thus can be used in any HTML tag.

Reasonable names for behavior triggers

Many XHTML coders understand that it is not correct to have a class with value red to format a text in order to emphasize its content: <span class="red">Error: the address field is required</span>. The reason is obvious. This class value carries presentation information, not semantic. Presentation information should be in the CSS file, not in the XHTML code. One solution is to find a name that carries information about the reason why that text is presented in a different way (now red, but perhaps the CSS designer could change it into a dark red and bold text some day. Then, the value red in the class attribute would become obsolete). The reason is that the user forgot to fill a field in a form. There is an error. That's the meaning, the semantic information. Thus, the value for that class could be "error" or "required". None of them carries information about the presentation of those classes. The responsible for the presentation is the CSS file.

In a similar way, names attached to class/id attributes in the XHTML code to trigger javascript should have a semantic value, not behavioral meaning. It's very subtle, but you are warned to think a bit when you have to find a name for a behavior trigger. For example, you may think that the previous <a href="destination_url" rel="popup"> has a correct value in the rel attribute. But that's not true as the "popup" is carrying a very clear behavioral meaning. It suggests that when you click this link a new popup window will open. But we could change this behavior and display the content of the target link into a div in the same page, or open a new tab, or whatever other behavior we can think of. What would be a proper name, then? Well, I can think of names like "externalLink", "outLink", ... The js file will trigger some behavior for those links in the XHTML page with a value of "outLink" in its rel attribute. In the end, we have accomplished what is called behavioral separation.