I am trying to figure out how to user the paging functionality of the jqGrid. Currently I am stuck on Page 1 of 4. No matter if I press the Next button or not. It just stays on 1.
I am using ASP.Net with a webservice to populate my JSON data. How do capture the event from the client to populate the property on the webservice to bring back the correct value?
Any help is appreciated.
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.