locked
Grouping the data in a winjs.ui.listview that is based on REST

    Question

  • Hi,

    I want to display a listview grouped by a certain field.

    My data is as follows

    <div id="productTemplate" data-win-control="WinJS.Binding.Template">
            <div class="productSummary">
                <h1><span data-win-bind="innerText:Accno"></span></h1>
                <h3><span data-win-bind="innerText:Address"></span></h3>
                <h2><span data-win-bind="innerText:Status"></span></h2>
            </div>
    
        </div>
        <div id="productGroupHeaderTemplate" data-win-control="WinJS.Binding.Template">
            <div class="productGroupHeader">
                <h1 data-win-bind="innerText: title"></h1>
            </div>
        </div>
        <div id="SummaryGrid" data-win-control="WinJS.UI.ListView"
             data-win-options="{
                                            itemDataSource:DataExample.dataList.dataSource,
                                            itemTemplate:select('#productTemplate'),
                                            groupDataSource:DataExample.dataList.groups.dataSource,
                                            groupHeaderTemplate:select('#productGroupHeaderTemplate'),
                                            layout:{type:WinJS.UI.GridLayout}}">
        </div>

    My JS code is

    // For an introduction to the Blank template, see the following documentation:
    // http://go.microsoft.com/fwlink/?LinkId=232509
    (function () {
        "use strict";
    
        var app = WinJS.Application;
    
        var dataList = new WinJS.Binding.List();
    
        var activation = Windows.ApplicationModel.Activation;
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll());
                //document.getElementById("btnExample").addEventListener("click", JSonRecord, false);
                JSonRecord();
                GroupRecords();
            }
        };
    
        app.oncheckpoint = function (args) {
            // TODO: This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // args.setPromise().
        };
    
       
    
        function JSonRecord(event) {
    
    
    
            var baseURL = "url";
    
            WinJS
                .xhr(
                        {
                            type: "GET",
                            url: baseURL,
                            headers: { "Content-type": "application/json;charset=utf-8" }
                        }
                     )
                .then
                     (
                        function (response) {
    
                            var sourceData = JSON.parse(response.responseText);
    
                            for (var i = 0; i < sourceData.length; i++) {
    
                                //dataList.push(sourceData[i]);
    
                                dataList.push({
                                    Accno: sourceData[i].Accno,
                                    Address: sourceData[i].Address,
                                    Priority: sourceData[i].Priority,
                                    Status: sourceData[i].Status
                                    //firstname: sourceData[i].firstname,
                                    //LastName: sourceData[i].LastName
                                });
                            }
                        }, function (error) {
                            console.log(error);
                        });
    
        }
    
        function GroupRecords(event) {
            // Create grouped data source
            var groupedProducts = dataList.createGrouped(
                function (dataItem) {
                    return dataItem.Priority;
                },
                function (dataItem) {
                    return { title: dataItem.Priority };
                },
                function (group1, group2) {
                    return group1.charCodeAt(0) - group2.charCodeAt(0);
                }
            );
    
            // Expose the grouped data source
            WinJS.Namespace.define("DataExample", {
                dataList: groupedProducts
            });
    
    
            //WinJS.Namespace.define("ListViewDemos", {
            //    products: groupedProducts
            //});
        }
    
        app.start();
    })();
    

    When I use a static array of data it works fine but when using a REST service the application breaks in the debugger and nothing is displayed on the screen. What is wrong with this code. If I use the REST service without the grouping then it works perfectly.

    Thanks,

    Rajesh

    Wednesday, November 13, 2013 1:31 PM

All replies

  • Hi Rajesh,

    Can we say if you use REST service with grouping data, the app crashes, but without grouping it works fine.

    I suggest you could try put "GroupRecords()" in your WinJS.xhr success part to see if your app works, let's say if you WinJS.xhr fetching data action is not finished, there is no data to group and of course your app will display no data, you have to ensure the data exist before you can group them.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.



    Thursday, November 14, 2013 11:42 AM
    Moderator
  • Hi James,

    Thanks for your reply. Today I did some more research on this and I observed the following.

    1. Commented out the entire HTML code for the ListView.

    2. Put a break point on the JSonRecord() line to step through.

    I observed that in WinJS the entire code is checked for variable declaration. Then the code steps through each method. Interesting to say that when you step through the loop for pushing the data from the Json responseText to the WinJS.Binding.List, it also loops through the grouping function i.e. to say it groups the data on the fly instead of grouping at the end of pushing.

    And then in the end the code ends up in the debugger line in base.js. No hint is given what exactly went wrong and which part of the code failed.

    As explained earlier using a hard coded arraylist in JavaScript achieved the result.

    Thanks,

    Rajesh 

    Thursday, November 14, 2013 12:29 PM
  • This code works a bit better for me when I move JSonRecord() and GroupRecords() to the initialization section:

    if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
        // TODO: This application has been newly launched. Initialize
        // your application here.

        // Moved these functions.
        JSonRecord();
        GroupRecords();

        }

    although I think there is some other issue. It sounds like you end up in the terminateAppHandler() function. You can look at the error ('e') in that function for a description.

    Thursday, November 14, 2013 6:15 PM
  • Hi,

    Thanks a lot for pointing it out. Yes it works when placed as mentioned by you.

    Actually I was working on a navigation application and so I placed this code in the ready function of the 2nd page of the application.

        WinJS.UI.Pages.define("/pages/page2/page2.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.
                //element.setAttribute("/pages/page2/page.html", window.getComputedStyle(this._element, null).direction);
                JSonRecord();
                GroupRecords();
    

    But it fails here. Wondering what is the difference between the single page navigation and multiple page navigation. Is there any pre-caution to be followed when attempting to populate data on the load event of a page.

    The error that I am getting is dataList is undefined. The code breaks in this line of the previous page.

    function image1Click(mouseEvent) {
            WinJS.Navigation.navigate("/pages/page2/page2.html");
        }

    Thanks,

    Rajesh.

    Friday, November 15, 2013 1:53 PM