Quantcast
Channel: DataBinding – Dhananjay Kumar
Viewing all articles
Browse latest Browse all 3

ListView Binding with Grouping and Semantic Zoom in Windows 8 JavaScript Metro Application

$
0
0

Windows 8 CP and VS11 are around. Recently I wrote Setting up Visual Studio11 Beta for Metro Application Creation . In this post let us get into some development.

In this post we will see

  • Creating DataSource
  • ListView Binding to DataSource
  • Creating ItemTemplate
  • Grouping Data Source
  • Using SemanticZoomView over ListView

At the end of the post we will have output like below,

clip_image002clip_image004

We are going to display list of movies in a ListView. Movies will be grouped with the first letter of their title. Later in the post we will apply SemanticZoomView on the ListView . In above image you can see Semantic Zoom View. To switch between SemanticZoomView and detail view either you can tap on the screen or press CTRL + Arrow key on the keyboard.

Create DataSource

Very first we need to create a DataSource. To create DataSource right click on JS folder and add a new JavaScript file. Let us call this newly added JavaScript file as moviedata.js

clip_image002[5]

Inside newly created file, we need to create an anonymous JavaScript function and define a JavaScript array. This array contains locally data to be bind to the ListView.

MovieArray contains two properties,

  • Title to display name of the movie
  • Picture to display thumbnail of the movie.

All the movie images are inside images folder in the project. Let us create array with sample data. Array is given below.


var movieArray = [
{ title: "The Artist", picture: "images/TheArtist.jpg" },
{ title: "A Better Life", picture: "images/abetterlife.jpg" },
{ title: "Abduction", picture: "images/abduction.jpg" },
{ title: "African Cats", picture: "images/africancats.jpg" },
{ title: "Angel Crest", picture: "images/angelscrest.jpg" },
{ title: "Arthur", picture: "images/arthur.jpg" },
{ title: "Anonymous", picture: "images/anonymous.jpg" },
{ title: "A Dangerous Method", picture: "images/adangerousmethod.jpg" },
{ title: "A Good Old Fashioned Orgy ", picture: "images/agoodoldfashionedorgy.jpg" },
{ title: "A Seperation ", picture: "images/aseparation.jpg" },
{ title: "Another Earth ", picture: "images/anotherearth.jpg" },
{ title: "A Heartbeat Away ", picture: "images/aheartbeataway.jpg" },
{ title: "Bad Teacher ", picture: "images/badteacher.jpg" },
{ title: "Begineers ", picture: "images/beginners.jpg" },
{ title: "Brotherhood ", picture: "images/brotherhood.jpg" },
{ title: "Bridesmaids ", picture: "images/bridesmaids.jpg" },
{ title: "Born To Be Wild ", picture: "images/borntobewild.jpg" },
{ title: "Blackthorn ", picture: "images/blackthorn.jpg" },
{ title: "Bellflower ", picture: "images/bellflower.jpg" },
{ title: "Butter ", picture: "images/butter.jpg" },
{ title: "Bunraku ", picture: "images/bunraku.jpg" },
{ title: "Cars 2 ", picture: "images/cars2.jpg" },
{ title: "Cost Of A Soul", picture: "images/costofasoul.jpg" },
{ title: "Carnage ", picture: "images/carnage.jpg" },
{ title: "Crazy Stupid Love ", picture: "images/crazystupidlove.jpg" },
{ title: "Cracks ", picture: "images/cracks.jpg" },
{ title: "Colombiana ", picture: "images/colombiana.jpg" },
{ title: "Cedar Rapids ", picture: "images/cedarrapids.jpg" },
{ title: "Captain America ", picture: "images/captainamerica.jpg" },
];

Next we need to convert JavaScript array into list to be bind to ListView.

image

Now to make this data publicly available we need to make a namespace and on the HTML page need to add reference of this namespace to use data from this file. Namespace can be created as below,

clip_image002[7]

There are few points worth discussing about creating namespace

  • MovieData.itemList is the public member.
  • MovieData.itemList.datasource will be the datasource.

By this step we have created DataSource. And putting all piece of code together moviedata.js file will be as below,

