ListView.itemTemplate property
Gets or sets the WinJS.Binding.Template or templating function that creates the Document Object Model (DOM) elements for each item in the itemDataSource. Each item can contain multiple elements, but it must have a single root element.
Syntax
<div
data-win-control="WinJS.UI.ListView"
data-win-options="{ itemTemplate : select('value')}">
</div>
var itemTemplate = listView.itemTemplate;
listView.itemTemplate = itemTemplate;
Property value
Type: Object
A WinJS.Binding.Template or a templating function that generates DOM elements for each item. For more info, see the Remarks section. You must set this property if you want to style the ListView items. The default value is null.
Remarks
Items in a ListView control can contain other controls, but they can't contain a FlipView or another ListView.
Using a Template to Display Items
An item Template defines the HTML markup that is displayed for each data item in your ListView. It has a single root element and can contain as many HTML elements as you want. To use one of those elements to display your data, you set the data-win-bind attribute on that element. The item Template should bind to the properties of the data that you want to display.
The data-win-bind attribute uses this syntax:
data-win-bind="propertyName: dataFieldName" |
For example, to bind the src property of an img to the "picture" field, use the following syntax:
<img data-win-bind="src : picture" />
To set multiple properties, separate them with a comma:
data-win-bind="property1Name: dataField1Name, property2Name: dataField2Name" |
This code creates a set of items that have title, text, and picture properties.
(function () {
"use strict";
var dataArray = [
{ title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
{ title: "Banana blast", text: "Ice cream", picture: "images/60banana.png" },
{ title: "Brilliant banana", text: "Frozen custard", picture: "images/60banana.png" },
{ title: "Orange surprise", text: "Sherbet", picture: "images/60orange.png" },
{ title: "Original orange", text: "Sherbet", picture: "images/60orange.png" },
{ title: "Vanilla", text: "Ice cream", picture: "images/60vanilla.png" },
{ title: "Very vanilla", text: "Frozen custard", picture: "images/60vanilla.png" },
{ title: "Marvelous mint", text: "Gelato", picture: "images/60mint.png" },
{ title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" }
];
var itemList = new WinJS.Binding.List(dataArray);
// Create a namespace to make the data publicly
// accessible.
var publicMembers =
{
itemList: itemList
};
WinJS.Namespace.define("TemplatingExample", publicMembers);
})();
The next example creates an item template that displays the title
, text
, and picture
of each data item.
<div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template">
<div class="mediumListIconTextItem">
<!-- Displays the "picture" field. -->
<img class="mediumListIconTextItem-Image"
src="#"
data-win-bind="alt: title; src: picture" />
<div class="mediumListIconTextItem-Detail">
<!-- Displays the "title" field. -->
<h4 data-win-bind="innerText: title"></h4>
<!-- Displays the "text" field. -->
<h6 data-win-bind="innerText: text"></h6>
</div>
</div>
</div>
<div id="basicTemplateListView" data-win-control="WinJS.UI.ListView"
data-win-options="{itemDataSource : TemplatingExample.itemList.dataSource,
itemTemplate: select('#mediumListIconTextTemplate')}">
</div>
The next example shows the CSS for styling the template and the ListView.
/* CSS for the ListView */
.win-listview
{
width: 600px;
height: 300px;
border: solid 2px rgba(0, 0, 0, 0.13);
}
/* Template for items */
.mediumListIconTextItem
{
width: 282px;
height: 70px;
padding: 5px;
overflow: hidden;
display: -ms-grid;
}
.mediumListIconTextItem img.mediumListIconTextItem-Image
{
width: 60px;
height: 60px;
margin: 5px;
-ms-grid-column: 1;
}
.mediumListIconTextItem .mediumListIconTextItem-Detail
{
margin: 5px;
-ms-grid-column: 2;
}
Using a function to display items
Instead of defining an item template in markup, you can create a function that renders each list item. The render function takes these parameters:
object renderItem(itemPromise, recycledElement)
itemPromise: a IItemPromise for the data for the item to render. With a synchronous datasource, the IItemPromise is usually complete, but with an async datasource, it will complete at some time in the future.
recycledElement : the Document Object Model (DOM) from a previous item that can be reused to display new content. This parameter is optional.
If you use element recycling:
Clear out the old item's info before using the recycled element as a placeholder. When you use recycling, the old item will likely contain old data and state from the last time it was used. Clear or hide the state before reusing the recycled element.
For example, if the template contains a photo and you want to reuse the img element but don't have the new URL yet, hide the img by setting its opacity to 0 because it might contain a photo from the old data. When you have the URL of the new photo, you can update the img element and change its opacity back to 1.
If the HTML for an item has conditional state based on the item data, be sure to reset it when it's recycled.
When recycling elements, minimize structural changes to the DOM. If the recycledElement is not appropriate for re-use, ignore it and create a new element from scratch, and the recycledElement will be garbage collected.
Warning The ListView can change the structure of recycledElement, so always test that child elements exist before trying to access them.
The render function must return either:
The root element of a DOM tree for the item.
An object that contains these properties:
element
: the root element of a DOM tree for the item, or a promise that when completed will return the root element for the item.renderComplete
: a Promise that completes when the item is fully rendered.
This example retrieves a ListView named templateFunctionListView and sets its itemTemplate property with an item template function that displays the title
, text
, and picture
of each data item.
function itemTemplateFunction(itemPromise) {
return itemPromise.then(function (item) {
var div = document.createElement("div");
div.className = "mediumListIconTextItem";
var img = document.createElement("img");
img.src = item.data.picture;
img.alt = item.data.title;
img.className = "mediumListIconTextItem-Image";
div.appendChild(img);
var childDiv = document.createElement("div");
childDiv.className = "mediumListIconTextItem-Detail";
var title = document.createElement("h4");
title.innerText = item.data.title;
childDiv.appendChild(title);
var desc = document.createElement("h6");
desc.innerText = item.data.text;
childDiv.appendChild(desc);
div.appendChild(childDiv);
return div;
});
};
WinJS.Namespace.define("TemplatingExample", { itemTemplateFunction: itemTemplateFunction });
WinJS.Utilities.markSupportedForProcessing(TemplatingExample.itemTemplateFunction);
The next example creates a ListView that uses the templating function.
<div id="templatingFunctionListView" data-win-control="WinJS.UI.ListView"
data-win-options="{itemDataSource : TemplatingExample.itemList.dataSource,
itemTemplate : TemplatingExample.itemTemplateFunction }">
</div>
The previous example set the ListView control's itemTemplate property in markup. You can also set this property in JavaScript:
WinJS.UI.Pages.define("/pages/templating/templating.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function (element, options) {
// TODO: Initialize the page here.
var listViewHost = element.querySelector("#templatingFunctionListView");
var lView = listViewHost.winControl;
lView.itemTemplate = itemTemplateFunction;
},
unload: function () {
// TODO: Respond to navigations away from this page.
},
updateLayout: function (element, viewState, lastViewState) {
/// <param name="element" domElement="true" />
// TODO: Respond to changes in viewState.
}
});
For more info about using templating functions, see How to create a templating function.
Adding interactive elements to an item template
The item template can contain most other controls, but it can't contain a FlipView or another ListView.
Normally, when the user interacts with an element, the ListView captures that interaction and uses it to determine whether the user selected or invoked an item or is panning through items. For an interactive element, such as a control, to receive input, you must attach the win-interactive
class to the interactive element or one of its parent elements. That element and its children receive the interaction and no longer trigger events for the ListView.
When you attach the win-interactive
to an element in a item template, be sure that the element doesn't fill the entire item, otherwise the user won't have a way to select or invoke that item.
To add interactive elements to your item template, you must use a templating function instead of a WinJS.Binding.Template.
Requirements
Minimum WinJS version |
WinJS 3.0 |
Namespace |
WinJS.UI |