Windows Library for JavaScript templates are a convenient way to format and display multiple instances of data. You can use these templates in conjunction with ListView and FlipView objects to specify the way you want them to be displayed. You can also use a template to bind multiple instances of a data object without using a predefined view. For more information about using a template with a ListView, see Quickstart: Add a ListView. For more information about using a template with a FlipView, see Adding FlipView controls. The following procedure shows how to use a template with an array.
You can define a template declaratively as a Windows Library for JavaScript control and specify its internal structure and style. Even though they are declared as DIV elements, templates are not processed as part of the DOM and are not returned as part of DOM search results. You can either specify the DIV element in which the template should appear, or allow the render method to create its own DIV element. This topic shows how to use a template to bind a variable number of bindable data objects to a DIV element. The user chooses the number of objects to display by selecting an item from a drop-down list.
Important When you perform declarative binding, you should always set the WinJS.Binding.optimizeBindingReferences property to true in the startup procedure for your app. If you do not do so, the bindings in your app may leak memory.
Prerequisites
- Working through the topic Quickstart: Binding data and styles to HTML elements might help you to complete the steps in this how-to topic.
Instructions
Step 1: Setting up a project to use a template
To set up a project to use a template, complete these steps.

-
Create a blank Windows Store app built for Windows using JavaScript and name it TemplateExample.
-
Make sure that the default.js file has the WinJS.Binding.optimizeBindingReferences property set to true. If it does not, add it to the top of that file, as follows:
(function () { "use strict"; WinJS.Binding.optimizeBindingReferences = true; ... }
-
Inside the BODY element of the default.html file, add a DIV element for the template and give it an ID of templateDiv, and then add a data-win-control attribute that has a value of "WinJS.Binding.Template", as shown here.
<body> <div id="templateDiv" data-win-control="WinJS.Binding.Template"></div> </body>
We'll return to add the internal structure of the template after we've defined the data object.
Step 2: Defining a data object and binding it to the fields of the template
- Declare an object that contains several fields. In this case, we'll use WinJS.Binding.define, which makes all the fields bindable.
<script type="text/javascript"> var Person = WinJS.Binding.define({ name: "", color: "", birthday: "", petname: "", dessert: "" }); </script>
-
To display the fields of this object in the template, add a list whose items correspond to the fields of the data object, as shown here.
<div id="templateDiv" data-win-control="WinJS.Binding.Template"> <div class="templateItem" data-win-bind="style.background: color"> <ol> <li><span>Name :</span><span data-win-bind="textContent: name"></span></li> <li><span>Birthday:</span><span data-win-bind="textContent: birthday"></span></li> <li><span>Pet's name: </span><span data-win-bind="textContent: petname"></span></li> <li><span>Dessert: </span><span data-win-bind="textContent: dessert"></span></li> </ol> </div> </div>
-
Add a DIV element at the location where the template should be rendered.
<div id="templateControlRenderTarget"></div>
Step 3: Controlling the number of objects displayed
For the purposes of this example, we'll instantiate three Person objects and add a drop-down list so the user can select the number of Person objects to display.
-
Add the drop-down list as follows.
<fieldset id="templateControlObject"> <legend>Pick a name:</legend> <select id="templateControlObjectSelector"> <option value="0">Show one</option> <option value="1">Show two</option> <option value="2">Show three</option> </select> </fieldset>
-
Create an array of three Person objects.
var people = [ new Person({name:"Bob", color:"red", birthday:"2/2/2002", petname:"Spot", dessert:"chocolate cake"}), new Person({name:"Sally", color:"green", birthday:"3/3/2003", petname:"Xena", dessert:"cherry pie"}), new Person({name:"Fred", color:"blue", birthday:"2/2/2002", petname:"Pablo", dessert:"ice cream"}), ];
-
3. Now add a listener to the change event of the drop-down selector. You can do this as part of the WinJS.Utilities.ready function. It's called immediately after the DOMContentLoaded event, which fires after the page has been parsed but before all the resources are loaded.
WinJS.Utilities.ready(function () { var selector = document.getElementById("templateControlObjectSelector"); selector.addEventListener("change", handleChange, false); }, false);
In the change event handler, find the DIV element that contains the template and the DIV element that specifies where to display the data, and then call render on the template control (which you can get from the wincontrol property of the templateDiv element). When you call render on the template, the relevant fields of the data object are bound to the template's list items.
function handleChange(evt) { var templateElement = document.getElementById("templateDiv"); var renderElement = document.getElementById("templateControlRenderTarget"); renderElement.innerHTML = ""; var selected = evt.target.selectedIndex; var templateControl = templateElement.winControl; while (selected >= 0) { templateElement.winControl.render(people[selected--], renderElement); } }
Now you can build and debug the app. When you make a selection in the drop-down list, the app displays the appropriate number of data objects.
Step 4: Allowing render to add a DIV
You do not have to give the render function a DIV you have created; render creates a new DIV if no DIV is specified. You must, however, add the new DIV to the DOM. Note that the return value of render is a WinJS.Promise. (For more information about promises, see Quickstart: using promises.) In the promise's done method you add a function that adds the new DIV.
Change the while block of the previous step as follows.
while (selected >= 0) {
templateElement.winControl.render(people[selected--])
.done(function (result) {
renderElement.appendChild(result);
});
}
Complete example
Here is the complete listing of the code in this topic.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>TemplateExample</title>
<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
<!-- TemplateExample references -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/default.js"></script>
</head>
<body>
<div id="templateDiv" data-win-control="WinJS.Binding.Template">
<div class="templateItem" data-win-bind="style.background: color">
<ol>
<li><span>Name :</span><span data-win-bind="textContent: name"></span></li>
<li><span>Birthday:</span><span data-win-bind="textContent: birthday"></span></li>
<li><span>Pet's name: </span><span data-win-bind="textContent: petname"></span></li>
<li><span>Dessert: </span><span data-win-bind="textContent: dessert"></span></li>
</ol>
</div>
</div>
<div id="templateControlRenderTarget"></div>
<fieldset id="templateControlObject">
<legend>Pick a name:</legend>
<select id="templateControlObjectSelector">
<option value="0">Show one</option>
<option value="1">Show two</option>
<option value="2">Show three</option>
</select>
</fieldset>
<script type="text/javascript">
var Person = WinJS.Binding.define({
name: "",
color: "",
birthday: "",
petname: "",
dessert: ""
});
var people = [
new Person({ name: "Bob", color: "red", birthday: "2/2/2002", petname: "Spot", dessert: "chocolate cake" }),
new Person({ name: "Sally", color: "green", birthday: "3/3/2003", petname: "Xena", dessert: "cherry pie" }),
new Person({ name: "Fred", color: "blue", birthday: "2/2/2002", petname: "Pablo", dessert: "ice cream" }),
];
WinJS.Utilities.ready(function () {
var selector = document.getElementById("templateControlObjectSelector");
selector.addEventListener("change", handleChange, false);
}, false);
function handleChange(evt) {
var templateElement = document.getElementById("templateDiv");
var renderElement = document.getElementById("templateControlRenderTarget");
renderElement.innerHTML = "";
var selected = evt.target.selectedIndex;
var templateControl = templateElement.winControl;
while (selected >= 0) {
templateElement.winControl.render(people[selected--])
.done(function (result) {
renderElement.appendChild(result);
});
}
}
</script>
</body>
</html>
Related topics
Build date: 10/26/2012