Moviedata.js


(function () {
"use strict";
// http://www.allmoviephoto.com/photo/index_2011.html
var movieArray = [
{ title: "The Artist", picture: "images/TheArtist.jpg" },
{ title: "A Better Life", picture: "images/abetterlife.jpg" },
{ title: "Abduction", picture: "images/abduction.jpg" },
{ title: "African Cats", picture: "images/africancats.jpg" },
{ title: "Angel Crest", picture: "images/angelscrest.jpg" },
{ title: "Arthur", picture: "images/arthur.jpg" },
{ title: "Anonymous", picture: "images/anonymous.jpg" },
{ title: "A Dangerous Method", picture: "images/adangerousmethod.jpg" },
{ title: "A Good Old Fashioned Orgy ", picture: "images/agoodoldfashionedorgy.jpg" },
{ title: "A Seperation ", picture: "images/aseparation.jpg" },
{ title: "Another Earth ", picture: "images/anotherearth.jpg" },
{ title: "A Heartbeat Away ", picture: "images/aheartbeataway.jpg" },
{ title: "Bad Teacher ", picture: "images/badteacher.jpg" },
{ title: "Begineers ", picture: "images/beginners.jpg" },
{ title: "Brotherhood ", picture: "images/brotherhood.jpg" },
{ title: "Bridesmaids ", picture: "images/bridesmaids.jpg" },
{ title: "Born To Be Wild ", picture: "images/borntobewild.jpg" },
{ title: "Blackthorn ", picture: "images/blackthorn.jpg" },
{ title: "Bellflower ", picture: "images/bellflower.jpg" },
{ title: "Butter ", picture: "images/butter.jpg" },
{ title: "Bunraku ", picture: "images/bunraku.jpg" },
{ title: "Cars 2 ", picture: "images/cars2.jpg" },
{ title: "Cost Of A Soul", picture: "images/costofasoul.jpg" },
{ title: "Carnage ", picture: "images/carnage.jpg" },
{ title: "Crazy Stupid Love ", picture: "images/crazystupidlove.jpg" },
{ title: "Cracks ", picture: "images/cracks.jpg" },
{ title: "Colombiana ", picture: "images/colombiana.jpg" },
{ title: "Cedar Rapids ", picture: "images/cedarrapids.jpg" },
{ title: "Captain America ", picture: "images/captainamerica.jpg" },
];

var dataList = new WinJS.Binding.List(movieArray);

Creating ListView

We have created data source and ahead and create a ListView. In ListView we need to set itemDataSource to MovieData.itemList.dataSource.

image

If you remember while creating data source we have created public namespace with name MovieData . in MovieData.js file so we need to add reference as below.

image

At this point if we run the application we will get output as below. Essentially below is the same array we get as output we created as data source

image

Now we need to create a template to render movie image and name of the movie. An ItemTemplate for ListView can be created as below.

image

Inside ItemTemplate there are two controls

  1. Image control to render thumbnail of the movie
  2. Inside div rendering title of movie.

Now go ahead and set the itemTemplate of ListView as below

image

At this point if we run application we should get ListView as below,

image

You can notice automatically WinJS has added scrollbar. By this point we should have HTML file as below,

Default.html


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ListViewBinding</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>

<!-- ListViewBinding references -->
<link href="/css/default.css" rel="stylesheet">
<script src="/js/default.js"></script>
<script src="/js/moviedata.js"></script>

</head>
<body>

<div id="headerTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
<div>
<h1 data-win-bind="innerText: title"></h1>
</div>
</div>

<div id="moviesTemplate"
data-win-control="WinJS.Binding.Template">

<div style="width: 150px; height: 130px;">
<img src="#" style="width: 100px; height: 100px;"
data-win-bind="alt: title; src: picture" />
<div>
<h4 data-win-bind="innerText:title"></h4>
</div>
</div>

</div>

<div id="movieListView"
data-win-control="WinJS.UI.ListView"
data-win-options="{ itemDataSource :MovieData.itemList.dataSource,
itemTemplate:moviesTemplate,
layout: {type: WinJS.UI.GridLayout} }">
</div>
</body>
</html>

Customizing ListView

If we see the ListView, it is not that immersive. we can customize a ListView by overriding the CSS. Each HTML file got a corresponding CSS file associated. For example for default.html there is a css file default.css.Now let us go ahead and override ListView properties. In below CSS

  • ListView height and width is set to 600 pixels and 800 pixels respectively
  • ListView border is set to 2 Pixel
  • Margin of each item in ListView is set to 10 Pixel
  • On hover on each item color would get changed to Red.

image

We need to put above CSS in default.css . After that when we run the application, we will get ListView as below. You can notice that on mouse hover color is changing to Red.

image

Grouping of ListView Items

To group the items in ListView, we need to call CreateGrouped JavaScript function from base.js. This function is defined as below

clip_image001

we can see that it takes three parameters. Explanation of parameters are given below

clip_image002

As you see createGrouped function takes three functions as input parameter. So let us create these functions one by one.

Below function will compare the groups. This function will be groupSorter

clip_image001[6]

This function will return group of the item.

clip_image002[6]

Below function will return Title of the group. In this case items would be grouped with first letter.

clip_image001[8]

In last step we need to call above three functions to create group and make a public namespace for this that is it accessible from other files.

clip_image003

By putting all codes together in mymoviedata.js file you will have two public namespaces. You need to set MovieGroupedData as datasource of ListView to create grouped data.

MovieGroupedData.js


(function () {
"use strict";
// http://www.allmoviephoto.com/photo/index_2011.html
var movieArray = [
{ title: "The Artist", picture: "images/TheArtist.jpg" },
{ title: "A Better Life", picture: "images/abetterlife.jpg" },
{ title: "Abduction", picture: "images/abduction.jpg" },
{ title: "African Cats", picture: "images/africancats.jpg" },
{ title: "Angel Crest", picture: "images/angelscrest.jpg" },
{ title: "Arthur", picture: "images/arthur.jpg" },
{ title: "Anonymous", picture: "images/anonymous.jpg" },
{ title: "A Dangerous Method", picture: "images/adangerousmethod.jpg" },
{ title: "A Good Old Fashioned Orgy ", picture: "images/agoodoldfashionedorgy.jpg" },
{ title: "A Seperation ", picture: "images/aseparation.jpg" },
{ title: "Another Earth ", picture: "images/anotherearth.jpg" },
{ title: "A Heartbeat Away ", picture: "images/aheartbeataway.jpg" },
{ title: "Bad Teacher ", picture: "images/badteacher.jpg" },
{ title: "Begineers ", picture: "images/beginners.jpg" },
{ title: "Brotherhood ", picture: "images/brotherhood.jpg" },
{ title: "Bridesmaids ", picture: "images/bridesmaids.jpg" },
{ title: "Born To Be Wild ", picture: "images/borntobewild.jpg" },
{ title: "Blackthorn ", picture: "images/blackthorn.jpg" },
{ title: "Bellflower ", picture: "images/bellflower.jpg" },
{ title: "Butter ", picture: "images/butter.jpg" },
{ title: "Bunraku ", picture: "images/bunraku.jpg" },
{ title: "Cars 2 ", picture: "images/cars2.jpg" },
{ title: "Cost Of A Soul", picture: "images/costofasoul.jpg" },
{ title: "Carnage ", picture: "images/carnage.jpg" },
{ title: "Crazy Stupid Love ", picture: "images/crazystupidlove.jpg" },
{ title: "Cracks ", picture: "images/cracks.jpg" },
{ title: "Colombiana ", picture: "images/colombiana.jpg" },
{ title: "Cedar Rapids ", picture: "images/cedarrapids.jpg" },
{ title: "Captain America ", picture: "images/captainamerica.jpg" },
];

var dataList = new WinJS.Binding.List(movieArray);

function compareGroups(left, right) {
return left.charCodeAt(0) - right.charCodeAt(0);
}

function getGroupKey(dataItem) {
return dataItem.title.toUpperCase().charAt(0);
}

function getGroupData(dataItem) {
return {
title: dataItem.title.toUpperCase().charAt(0)
};
}

var publicMembers =
{
itemList: dataList
};
WinJS.Namespace.define("MovieData", publicMembers);

var groupedItemsList = dataList.createGrouped(getGroupKey, getGroupData, compareGroups);
WinJS.Namespace.define("MovieGroupedData",
{
groupedItemsList: groupedItemsList
});

})();

By this point we have created functions to group data .Next we need to modify ListView datasource to group ListView items. For that let us created a header template. Header template will display Title of the group. Header Template can be created in the same way of Item Template. Header template is given below

image

And we have already created Item Template as following.

image

To group items in ListView we need to create Header Template and Item Template. We have created this in previous step. Next we need to set datasource of the ListView to bind grouped items. ListView can be created as below for the grouped items

image

If we put all codes together then default.html will have following codes.

Default.html

Let us go ahead and run the application. We should be getting output as following.

clip_image002[13]

We have grouped items in ListView. Next let us add Semantic View. To add Semantic View you need to put ListView in side Semantic View control. In Semantic Zoom we will have two views of same ListView. We need to create a view for the zoom out . For zoom out Template can be created as given below.

clip_image003[4]

After creation of Template let us go ahead and create a ListView for Zoom Out view.

clip_image005[4]

ItemDataSource of zoomed ListView is same as of the zoomed in ListView. Now we need to put both ListView , Zoomed In and Zoomed out in the Semantic Zoom control. We can put ListView controls in Semantic Zoom control as below

clip_image007[4]

Now we should have default.html as following

Default.html


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ListViewBinding</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>

<!-- ListViewBinding references -->
<link href="/css/default.css" rel="stylesheet">
<script src="/js/default.js"></script>
<script src="/js/moviedata.js"></script>

</head>
<body>

<div id="headerTemplate"
data-win-control="WinJS.Binding.Template"
style="display: none">
<div>
<h1 data-win-bind="innerText: title"></h1>
</div>
</div>

<div id="moviesTemplate"
data-win-control="WinJS.Binding.Template">

<div style="width: 150px; height: 130px;">
<img src="#" style="width: 100px; height: 100px;"
data-win-bind="alt: title; src: picture" />
<div>
<h4 data-win-bind="innerText:title"></h4>
</div>
</div>

</div>

<!--<div id="movieListView"
data-win-control="WinJS.UI.ListView"
data-win-options="{ itemDataSource :MovieData.itemList.dataSource,
itemTemplate:moviesTemplate,
layout: {type: WinJS.UI.GridLayout} }">
</div>  -->

