the Future of the Web
  • Articles
  • Contact
  • Official jQuery Templating Plugin

    Oct 11 2010

    jQuery announced that they are now officially supporting jQuery Templates, thanks in big part to Microsoft.

    Templating cleans up the job of generating HTML with jQuery. It also gives you the opportunity of keeping HTML code out of your JavaScript completely, if you wish.

    Let's say you have a block of data like this:

    var fruits = [
        { name: 'apples', color: 'green' },
        { name: 'oranges', color: 'orange' },
        { name: 'bananas', color: 'yellow' },
        { name: 'tomatoes', color: 'red' }
    ];
    

    You want to display the data in a nice table with some color effects:

    namecolor
    apples green
    oranges orange
    bananas yellow
    tomatoes red

    Without templates, your code might look like this:

    // create a table
    var $table = $('<table class="fruit-table">');
    
    // append a header to the table
    $('<tr><th>name</th><th>color</th></tr>').appendTo( $table );
    
    // append a row for each fruit
    for (var i in fruits) {
        // create a row, and set the background to the color of the fruit
        var $row = $('<tr/>', { css: { background: fruits[i].color } });
    
        // create a column and append to the row
        // we use text here so all HTML is escaped, to prevent hacking
        $('<td/>', { text: fruits[i].name }).appendTo( $row );
    
        // do the same for the color
        $('<td/>', { text: fruits[i].color }).appendTo( $row );
    
        // append the row to the table
        $row.appendTo( $table );
    }
    
    // all done, stick the table on the page
    $table.appendTo('body');
    

    Unfortunately, code like this usually ends up looking kludgy, and it's often hard to visualize what the final HTML will look like.

    Templates let us turn the HTML/JavaScript relationship inside-out by putting the looping right in the HTML:

    // define a template for the fruit table
    // we'll use slashes at the end of each line to escape the line break
    // this way we don't have to concatenate strings.
    $.template('fruit-table', '\
        <table class="fruit-table"> \
            <tr><th>name</th><th>color</th></tr> \
            {{each rows}} \
                <tr style="background: ${color}"> \
                    <td>${name}</td> \
                    <td>${color}</td> \
                </tr> \
            {{/each}} \
        </table> \
    ');
    
    // instantiate the template with the fruit array passed in as 'rows'
    var $table = $.tmpl('fruit-table', { rows: fruits });
    
    // that's it. stick it on the page.
    $table.appendTo('body');
    

    Now there's no question what the HTML will look like. It's in plain view.

    If you'd like to jump on the chance to take the HTML out of your JavaScript completely, you can stick the same block on the page, in a special <script> block:

    <script id="fruit-table" type="text/x-jquery-tmpl">
    
        <table class="fruit-table">
            <tr><th>name</th><th>color</th></tr>
            {{each rows}}
                <tr style="background: ${color}">
                    <td>${name}</td>
                    <td>${color}</td>
                </tr>
            {{/each}}
        </table>
    
    </script>
    

    Now we're down to a single line of code. Beautiful, isn't it?

    $('#fruit-table').tmpl({ rows: fruits }).appendTo('body');
    

    Now that we've gotten that taken care of, let's take it to the next level, and make a template that will dump any tabular data we give it:

    <script id="table" type="text/x-jquery-tmpl">
    
    {{if !data || data.length == 0 }}
        <p>No data.</p>
    {{else}}
        <table class="${className}">
            <tr>
                {{each(key) data[0]}}
                   <th>${key}</th>
                {{/each}}
            </tr>
            {{each(i, row) data}}
                <tr>
                    {{each(key, value) row}}
                        <td>${value}</td>
                    {{/each}}
                </tr>
            {{/each}}
        </table>
    {{/if}}
    
    </script>
    

    $('#table').tmpl({
        data: fruits,
        className: 'fruits-table'
    }).appendTo('body');
    

    Want more? Check out the documentation and official announcements for lots more information:

    • Templates documentation on jQuery API
    • jQuery announcement
    • Microsoft announcement
    View 7 Comments | Add a comment
  • Comments

    1. Zach Leatherman at 2:09pm on October 12, 2010

    Hey Jesse, great to see you blogging again.

    Any idea/documentation on the performance overhead of using templates over standard jQuery templates, innerHTML, or raw DOM?

    2. Jesse Skinner at 2:15pm on October 12, 2010

    @Zack - I'm glad to be back too :)

    Good question. I haven't done any performance profiling yet, but I do know that the Templates plugin will cache templates as a "compiled" function which will speed up reuse of that template. Whether that speed-up is faster than regular innerHTML or DOM isn't clear but definitely worth experimenting with.

    3. Jesse Skinner at 2:25pm on October 12, 2010

    @Zach - I just tried with the examples above, comparing the regular jQuery DOM scripting to using the jQuery template (second example), and compared to re-using the template again after it has been cached. I found the following:

    jQuery DOM: 4.5ms
    jQuery Template Definition and Use: 2ms
    jQuery Template Reuse: 1.4ms

    So it seems using the template is considerably faster than jQuery DOM even before the template is cached.

    I didn't compare to constructing the innerHTML yourself or doing non-jQuery DOM scripting, so I'm not sure how those compare. If you construct the HTML yourself, make sure you are escaping HTML in the data for a fair comparison.

    I hope this helps. Try experimenting and let us know if you discover anything.

    4. SEO services at 4:14am on January 27, 2011

    But what is the reason to keep the HTML codes out? What is the need to avoid it?

    5. Barrett at 8:35pm on May 8, 2011

    Thanks very much

    6. yangbb at 10:02pm on June 26, 2011

    http://jsperf.com/jquery-template-table-performance

    7. heredress at 8:45am on August 25, 2011

    <a href="http://www.tidebuy.com/">Online shopping</a>

    Add a Comment

    Note: HTML tags and entities will be converted so that they are displayed as you type them. This means if you type in <em>, people will see <em>, and if you type &lt;em&gt;, people will see &lt;em&gt;.

  • Jesse Skinner

    Jesse Skinner
    • About Me
    • Email Me
    • RSS Feed RSS Icon
    • @JesseSkinner
  • Recent Articles

    • Free eBook: Unobtrusive Ajax
    • Official jQuery Templating Plugin
    • jQuery Live Events
    • buttons need type="submit" to submit in IE
    • Use Arrays in HTML Form Variables
    • 5 Reasons Freelancers Can Succeed in a Shrinking Economy
    • Keeping a Live Eye on Logs
    • Using PHP's empty() Instead of isset() and count()
    • Testing Web Pages with Lynx
    • Stop CSS Background Flickering in Internet Explorer 6
    • See All...
  • Categories

    • javascript (41)
    • links (17)
    • about (17)
    • web (14)
    • html (12)
    • server (11)
    • css (8)
    • browsers (8)
    • carnival (7)
    • work (5)
    • design (4)
    • seo (4)
    • ads (4)
    • events (4)
    • standards (4)
  • Older Articles

    • October 2010
    • February 2009
    • January 2009
    • December 2008
    • November 2008
    • October 2008
    • July 2008
    • June 2008
    • May 2008
    • April 2008
    • February 2008
    • January 2008
    • December 2007
    • November 2007
    • September 2007
    • August 2007
    • July 2007
    • June 2007
    • May 2007
    • April 2007
    • March 2007
    • February 2007
    • January 2007
    • December 2006
    • November 2006
    • October 2006
    • September 2006
    • August 2006
    • July 2006
    • June 2006
    • May 2006
    • April 2006
    • March 2006
    • February 2006
    • January 2006
    • December 2005
    • November 2005
    • October 2005
    • September 2005
    • August 2005
    • April 2005
    • See All...
Copyright © 2012 The Future of the Web