Microsoft's jQuery Templates Extension
Don Kiely takes you on a tour of Microsoft's jQuery plug-in, which provides client-side template functionality
June 9, 2011
Microsoft has embraced jQuery in a big way, even to the point of creating its own extensions to the core library as part of the standard jQuery contribution process. Some of Microsoft's top web and JavaScript developers are working with members of the core jQuery team to create extensions that replace parts of their Microsoft Ajax Library. These extensions do things like make data more readily usable from client-side web pages and make it easier to implement globalization on a site. One group is even attempting to create a UI grid that will be full-featured enough to handle almost any kind of scenario. These are exciting times in Microsoft's corner of jQuery!
Client-side templates were one of the major features that Microsoft added to its Ajax Library before it ceased all development on it and switched to jQuery. Shortly after announcing their support for jQuery in ASP.NET and Visual Studio, Microsoft made a proposal to add templates to jQuery, and after a lot of hard work by Microsoft and the jQuery community, templates are close to reality.
Templates let you easily generate and render HTML on the client by defining the HTML that the browser should generate for each item in a set of data. The template is a declarative definition of the structure of the generated HTML along with binding expressions, so that at runtime you can programmatically invoke the template with data as JavaScript objects to generate content and markup for the page. You can generate the JavaScript objects dynamically on the client or retrieve them via Ajax from the server.
The main benefit of using client-side templates is that you can easily structure content you add dynamically to a page without using string concatenation and the pain of writing code to make it all work. Simply define the template using plain old HTML, insert simple binding expressions where the data from each data item should go, and invoke the template at runtime. It really is a pretty slick way of updating a page on the client.
By the way, at one point it looked like the jQuery team would incorporate templates into the core library. But that didn't happen in jQuery 1.5, much to the disappointment of the Microsoft developers who built the plug-in. It appears likely that templates will make their way into the library at some point, but no one seems to know when that will happen.
Basic Template Structure
Templates can sound like a rather abstract concept, but an example will serve to make them clearer. The sample page, shown in Figure 1, calls an ASP.NET web service to retrieve JSON data containing information about a few of the boroughs in Alaska. The page uses templates to dynamically structure the data into the list items displayed on the page. The first three buttons all display the same information, and the fourth button uses a conditional expression in a template to display additional information. The figure shows what you'll see when you click any of the first three buttons; you'll learn about the fourth button later in this article.
The HTML in the body of the page is pretty simple, as shown below. It simply consists of the four buttons and a divResult that functions as a placeholder for the borough data. Nothing interesting here, and nothing that indicates that the page uses templates to update itself.
Alaska Boroughs Get Boroughs (Script Version) Get Boroughs (Code Version) Get Boroughs (Named Template) Get Boroughs (Conditional)
The head section of the page includes the Site.css stylesheet, the jQuery library, the jQuery Templates plug-in file, and a public domain function, addCommas, to format the population numbers on the page.
Defining the Template in the Page
Now we get to the interesting parts of the page. There are a few different ways to define a template in the page, and the easiest is to include it as the content of a script element on the page. The following code defines the template for the borough data, using a type value of text/x-jquery-tmpl, and including the HTML as the content of the element. The template includes three binding expressions: one for the borough name, another for the population, and the third for the date the borough was founded. Notice that you can include JavaScript within the binding expression in various ways, such as the call to the addCommas function to format the population numbers with commas.
Setting the type attribute of the script element to text/x-jquery-tmpl looks like it will be the setting that will make it to the final version of jQuery Templates. At one point the developers were using text/html, and you'll still see samples online like that. But anything can change before the final release. Also, the jQuery Template team seems to have settled on the ${ } syntax for binding expressions, but {{ }} also works.
The template will generate a li element for each data item in the collection of JavaScript objects that the code in the page binds the template to. The data returned from the GetAllBoroughs Web service method includes five Borough objects, so the page will have five li elements.
The following code defines the click event of the first button, buttonGetScript. It starts by using the jQuery ajax method to call the GetAllBoroughs Web method and defines a custom function when the call is successful and the page gets a response with the borough information in JSON form.
$('#buttonGetScript').click(function () { $.ajax({ type: "POST", url: "AjaxServices.asmx/GetAllBoroughs", data: "{}", contentType: "application/json; charset=utf-8", dataType: "json", success: function (response) { $('#divResult').html('') .append('Here are a few of Alaska's boroughs (template defined in '); var boroughs = response.d; $("#boroughTemplate").tmpl(boroughs) .appendTo("#boroughList"); $('#divResult').css('display', 'block'); } });});The success function starts by clearing out the divResult element, so you can click the button multiple times and display only the data from the latest request. Then it adds a p element that introduces the list of boroughs, along with the ul element that will be the parent for the li elements created using the template.Up to here, the code has just been setting up the page. The next two statements, repeated below, are all that is needed to bind the template to the data, generate the li elements, and add them to the new ul element boroughList. The first statement gets the data from the response and stores it in a boroughs variable. The second statement selects the script element with the template definition, and calls the tmpl method from the jQuery Templates plug-in, to bind the template to the data in the boroughs variable. The resulting HTML is then appended to the boroughList ul element.var boroughs = response.d;$("#boroughTemplate").tmpl(boroughs).appendTo("#boroughList");The second button results in the same content added to the page. But instead of using a template defined in a script element, it passes the template definition as a string to the tmpl method. The following code is the only change from the code for the first button, other than changing the text in the p element to indicate that this example uses a template defined in code. This is a convenient way to use short, simple templates that you'll use in only one place on a page.$.tmpl('${Name}: ${addCommas(Population)} people, created in ${Created}', boroughs) .appendTo("#boroughList");Another option is to create named templates in the page in code, then reference the template by name when you need to bind data to it. This is a convenient way to manage multiple templates that you'll use in a page, and you can put the template definitions into a separate .js file and include them in whatever pages you need them.The first thing to do is to define the named template, using the following code. This code creates a template called boroughTempl, using the same template definition as the previous samples. Once this code executes, you can use boroughTempl anywhere in the page.$.template('boroughTempl', '${Name}: ${addCommas(Population)} people, created in ${Created}');To use a named template, you simply pass the name as the first argument to the tmpl method, as shown in the following code for the click event defined for the buttonGetNamed button.$.tmpl('boroughTempl', boroughs).appendTo("#boroughList");You aren't limited to including simple binding expressions in static HTML for a template. You can use a variety of template tags to dynamically customize the template at run time in various ways. For example, the following template definition uses the {{if}} template tag to add a note that the current borough is a megaborough if its population is greater than 200,000.Other template tags you can use include {{else}} with {{if}} for alternate conditions and {{each}} to loop through objects, which is very handy for displaying child objects.The following code to invoke the template is the same as the previous example that used a template defined in a script element, other than referencing the boroughTemplateMega script element. It simply passes in the boroughs variable to the tmpl method. Figure 2 shows the result of clicking the buttonGetIf button. With almost half the population of Alaska, Anchorage certainly qualifies as a megaborough!$("#boroughTemplateMega").tmpl(boroughs).appendTo("#boroughList");Once the final version of jQuery Templates is released, it will be much easier to create updated content for a page using JavaScript objects. The template definition and required code is much simpler than performing string concatenation, and you can create very complex templates for updated content that would be a nightmare to write string concatenation code for!You can download the Templates plug-in here.This article is adapted from courseware I wrote for AppDev.Don Kiely, MVP, MSCD, is a senior technology consultant specializing in developing secure desktop and web applications that integrate databases and related technologies. When he isn’t writing software, he’s writing and speaking about it.
Read more about:
MicrosoftAbout the Author
You May Also Like