Metro: Introduction to the WinJS ListView Control
- by Stephen.Walther
The goal of this blog entry is to provide a quick introduction to the ListView control – just the bare minimum that you need to know to start using the control. When building Metro style applications using JavaScript, the ListView control is the primary control that you use for displaying lists of items. For example, if you are building a product catalog app, then you can use the ListView control to display the list of products.
The ListView control supports several advanced features that I plan to discuss in future blog entries. For example, you can group the items in a ListView, you can create master/details views with a ListView, and you can efficiently work with large sets of items with a ListView. In this blog entry, we’ll keep things simple and focus on displaying a list of products.
There are three things that you need to do in order to display a list of items with a ListView:
Create a data source
Create an Item Template
Declare the ListView
Creating the ListView Data Source
The first step is to create (or retrieve) the data that you want to display with the ListView. In most scenarios, you will want to bind a ListView to a WinJS.Binding.List object.
The nice thing about the WinJS.Binding.List object is that it enables you to take a standard JavaScript array and convert the array into something that can be bound to the ListView. It doesn’t matter where the JavaScript array comes from. It could be a static array that you declare or you could retrieve the array as the result of an Ajax call to a remote server.
The following JavaScript file – named products.js – contains a list of products which can be bound to a ListView.
(function () {
"use strict";
var products = new WinJS.Binding.List([
{ name: "Milk", price: 2.44 },
{ name: "Oranges", price: 1.99 },
{ name: "Wine", price: 8.55 },
{ name: "Apples", price: 2.44 },
{ name: "Steak", price: 1.99 },
{ name: "Eggs", price: 2.44 },
{ name: "Mushrooms", price: 1.99 },
{ name: "Yogurt", price: 2.44 },
{ name: "Soup", price: 1.99 },
{ name: "Cereal", price: 2.44 },
{ name: "Pepsi", price: 1.99 }
]);
WinJS.Namespace.define("ListViewDemos", {
products: products
});
})();
The products variable represents a WinJS.Binding.List object. This object is initialized with a plain-old JavaScript array which represents an array of products.
To avoid polluting the global namespace, the code above uses the module pattern and exposes the products using a namespace. The list of products is exposed to the world as ListViewDemos.products.
To learn more about the module pattern and namespaces in WinJS, see my earlier blog entry:
http://stephenwalther.com/blog/archive/2012/02/22/metro-namespaces-and-modules.aspx
Creating the ListView Item Template
The ListView control does not know how to render anything. It doesn’t know how you want each list item to appear. To get the ListView control to render something useful, you must create an Item Template.
Here’s what our template for rendering an individual product looks like:
<div id="productTemplate" data-win-control="WinJS.Binding.Template">
<div class="product">
<span data-win-bind="innerText:name"></span>
<span data-win-bind="innerText:price"></span>
</div>
</div>
This template displays the product name and price from the data source.
Normally, you will declare your template in the same file as you declare the ListView control. In our case, both the template and ListView are declared in the default.html file.
To learn more about templates, see my earlier blog entry:
http://stephenwalther.com/blog/archive/2012/02/27/metro-using-templates.aspx
Declaring the ListView
The final step is to declare the ListView control in a page. Here’s the markup for declaring a ListView:
<div data-win-control="WinJS.UI.ListView"
data-win-options="{
itemDataSource:ListViewDemos.products.dataSource,
itemTemplate:select('#productTemplate')
}">
</div>
You declare a ListView by adding the data-win-control to an HTML DIV tag. The data-win-options attribute is used to set two properties of the ListView.
The ListView is associated with its data source with the itemDataSource property. Notice that the data source is ListViewDemos.products.dataSource and not just ListViewDemos.products. You need to associate the ListView with the dataSoure property.
The ListView is associated with its item template with the help of the itemTemplate property. The ID of the item template — #productTemplate – is used to select the template from the page.
Here’s what the complete version of the default.html page looks like:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ListViewDemos</title>
<!-- WinJS references -->
<link href="//Microsoft.WinJS.0.6/css/ui-dark.css" rel="stylesheet">
<script src="//Microsoft.WinJS.0.6/js/base.js"></script>
<script src="//Microsoft.WinJS.0.6/js/ui.js"></script>
<!-- ListViewDemos references -->
<link href="/css/default.css" rel="stylesheet">
<script src="/js/default.js"></script>
<script src="/js/products.js" type="text/javascript"></script>
<style type="text/css">
.product {
width: 200px;
height: 100px;
border: white solid 1px;
}
</style>
</head>
<body>
<div id="productTemplate" data-win-control="WinJS.Binding.Template">
<div class="product">
<span data-win-bind="innerText:name"></span>
<span data-win-bind="innerText:price"></span>
</div>
</div>
<div data-win-control="WinJS.UI.ListView"
data-win-options="{
itemDataSource:ListViewDemos.products.dataSource,
itemTemplate:select('#productTemplate')
}">
</div>
</body>
</html>
Notice that the page above includes a reference to the products.js file:
<script src=”/js/products.js” type=”text/javascript”></script>
The page above also contains a Template control which contains the ListView item template. Finally, the page includes the declaration of the ListView control.
Summary
The goal of this blog entry was to describe the minimal set of steps which you must complete to use the WinJS ListView control to display a simple list of items. You learned how to create a data source, declare an item template, and declare a ListView control.