1

I am using jqGrid (inlineNav) with data from azure service and interested in learning how one could use server side sorting and paging with Azure Mobile Services.

Please share thoughts around this.

Oleg
  • 220,925
  • 34
  • 403
  • 798
Mohit
  • 39
  • 1
  • 2
  • 10

1 Answers1

3

Windows Azure Mobile Services provides REST API which can be used to get/insert/edit/delete data of the the tables which you configured for the corresponding access (see the documentation). Query records operation request uses HTTP GET verb. It supports Open Data Protocol (OData) URI options $orderby, $skip, $top and $inlinecount which could be used to fill jqGrid.

$("#list4").jqGrid({
    url : 'https://mohit.azure-mobile.net/tables/Schedules',
    datatype: "json",
    height: "auto",
    colModel: [
        { name: "RouteId", width: 50 },
        { name: "Area", width: 130 }
    ],
    cmTemplate: {editable: true, editrules: { required: true}},
    rowList: [10, 20, 30],
    rowNum: 10,
    prmNames: { search: null, nd: null },
    ajaxGridOptions: {
        contentType: "application/json",
        headers: {
            "X-ZUMO-APPLICATION": "myKey"
        }
    },
    serializeGridData: function (postData) {
        if (postData.sidx) {
            return {
                $top: postData.rows,
                $skip: (parseInt(postData.page, 10) - 1) * postData.rows,
                $orderby: postData.sidx + " " + postData.sord,
                $inlinecount: "allpages"
            };
        } else {
            return {
                $top: postData.rows,
                $skip: (parseInt(postData.page, 10) - 1) * postData.rows,
                $inlinecount: "allpages"
            };
        }
    },
    beforeProcessing: function (data, textStatus, jqXHR) {
        var rows = parseInt($(this).jqGrid("getGridParam", "rowNum"), 10);
        data.total = Math.ceil(data.count/rows);
    },
    jsonReader: {
        repeatitems: false,
        root: "results",
        records: "count"
    },
    loadError: function (jqXHR, textStatus, errorThrown) {
        alert('HTTP status code: ' + jqXHR.status + '\n' +
            'textStatus: ' + textStatus + '\n' +
            'errorThrown: ' + errorThrown);
        alert('HTTP message body (jqXHR.responseText): ' + '\n' + jqXHR.responseText);
    },
    pager: "#pager1",
    sortname: "Area",
    viewrecords: true,
    caption: "Schedule Data",
    gridview: true
});

Some comments to the above code:

  • I removed sortable: false to allow sorting of grid by click on the column header
  • with respect of prmNames option one can remove sending of unneeded parameters to the server or rename it. I used prmNames: { search: null, nd: null } to deny sending of _search and nd options. One could use sort: "$orderby", rows: "$top" to rename two other parameters, but because we need to calculate $skip and append sord after sidx we need to use serializeGridData. So the renaming of other parameters are not needed in the case.
  • using serializeGridData we construct the list of options which will be send to the server.
  • ajaxGridOptions will be used to set additional parameters of jQuery.ajax request which do jqGrid internally for access to the server. The options which I use in the example set Content-Type: application/json and X-ZUMO-APPLICATION: myKey in the HTTP headers
  • the response from the server don't contains total (the total number of pages), so we use beforeProcessing callback to fill the property based on other information before the response will be processed.
  • because we use $inlinecount=allpages options in the URL the response from the server will contains information about the total number of records and the page of data will be wrapped in the results part of the answer. So we use jsonReader: {repeatitems: false, root: "results", records: "count"} to read the response.
  • we have to remove loadonce: true option because the server returns only the requested page of data instead of the whole set of data.
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • thanks oleg for sharing such a detailed version. I am going through code. there is a some issue with "$orderby: postData.sidx + " " + postData.sord,". If I use this, data in grid does not load as it results in "orderby=+asc" in url. I think we need to define "sidx" in "prmNames". Although I tried same, but it did not work out. – Mohit Apr 13 '13 at 10:19
  • Another question in my mind : which one is better: fetching data per page (as you have done at present) or fetching all data once and avoid multiple server roundtrips? – Mohit Apr 13 '13 at 10:27
  • @Mohit: Sorry, but I verified one more time my working test with the code which I posted and could not see any differences. I recommend you to verify that you really use `prmNames: { search: null, nd: null }` and that you defined `serializeGridData` *once* with the code which I posted. You can start Developer Tools with F12, set breakpoint on the first line of `serializeGridData` and start debugging. You can verify all properties of `postData`. You can also post me per email the URL with the modified demo. – Oleg Apr 13 '13 at 11:11
  • @Mohit: The choice whether to use `loadonce: true` depend on the number of rows in the grid and from the performance of azure page. I think that if you have less then 1000 rows `loadonce: true` will be the best choice. For more as 10000 rows you should definitively use server side paging. The edge between 1000 and 10000 when you should use client or server side paging depend on your tests and the performance of web browsers which you support. See [the answer](http://stackoverflow.com/a/15815852/315935) for details. – Oleg Apr 13 '13 at 11:16
  • @Mohit: I find only very important from design point of view to have full salable solution. So that you could use jqGrid with any size of tables of the backend. The choice `loadonce: true` will be just optimization step for small grids. Additional benefit would be simple usage of client side filtering/searching of data (see [here](http://www.trirand.com/jqgridwiki/doku.php?id=wiki:toolbar_searching) and [here](http://www.trirand.com/jqgridwiki/doku.php?id=wiki:advanced_searching)) – Oleg Apr 13 '13 at 11:20
  • using everything as you mentioned in code...so while debugging I could see that sidx="" so I thought I need to define it properly in prmNames...mailing you details with modified demo – Mohit Apr 13 '13 at 11:24
  • @Mohit: You don't need define `sidx` because per default `sort:"sidx"` is defined in `prmNames`. The page `page3.html` and `app2.js` contains still old code which don't use server side paging. Where is the code which you use? – Oleg Apr 13 '13 at 11:31
  • @Mohit: I modified the code to make it working with or without using `sortname` option. I looked in your demo and recommend you to remove `id` column from the grid which seems me unneeded. – Oleg Apr 13 '13 at 12:22
  • with help of oleg, we could find issue. we need to define one more parameter "sortname" parameter and take care that "sortable:false" is not defined in colModel. Thanks to Oleg again – Mohit Apr 13 '13 at 12:43
  • @Mohit: You are welcome! The last version of `serializeGridData` from my answer should work with or without `sortname`. – Oleg Apr 13 '13 at 12:54