Saturday, January 29, 2011

jQuery Templates and JSON

Imagine the Web Application executing some functionality on the server using AJAX and processing data returned in JSON format. Very often such a processing is also updating UI with the provided data - recently we gained a powerful ally in this task - jQuery Templates.

This post will give you quick example of using jQuery Templates. We will focus on the client side of this process, assuming that the JSON response will look like this:
{"employer":{"id":1,"employees":[{"id":1,"firstName":"John","benefits":[{"name":"Healthy Employees","id":1,"type":"HEALTH_COVERAGE","startDate":1104534000000,"endDate":null},{"name":"Gold Autumn","id":2,"type":"RETIREMENT_PLAN","startDate":1104534000000,"endDate":null},{"name":"Always Secured","id":3,"type":"GROUP_TERM_LIFE","startDate":1104534000000,"endDate":null}]},{"id":2,"firstName":"Mary","benefits":[]},{"id":3,"firstName":"Eugene","benefits":[]}],"businessName":"Mighty Ducks"}}
And here comes the HTML/JavaScript part:
<html>
    <head>
    ...
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
        <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
        <script type="text/javascript">
        $(document).ready(
            function() {
                $("#ajax-trigger").click(
                    function(event) {
                        event.preventDefault();
                        $.getJSON("templates.json", { 'employerId' : 1}, 
                            function(data) {
                                $("#employerList").tmpl(data).appendTo("#ajax-target");
                            });
                    });
            });
        </script>
        <script id="employerList" type="text/x-jquery-tmpl">            
            {{tmpl(employer) "#employerTemplate"}}
        </script>
        <script id="employerTemplate" type="text/x-jquery-tmpl">
            <h1>${businessName}</h1>
            <table>
                <caption>Employees</caption>
                {{each(i, employee) employees}}{{tmpl(employee) "#employeeTemplate"}}{{/each}}
            </table>
        </script>
        <script id="employeeTemplate" type="text/x-jquery-tmpl">
            <tr>
                <td>${firstName}</td>
            </tr>        
        </script>    
    </head>
    <body>
        <div>
            <a href="javacsript:void();" id="ajax-trigger">AJAX</a>
        </div>
        <div id="ajax-target"></div>               
    </body>
</html>
As you see the whole machinery is triggered when you click on the "AJAX" link, then JSON response is fetched from server using $.getJSON and processed using following code:

$("#employerList").tmpl(data).appendTo("#ajax-target");

Which in more human friendly language means - find the element having id employerList and render its content as template using data returned from server, then append the result to element having id ajax-target.
Our first template (employerList) extracts the employer information from the provided data, and calls another template for this specific employer:

{{tmpl(employer) "#employerTemplate"}}

The employer template in turn displays the employer's business name, and for each of its employees calls the last template we use in this example - employeeTemplate

<h1>${businessName}</h1>
<table>
    <caption>Employees</caption>
    {{each(i, employee) employees}}{{tmpl(employee) "#employeeTemplate"}}{{/each}}
</table>

The employee template is very simple in this example, it only displays employee's first name

<tr>
    <td>${firstName}</td>
</tr>

Let's take a look at the above code in action - first the page right after loading:
Nothing special, except the big white space ;) - now after processing the JSON response:
As you see it works :) - and it's pretty fast, this very simple template was rendered on my chrome browser in less than 3 ms.

One and only doubt related to this solution which is troubling me is its compliance with HTML standard, because we put here different html tags inside of script tag - and W3C validator is not happy with that ;) - the question is if we should ...

Few links for the dessert:
  1. jQuery API - Templates
  2. Introducing jQuery Templates 1: First Steps
  3. jQuery Templates is now an Official jQuery Plugin
  4. jQuery JavaScript Templates Tutorial: Nesting Templates 

4 comments:

  1. Hm, microsoft CDN for jquery is not accident.

    Looks like manifest :)

    ReplyDelete
  2. Just wondering if you have an example of the server-side code for this in asp?

    ReplyDelete
  3. I was looking for a very similar plugin.
    But the issue with the plugin is that it does not work when working with the Spring framework. Basically all the ${abc..} is replace with blank (due to the automatic binding in Spring)

    ReplyDelete