Thursday, July 17, 2008

CSS Body Snatching

Yes, CSS is the best way to make sure all your <p> tags use the same font but ...

Have you ever thought of using CSS to control the flow of an application?

... with Body Class Switching, CSS can dictate not only how an application appears, but also how it functions.


Let’s use the example of an application with lots of user interaction; a shopping cart.

[1] [2] [3] [4]
  1. Category selection on the left, visitor selects category ...
  2. List of matching products, visitor selects product ...
  3. Full details displayed, visitor select [Add] ...
  4. My Cart displayed.

In an AJAX application it would normally be javascript that changes the layout as the visitor moves from [1] to [4].
If, instead of making assumptions about layout, javascript simply set the class of the body tag then CSS would be able to take over control from there.

Let's try that flow again

[1] -> [2] Visitor clicks a category and Javascript sets the body class
<body class='categoryselected'>
CSS can now take over and decide to display the product thumbnails
.categoryselected #thumbnailcontainer { display:block; }

[2] -> [3] The visitor clicks on a product and javascript says:
<body class='productselected'>
CSS responds with:
.productselected #productdetailcontainer { display:block; }

[3] -> [4] The visitor clicks on ‘Add to Cart’ and javascript says:
<body class='addedtocart'>
CSS replies:
.addedtocart #cartcontainer { display:block; }

What has happened is that CSS has taken control of the visual flow application.

Why do it?

Control   If the javascript is created being someone other than the designer then the designer is in control of what are essentially design decisions.

Maintainability   If the layout of the application changes then you don't have to plough through javascript trying to find out where to mirror the changes.

Portability   The same javascript library and server side code can be used to create two apparently different applications simply because they use a different stylesheet.

User friendly   You could give your users the choice of how they want to see the application, some might want everything on the screen at the same time in a control panel kind of scenario while other might be more comfortable with basic uncluttered screens.

Philosophical   Layout is a design decision and hard coding it into javascript blurs the separation between design and functionality.

An Example

Tuesday, July 15, 2008

Simple javascript repeater

Assume you want to add content to a page after it has loaded such as JSON data retrieved from the server e.g.:
var data = [{Name: 'Google', URL: 'http://www.google.com'},
{Name: 'Yahoo', URL: 'http://www.yahoo.com'},
{Name: 'LiveSearch', URL: 'http://search.live.com/'}];
This content could possibly be displayed as
<ul>
<li>Google [http://www.google.com]</li>
<li>Yahoo [http://www.yahoo.com]</li>
<li>LiveSearch [http://search.live.com/]</li>
</ul>
or perhaps
<p><a href='http://www.google.com'>Google</a></p>
<p><a href='http://www.yahoo.com'>Yahoo</a></p>
<p><a href='http://search.live.com/'>LiveSearch</a></p>
and you don't want to have to deal with that issue in the javascript function. Firstly, create an HTML template of what the contents would look like when displayed. In the template you will have to indicate the bits that would be substituted by the actual data received. In the tradition of many great javascript libraries we'll use the ${} notation where ${Name} indicates that you want the 'Name' property of the data coming in to be placed in that location.
<p> <a href='${URL}'>${Name}</a> </p>
Now that we have a template we need a javascript function that can populate it, here's one
function ParseTemplate(aryData, strTemplate) { var result = ""; for(var i = 0; i < data.length; i++){ var obj = aryData[i]; result += strTemplate.replace( /\$\{([^}]*)\}/g, function(match, group1) { return obj[group1]; } ); } return result; }
Now, whenever new data is loaded you simply need to tell the function what template you want to use and where to put the result. Here is a full code listing to try out: