jqgrid Page 1 of x pager

If one press “Next” button a new request will be send to the server. The request will contain page=2 and, for example, rows=10 parameters as a part of URL (if one want to get next 10 rows of the second page).

Your server code should read this parameters and send back the corresponding data rows. The JSON data send back from the server should look like following

{ 
  "total": "5", 
  "page": "2", 
  "records": "55",
  "rows" : [
    {"id" :"21", "cell" :["cell11", "cell12", "cell13"]},
    {"id" :"22", "cell" :["cell21", "cell22", "cell23"]},
      ...
    {"id" :"30", "cell" :["cell31", "cell32", "cell33"]},
  ]
}

(see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data). So the data must contain the correct value for the page (page=2). In general it is possible, that now you have less data as before and you give back the page number 1 on the request to get the page number 2.

So I suggest that currently your server code don’t give back the correct value of page in the output.

UPDATED: OK Jeff. I continue my answer in jqgrid setGridParam datatype:local and post how is promised a code how do server side paging, sorting and searching (or advanced searching).

First of all in the example I will not really implement sorting and searching and only simulate paging where you have problem now. The real paging, sorting and searching should be implemented as the corresponding SELECT statements to SQL database where the data exists. The sorting follow to the ORDER BY, searching to WHERE and paging to constructions like TOP(x), TOP(x) with LEFT OUTER JOIN or the usage of ROW_NUMBER() OVER(...) constructs. But these all are not the subject of your question. So I reduce all to the simple simulation of data paging.

I start with the code of the ASMX Web Method:

public JqGridData TestMethod (int page, int rows, string sidx, string sord,
    bool _search, string searchField, string searchOper, string searchString) {
    // for advance search use "string filters" instead of the last three parameters
    int recordsCount = 205;

    int startIndex = (page - 1) * rows;
    int endIndex = (startIndex + rows < recordsCount) ?
                   startIndex + rows : recordsCount; 
    List<TableRow> gridRows = new List<TableRow> (rows);
    for (int i = startIndex; i < endIndex; i++) {
        gridRows.Add (new TableRow () {
            id = i,
            cell = new List<string> (2) {
                string.Format("Name{0}", i), 
                string.Format("Title{0}", i)
            }
        });
    }

    return new JqGridData () {
        total = (recordsCount + rows - 1) / rows,
        page = page,
        records = recordsCount,
        rows = gridRows
    };
}

where classes JqGridData and TableRow are defined like following:

public class TableRow {
    public int id { get; set; }
    public List<string> cell { get; set; }
}
public class JqGridData {
    public int total { get; set; }
    public int page { get; set; }
    public int records { get; set; }
    public List<TableRow> rows { get; set; }
}

We skip any verification of input parameters of the TestMethod to make the code example more readable.

Now the client code:

$("#list").jqGrid({
    url: './MyTestWS.asmx/TestMethod',
    datatype: 'json',
    mtype: 'POST',
    ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
    serializeGridData: function (postData) {
        if (postData.searchField === undefined) postData.searchField = null;
        if (postData.searchString === undefined) postData.searchString = null;
        if (postData.searchOper === undefined) postData.searchOper = null;
        //if (postData.filters === undefined) postData.filters = null;
        return JSON.stringify(postData);
    },
    jsonReader: {
        root: function (obj) { return obj.d.rows; },
        page: function (obj) { return obj.d.page; },
        total: function (obj) { return obj.d.total; },
        records: function (obj) { return obj.d.records; }
    },
    // you can also use following more simple form of jsonReader instead:
    // jsonReader: { root: "d.rows", page: "d.page", total: "d.total",
    //               records: "d.records", id: "d.names" }
    colModel: [
        { name: 'name', label: 'Name', width: 250 },
        { name: 'title', label: 'Title', width: 250 }
    ],
    rowNum: 10,
    rowList: [10, 20, 300],
    sortname: 'name',
    sortorder: "asc",
    pager: "#pager",
    viewrecords: true,
    gridview: true,
    rownumbers: true,
    height: 250,
    caption: 'My first grid'
}).jqGrid('navGrid', '#pager', {edit: false, add: false, del: false, search: true});
//                {}, // use default settings for edit
//                {}, // use default settings for add
//                {}, // delete instead that del:false we need this
//                {multipleSearch : true} // enable the advanced searching
//                );

In the code I use the same technique like in jqgrid setGridParam datatype:local but the code of serializeGridData function is a little different. Because we use POST and not GET method to get the data from the server all input parameters of the web method must be always set. On the other side jqGrid set not always parameters searchField, searchOper and searchString, but only if _search=true. For example at the first load of jqGrid, the _search=false and searchField, searchOper and searchString are not defined in the postData. To fix the problem we initialize undefined parameters with null.

To implement sorting one needs to use sidx (sort index) and sord (sort direction: "asc" or "desc") parameters.

To implement searching one needs to use other parameters _search, searchField, searchOper, searchString.

During advanced searching instead of searchField, searchOper, searchString parameters the parameter filters must be used (see commented lines). The data must be decoded with respect of a JSON deserializer. So must be set multipleSearch : true in the jqgrid. The serializeGridData function should be replaced to

serializeGridData: function (postData) {
    if (postData.filters === undefined) postData.filters = null;
    return JSON.stringify(postData);
}

and the prototype of the web method should be changed to

public JqGridData TestMethod (int page, int rows, string sidx, string sord,
    bool _search, string filters)

to decode the parameter filters one can use such simple code:

if (_search && !String.IsNullOrEmpty (filters)) {
    JavaScriptSerializer serializer = new JavaScriptSerializer ();
    jqGridSearchFilter searchFilter =
        serializer.Deserialize<jqGridSearchFilter> (filters);
    // use the searchFilter here
}

where the class jqGridSearchFilter can be defined like following:

public class jqGridSearchFilterItem {
    public string field { get; set; }
    public string op { get; set; }
    public string data { get; set; }
}
public class jqGridSearchFilter {
    public string groupOp { get; set; }
    public List<jqGridSearchFilterItem> rules { get; set; }
}

I hope this information will be enough for you to implement any kind of jqGrid usage with respect of ASMX Web Method.

I used here a simplest data send from server to the client with additional id outside of the main data. If one of the columns which you have in the table is the id, you can a little reduce the data send to the server. See Jqgrid 3.7 does not show rows in internet explorer for more details.

Leave a Comment