Jul 12, 2010
jQuery JavaScript Templates Tutorial: Nesting Templates
In my last post, I presented an intro to how to create a template using the new jQuery Template plugin being developed by the Microsoft Ajax Core team. In this tutorial, I’ll show you how to nest templates to have great control over your layout.
The nesting of a template within another template is a pretty valuable feature as it lets you create a modular structure for your layout. Instead of having to create one enormous template to cover every scenario, you can break the layout apart into individual templates and piece them together. Let’s start by defining some data:
var clientData = [
{ name: "Rey Bango", age: 42, id: 1, phone: [ "954-600-1234", "954-355-5555" ] },
{ name: "Mark Goldberg", age: 51, id: 2, phone: ["954-600-1234", "954-355-5555"] },
{ name: "Jen Statford", age: "25", id: 3, phone: ["954-600-1234", "954-355-5555"] }
];
What I’d like to do is to render the basic information like the name and age in one template and then render the phone numbers for each client in a different template.
Like I showed in my previous post, we first create a template for our layout:
<script id="clientTemplate" type="text/html">
<p><a href="clients/${id}">${name} - Age: ${age}</a></p>
</script>
This will display the name and age as a hyperlink included within paragraph tags. Next, we create a new template that will be used to render the phone numbers for each client”
<script id="phoneTemplate" type="text/html">
<ul>{{each phone}}<li>${$value}</li>{{/each}}</ul>
</script>
Lastly, we’re going to include the call to “phoneTemplate” in our main template using the “tmpl” tag. This tag is used by the plugin to identify templates and parse them accordingly. Here’s what the call would look like:
{{tmpl($data) "#phoneTemplate"}}
and we’re going to include it into the main template:
<script id="clientTemplate" type="text/html">
<p><a href="clients/${id}">${name} - Age: ${age}</a></p>
{{tmpl($data) "#phoneTemplate"}}
</script>
This will generate the following results:
There are a couple of key things to understand here. First, let’s look at the following:
{{tmpl($data) "#phoneTemplate"}}
The variable “$data” contains the data for the current record being parsed. We’re passing it to the nested template so that we can work with that record. Let’s move onto the nested template:
<script id="phoneTemplate" type="text/html">
<ul>{{each phone}}<li>${$value}</li>{{/each}}</ul>
</script>
Now that the current record has been passed to it, we can access the attribute name, in this case “phone”, and loop through each phone record using the ‘{{each}}‘ plugin template tag. Think of it as similar to jQuery’s $.each() method or a JavaScript “for” loop. The code will loop through each phone record creating a new list item for each one and then return to the main template to get the next main record.
Here’s the whole code for you to work with:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="robots" content="noindex" />
<title>Template Test</title>
<script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
<script src="jquery.tmpl.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var clientData = [
{ name: "Rey Bango", age: 42, id: 1, phone: [ "954-600-1234", "954-355-5555" ] },
{ name: "Mark Goldberg", age: 51, id: 2, phone: ["617-777-1234", "617-222-3333"] },
{ name: "Jen Statford", age: "25", id: 3, phone: ["608-555-5647", "608-645-8855"] }
];
$("#clientTemplate").tmpl(clientData).appendTo("div");
});
</script>
<script id="clientTemplate" type="text/html">
<p><a href="clients/${id}">${name} - Age: ${age}</a></p>
{{tmpl($data) "#phoneTemplate"}}
</script>
<script id="phoneTemplate" type="text/html">
<ul>{{each phone}}<li>${$value}</li>{{/each}}</ul>
</script>
</head>
<body>
<div></div>
</body>
</html>
Related posts:
- Not Using jQuery JavaScript Templates? You’re Really Missing Out. In preparation for my upcoming talk on jQuery Templates, I’ve...
- I’m Presenting on jQuery Templates at ThinkVitamin’s jQuery Online Conference This coming Monday (7/12/2010), I’ll be one of the speakers...
- Generic Activity Indicator for Ajax Requests Over the weekend I was fiddling was some code to...
- Use ScriptSrc.net to Copy and Paste the Script tag for Your Favorite JavaScript Library One of the things I hate about using CDNs is...
- Video Interviews Part 2 – Nicholas Zakas, Principal Front-end Engineer at Yahoo! on jQuery Performance and Menno van Slooten on his Automated UI Testing Framework for jQuery I got some more videos edited and uploaded for you...
Related posts brought to you by Yet Another Related Posts Plugin.

AIM: iamreybango

Rey,
I’m fascinated by what is happening here between jquery and Microsoft, but my off-the-cuff reaction is: Does anyone ever need to bind from client data? Usually, data is on a db server. How about a full-service example, starting from a db server, then getting to client and rendering? Then, enabling CRUD functionality?
Cheers,
Bill
Hey Bill,
Ben did a great job of answering that. To see it in action, check out the source code from my conference presentation. I posted it yesterday here:
http://blog.reybango.com/2010/07/12/the-source-code-for-my-twitter-demo-from-the-think-vitamin-jquery-online-conference-templating-presentation/
It’s almost identical to what Ben said.
@Bill,
The data can be retreived using jQuery.ajax method, so you can use the received data object instead of the hardcoded example.
jQuery(function(){
jQuery.ajax({
url: ‘/someJSONService’,
success: function(data){
$(‘#clientTemplate’).tmpl(data).appendTo(‘div’);
}
});
});
You can also send data with ajax and jQuery has some good documentation on how to achieve this. How you set up CRUD services however is kinda outside of scope of this article/jQuery plugin. I suggest setting up RESTfull services and using jQuery.ajax to post requests, there are many articles on the net on this very topic, just do a search
Thanks for answering that Ben. That’s actually the example I showed in my presentation yesterday. Great minds!
Thanks so much for the reply Rey and Ben! When I get unburied from work, I will take a much closer look at that example. Best wishes.
Awesome. Any reason why this isn’t yet documented on the main page? (Or if it is, I didn’t see it.)
The team is revising the documentation but this is a work in progress so expect some changes.
COol. Rey – a bit OT – any chance you can add email notifications for new comments?
Hmm I’m getting notified of new comments. I wonder if it’s isolated to you or if no one is getting notifications.
Weird – now I see “Notify me of…” I swear I didn’t see it before. Sorry for the noise.
thanks for the example and very timely indeed. Your original post had me thinking about this and I happened to come across this post
I have been playing with 3 levels of nesting (and kinda got it working) by nesting {{each}}. Is there a nicer way of doing this? I guess what I am trying to say is can we not add a {{tmpl($data) “#someTemplate”}} for each level of nesting?
Thanks
J
[...] jQuery JavaScript Templates Tutorial: Nesting Templates – Rey Bango continues his series looking at templating in jQuery with a look at using nested templates to provide multi-level templating. [...]
[...] jQuery JavaScript Templates Tutorial: Nesting Templates (Rey Bango) [...]
Ray, I’m loving these templates, they are going to make my life so much easier. Do you know if the creators are talking about any kind of form elements to add to the templates? For instance, if I wanted to add a row to a table, and one of the cells of the table was a select, it would require some fun coding right now, to create the select and then select the item you want selected by default.