09
Aug

Dynamically create a table from a template with javascript and underscore.js

The chances are that if you’ve been working with javascript, jquery and AJAX for any time then you’ve inserted snippets or blobs of html into the DOM using something along the lines of:

var data = [...]; // Some array

var html = "<table id='dataTable'>";
html += "<tr><th>First Name</th><th>Last name</th></tr>";

for (var i = 0; i < data.length; i++){
    html += "<tr><td>" + data.firstname + "</td><td>"
          + data.lastname + "</td></tr>";
}

html += "</table>";

$('#myDiv').html(html);

And for small snippets of HTML why not?

The trouble starts when you start inserting larger chunks of html, maybe even the whole page if this one of the increasingly popular Single Page Applications (SPA – an interactive web application with no page reloads). Long strings of html will become very messy very quickly as well as being very difficult to maintain and debug.

Also, you may be inserting HTML which has been generated server side. This solution will help to decouple your client from the server. Get the data via JSON or whatever and then the client deals with the presentation. (You may even want to take this a step further and implement an MVC solution such as backbone.js but that’s a tutorial for another day!)

The solution of course is to use a template – some HTML which can be dynamically updated. The realisation of how useful and necessary this is for client side development has spawned a few new templating solutions: mustache.js, IcanHaz.js as well as the new jQuery templates plugin (jquery-tmpl).

I had a simple task: I wanted to dynamically fill a table as in the example above. I looked at a few of the solutions – in particular the jQuery templates plugin which I found to be easy to use for a basic template but which became increasingly complex with having to compile nested templates, etc. The best solution, I found, was using the templating features of underscore.js which is an extremely useful library. The main feature of the underscore templating solution is that you can create straight HTML (which could be from a separate file, etc.) and then simply insert your dynamic data using native javascript. It’s pretty much the equivalent of inserting data into HTML using PHP tags.

Here’s how to do it:

First lets have some data. An array of customers for example:

var customerList = [
        {
            'firstname': 'Rio',
            'lastname' : 'Ferdinand',
            'email' : 'rio@gmail.com'
        },
        {
            'firstname': 'Paul',
            'lastname' : 'Scholes',
            'email' : 'paul@hotmail.com'
        },
        {
            'firstname': 'Ryan',
            'lastname' : 'Giggs',
            'email' : 'ryan@hotmail.com'
        }
    ]

Next our template. All you need is a container for the HTML. I’m using a script container but you can use anything – a div with display:none; or whatever. The container must have an identifier.

<script id="customerTemplate" type="text/html">

        <table>
            <tr>
                  <th>First name</th>
                  <th>Last name</th>
                  <th>Email</th>
            </tr>
            <% for(var i = 0; i < customerList.length; i++){ %>
            <% var customer = customerList[i]; %>
            <tr>
                 <td><%= customer.firstname %></td>
                 <td><%= customer.lastname %></td>
                 <td><%= customer.email %></td>
            </tr>
            <% } %>
        </table>

    </script>

So how cool is that? It’s just straight HTML with dynamic data inserted via native javascript. The only thing you need to do is to use the < % … %> tags to delimit your javascript and that’s it – no messy {{if}} tags, nested templates or anything like that. Just put in whatever javascript you need!

N.B. To print a value out, note the use of the < %= (with equals sign) as opposed to just <% for the other tags.

Ok it’s all very easy but we’re not done yet. Now we’re going to use underscore.js (if you haven’t explored underscore.js then I highly recommend that you do. It is an improbably useful library)

There are two steps: first we’ll create a template object from the template using underscore. This object can then be used with our data to output our final HTML.

// Use underscore to convert the template to a 'template' object
var customerTemplate = _.template($('#customerTemplate').text());

// Use the template object to output our html
// Note that the customerList name equates to the customerList
// array that is used in the template.
var html = customerTemplate({'customerList' : customerList});
$("#someDiv").html(html);

That’s it! Note you’ll need to include the underscore library!

About James
I'm all-round developer with a background in enterprise development using C++. I'm a client and server side web developer with a particular interest in making the web as interesting and usable as possible with seamless client / server interaction using jQuery and AJAX.

2 Comments for this entry

dmitry
September 6th, 2011 on 10:28 am

Great post! I first tried using moustache.js but I’m now convinced to use underscore.js since I plan to also use backbone.js in my future projects.

shrenik
October 5th, 2011 on 7:23 am

Thanks. g8 post. it works for me