Thursday, August 7, 2008

JSRepeater

The javascript repeater microsite is here.

It's all very well having JSON data coming from the server, the problem lies in displaying this data in a page. I used to write reams of javascript to append nodes to the DOM but I was looking for something a little more declarative so that each time I wanted to put another piece of data on a page I didn't have to write yet another hardcoded function.

I tried DOJO's repeater (dojox.iterator) but there were a few things such as nested repeaters which it didn't do, I had a look around at some of the other libraries available but none felt quite right, so I decided to write my own javascript repeater.

I Googled the term 'JSRepeater' and nothing came up so that's what I'll call it.

When the page is loaded the repeater will scan the page for any element which has the attribute template='true'. It will make a copy of that elements contents to serve as a template.

When you bind data to that template the repeater it will replace any markers with data from the source data and then place the result in the original template element for each item of data to which it was bound.

A few examples probably makes this clearer, first we need some JSON data to work with.

var Categories = [{"Name" : "Memory", "Subcategories" : [{"Name" : "2 GB"},{"Name" : "3GB"},{"Name" : "4GB"}]},

{"Name" : "Hard Drives", "Subcategories" : [{"Name" : "250 GB"},{"Name" : "500 GB"},{"Name" : "500+ GB"}]}

{"Name" : "Graphics", "Subcategories" : [{"Name" : "Integrated"},{"Name" : "Dedicated"}]}]

Basic Binding

In order to display all the categories in an unordered list we could use the following template

<ul id="CategoryList" template="true"> <li>${Name}</li> </ul>


In the onload event of the page we would insert the following two lines:

// Initialise the jsRepeater var rpt = new jsRepeater(); // Bind the data to the template rpt.bindTemplate('CategoryList', Categories);


which would result in:

  • Memory
  • Hard Drives
  • Graphics


When we bound the template to the data the JSRepeater looped through each category and wrote out the template we created substituting ${Name} for the Name of the category.

Binding nested data

The previous example only displayed categories but categories have subcategories as well and if we want to display the whole hierarchy in one fould swoop we let the repeater know this by using the context tag e.g.

<ol id='CategoryList2' template='true'> <li>${Name} <ol><li context='Subcategories'>${Name}</li></ol> </li> </ol>


Once again the repeater parses the template for each category but when it gets to an element with the context tag it evaluates that against the current category and treats that <li> as a separate inner template and parses it for each subcategory in the current category. Inside that template ${Name} no longer refers to the category but the subcategory.

The result is this:

  1. Memory
    1. 2 GB
    2. 3 GB
    3. 4 GB
  2. Hard Drives
    1. 250 GB
    2. 500 GB
    3. 500+ GB
  3. Graphics
    1. Integrated
    2. Dedicated


There is more ...

The jsRepeater does a lot more than this but a blog is not the place to go into all the details. To that end I have put up a microsite at jsRepeater, please check it out and see what other functionality jsRepeater has to offer.

Sunday, August 3, 2008

Gadget Paper Cart

The Gadget Paper Cart is based on a template from Free Website Templates.

Using the CSS Body Snatching technique that I mentioned in my previous post I have added functionality to this template to give it the feel of a regular shopping cart.

If all you see is a CSS template you have to imagine how it would work in real life. Adding a bit of javascript gives you the chance to test drive the template in action. You can now get a feel for the user friendliness of the design itself.

You can see the template in action, and, if you want to have a play with the design yourself, download the source files.