<h1>Rate Movies Application</h1>

<div id="movieListView"
data-win-control="WinJS.UI.ListView"
data-win-options="{ itemDataSource : MovieGroupedData.groupedItemsList.dataSource,
groupDataSource: MovieGroupedData.groupedItemsList.groups.dataSource,
itemTemplate: moviesTemplate,
groupHeaderTemplate: headerTemplate,
layout: {type: WinJS.UI.GridLayout} }">
</div>
</body>
</html>

Next we need to add some CSS to make it more immersive. In default.css , we need to add below css


.win-listview
{
height: 600px;
width: 800px;
border: 2px solid gray;
}

.win-listview .win-container {
margin: 10px;
}
.win-listview .win-container:hover {
background-color: red;
border-color: red;
}
.semanticZoomItem
{
width: 130px;
height: 130px;
background-color: rgba(38, 160, 218, 1.0);
}

.semanticZoomItem .semanticZoomItem-Text
{
padding: 10px;
line-height: 150px;
white-space: nowrap;
color: white;
}

On running we should be getting the below output

clip_image002[15]

On tapping or pressing of crtl and arrow key you should be getting the semantic zoom view. Semantic Zoom View of ListView is as following image.

image

In this way we can work ListView and SemanticZoom WinJS controls. In further post we will try to pull data from service. I hope this post is useful. Thanks for reading.


Filed under: Windows Store Apps

Viewing all articles
Browse latest Browse all 3

Latest Images

Trending Articles





Latest Images