[Windows 8] HTML/JS : VariableSize List View and Template Selection

24. January 2013 00:01 by Renaud in Windows 8  //  Tags: , ,   //   Comments (0)

Here is my first attempt to achive a VariableSize List View in HTML /JS. I tried to apply the same concept as what I knew about XAML and the TemplateSelector, so I started with a function returning the right template, and finally I come to this satisfaying solution :) I just made a first try to achieve this : http://sdrv.ms/Yosvcr Instead of giving a Template to the ListView, I gave it a function that selects the right template according to the index of the item. Then you have different template, with different style, but all the items style have the same size. Then, if you read the end of this page, the paragraph about cell-spanning, you'll see that you need to change two more things to achieve what you want : change the groupInfo or itemInfo properties of the GridLayout used in your ListView. Here are the key parts of the sample I provided : 1/ First, you declare two or more templates + your listview:

    <div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template">
        <div class="mediumItem">
            <h4 data-win-bind="innerText: title"></h4>
            <h6 data-win-bind="innerText: text"></h6>
        </div>
    </div>

    <div id="largeListIconTextTemplate" data-win-control="WinJS.Binding.Template">
        <div class="largeItem">
            <h2 data-win-bind="innerText: title"></h2>
            <h3 data-win-bind="innerText: text"></h3>
        </div>
    </div>

    <div id="listView"
        data-win-control="WinJS.UI.ListView"
        data-win-options="{ 
                itemDataSource: myData.items.dataSource, 
                itemTemplate:myData.template, 
                selectionMode: 'none', 
                tapBehavior: 'none', 
                swipeBehavior: 'none'
            }">
    </div>

Notice the itemTemplate property. It refers to myData.template, which is a function I defined in my JS file. Then you can add some CSS :

.mediumItem {
    width:100px;
    height:100px;
    background-color:cornflowerblue;
}

.largeItem {
    width:100px;
    height:150px;
    background-color:green;
}

Then, some javascript in a separated file :

(function () {
    "use strict";

    // Create a new bindable list
    var list = new WinJS.Binding.List([]);
    // some fake data
    list.push({ title: "Titre 1", text: "Texte 1" });
    list.push({ title: "Titre 2", text: "Texte 2" });
    list.push({ title: "Titre 3", text: "Texte 3" });
    list.push({ title: "Titre 4", text: "Texte 4" });

    // my function that selects the template
    function selectTemplate(itemPromise) {
        // it receives a promise of an item
        return itemPromise.then(function (item) {

            // Then I can get the item
            // and based on its index property I can choose a templatE.
            var container = window.document.createElement("div");
            var itemTemplate;
            switch (item.index) {
                case 0:
                    itemTemplate = WinJS.Utilities.query("#mediumListIconTextTemplate")[0];
                    break;
                case 1:
                    itemTemplate = WinJS.Utilities.query("#largeListIconTextTemplate")[0];
                    break;
                default:
                    itemTemplate = WinJS.Utilities.query("#largeListIconTextTemplate")[0];
                    break;
            }

            // I put my item in a container and style it with the choosen template.
            itemTemplate.winControl.render(item.data, container);
            return container;
        });
    }

    // The selection function has to be marked as supported for processing or you get an error.
    WinJS.Utilities.markSupportedForProcessing(selectTemplate);

    // declare the model and expose the selectTemplate function.
    WinJS.Namespace.define("myData",
    {
        items: list,
        template: selectTemplate
    });

})();

At this point, it uses the right template. But I still have to change the Layout, as explained in the msdn doc. So when the page gets processed by WinJS to display the controls :

           args.setPromise(WinJS.UI.processAll().then(function () {
                var listView = WinJS.Utilities.query('#listView')[0].winControl;
                listView.layout = new WinJS.UI.GridLayout;

                // Enable CellSpanning and give base size.
                listView.layout.groupInfo = function () {
                    return {
                        enableCellSpanning: true,
                        cellWidth: 50,
                        cellHeight: 50
                    };
                }
            }));

With those settings, the cell containing your item will be sized to fit best your template!

 

Add comment

  Country flag

biuquote
Loading

TextBox

About the author

I'm a developer, blog writer, and author, mainly focused on Microsoft technologies (but not only Smile). I'm Microsoft MVP Client Development since July 2013.

Microsoft Certified Professional

I'm currently working as an IT Evangelist with an awesome team at the Microsoft Innovation Center Belgique, where I spend time and energy helping people to develop their projects. I also give training to enthusiastic developers and organize afterworks with the help of the Belgian community.

MIC Belgique

Take a look at my first book (french only): Développez en HTML 5 pour Windows 8

Développez en HTML5 pour Windows 8

Membre de l'association Fier d'être développeur

TextBox

Month List