locked
Limiting items in Gridview categories in javascript

    Question

  • I have seen some other threads but am struggling with java script and implementing this feature

    On the root gridview page I want to limit the number of items under each category to 4,

    From my understanding the only way to do this with the java script is to create a separate data array

    Pointing my gridview to the separate and limited data array (which would only have 4 items under each catagory

    Than having my button link back to my original data array with the 200 plus items

    If someone could upload a version of the example with such code and be able to explain to me how it works, would be a true lifesaver, Any comments/help is greatly appreciated. {I have figured out how to limit the number in the group details page with c# but I am worn down by trying to implement this for groups}

    Tuesday, October 16, 2012 1:52 AM

All replies

  • Am I allowed to bump :) 
    Saturday, November 10, 2012 5:28 PM
  • Below I have implemented what you wanted to do. I have used two additional JavaScript libraries: jQuery and Underscore.

    First create a new Windows Store Navigation App.

    Create a new JavaScript file named data.js in the "js" folder and paste the code below into it.
    The code generates 20 items per group. It also contains a method (reduceGroupItems()) that reduces the number of items per group to four (4) for the front page list view.

    (function () {
    
        var items = generateItems();
        var frontPageItems = reduceGroupItems(items);
        
        function generateItems() {
            var items = [],
                group = undefined,
                groupNumber = 1;
    
            for (var i = 0; i < 500; i++) {
    
                // Create a new group. Each group will have 20 items.
                if (i % 20 === 0) {
                    group = { groupTitle: "Group nr " + groupNumber, groupKey: groupNumber };
                    groupNumber++;
                }
    
                var newItem = { title: i + " Lorem ipsum dolor sit amet", group: group };
    
                items.push(newItem); // Insert a new item to the item list.
            }
    
            return items;
        }
    
        function reduceGroupItems(itemsToReduce) {
    
            // Group items by their group key.
            var groupedItems = _.groupBy(itemsToReduce, function (item) {
                return item.group.groupKey;
            });
    
            // Convert to array to make it more easy to iterate over the groups.
            groupedItems = _.toArray(groupedItems);
    
            var reducedItems = [];
    
            // Loop through the collection of groups.
            groupedItems.forEach(function (group) {
    
                // This will execute the function four (4) times.
                _(4).times(function (i) {
    
                    // Add item to the reduced items list.
                    reducedItems.push(group[i]);
                });
            });
    
            return reducedItems;
        }
    
        function findGroupItems(groupKey) {
            
            // Return all items with the specified group key.
            return _.filter(items, function(item) {
                return item.group.groupKey === groupKey;
            });
        }
    
        WinJS.Namespace.define("Data", {
            allItems: items,
            reducedItems: frontPageItems,
            groupItems: findGroupItems
        });
    })();

    This is the home.js file:

        "use strict";
    
        WinJS.UI.Pages.define("/pages/home/home.html", {
            ready: function (element, options) {
                var listView = $(".root-listView")[0].winControl,
                    itemTemplate = $(".item-template")[0],
                    groupHeaderTemplate = $(".group-header-template")[0];
    
                var data = Data.reducedItems;
                
                // Create a grouped WinJS list.
                var frontPageData = new WinJS.Binding.List(data).createGrouped(function(item) { return item.group.groupKey; }, function(item) { return item.group; });
    
                WinJS.UI.setOptions(listView, {
                    itemDataSource: frontPageData.dataSource,
                    itemTemplate: itemTemplate,
                    groupDataSource: frontPageData.groups.dataSource,
                    groupHeaderTemplate: groupHeaderTemplate,
                    layout: new WinJS.UI.GridLayout()
                });
            },
            
            // Navigates to the groupHeaderPage. Called from the groupHeaders.
            navigateToGroup: function (key) {
                WinJS.Navigation.navigate("/pages/groupDetails/groupDetails.html", { groupKey: key });
            },
        });
    })();

    This is the home.html file:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>homePage</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>
    
        <link href="/css/default.css" rel="stylesheet" />
        <link href="/pages/home/home.css" rel="stylesheet" />
        <script src="/pages/home/home.js"></script>
    </head>
    <body>
        <!-- The content that will be loaded and displayed. -->
        <div class="fragment homepage">
            <header aria-label="Header content" role="banner">
                <button class="win-backbutton" aria-label="Back" disabled type="button"></button>
                <h1 class="titlearea win-type-ellipsis">
                    <span class="pagetitle">Welcome to App4!</span>
                </h1>
            </header>
            <section aria-label="Main content" role="main">
                
                <div class="group-header-template" data-win-control="WinJS.Binding.Template">
                    <div data-win-bind="textContent: groupTitle; groupKey: groupKey" onclick="Application.navigator.pageControl.navigateToGroup(event.srcElement.groupKey)"></div>
                </div>
    
                <div class="item-template" data-win-control="WinJS.Binding.Template">
                    <div class="tile" data-win-bind="textContent: title"></div>
                </div>
    
                <div class="root-listView" data-win-control="WinJS.UI.ListView"></div>
            </section>
        </div>
    </body>
    </html>
    

    This is the home.css file:

    .homepage .tile {
        color: white;
        background-color: gray;
        width: 150px;
        height: 150px;
    }
    
    .homepage .root-listView {
        width: 100%;
        height: 100%;
    }
    
    .homepage .win-groups.win-listview > .win-horizontal .win-surface {
        margin-left: 50px;
    }

    Now create a new folder named"groupDetails" in the "pages" folder. In there create a new Page Control named "groupDetails".

    This is the groupDetails.js file:

    (function () {
        "use strict";
    
        WinJS.UI.Pages.define("/pages/groupDetails/groupDetails.html", {
            ready: function (element, options) {
                var listView = $(".item-listView")[0].winControl,
                    template = $(".item-template")[0];
    
                var data = Data.groupItems(options.groupKey),
                    items = new WinJS.Binding.List(data);
                
                WinJS.UI.setOptions(listView, {
                    itemDataSource: items.dataSource,
                    itemTemplate: template,
                    layout: new WinJS.UI.GridLayout()
                });
            }
        });
    })();
    

    This is the groupDetails.html file:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>groupDetails</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>
    
        <link href="groupDetails.css" rel="stylesheet" />
        <script src="groupDetails.js"></script>
    </head>
    <body>
        <div class="groupDetails fragment">
            <header aria-label="Header content" role="banner">
                <button class="win-backbutton" aria-label="Back" disabled type="button"></button>
                <h1 class="titlearea win-type-ellipsis">
                    <span class="pagetitle">Welcome to groupDetails</span>
                </h1>
            </header>
            <section aria-label="Main content" role="main">
                
                <div class="item-template" data-win-control="WinJS.Binding.Template">
                    <div class="tile" data-win-bind="textContent: title"></div>
                </div>
    
                <div class="item-listView" data-win-control="WinJS.UI.ListView"></div>
            </section>
        </div>
    </body>
    </html>

    This is the groupDetails.css file:

    .groupDetails .tile {
        color: white;
        background-color: gray;
        width: 150px;
        height: 150px;
    }
    
    .groupDetails .item-listView {
        width: 100%;
        height: 100%;
    }
    
    .groupDetails .win-surface {
        margin-left: 120px;
        margin-bottom: 50px;
    }
    

    Remember to download the two JavaScript libraries and reference them in the default.html file (along with data.js).

    • Proposed as answer by Aratys Sunday, November 11, 2012 5:40 PM
    Sunday, November 11, 2012 3:12 PM
  • You are using a WinJS.Binding.List()?

    var x = WinJS.Binding.List([some array]);
    var y = x.createFiltered(function(foo) {

    return x.indexOf(foo) < 4;

    });

    Then set 
    ListView.itemDataSource = x.dataSource or y.dataSource

    Note you may have to call notifyMutated() if you do unshift/splice/push/pop/etc...

    • Proposed as answer by Cobra Tap Sunday, November 11, 2012 5:34 PM
    Sunday, November 11, 2012 5:34 PM