asp.net - jqgrid Página 1 de x pager
web-services jqgrid-asp.net (2)
Ok, estoy respondiendo a esto cuando tomé lo que Oleg había dicho antes, pero descubrí exactamente a qué se refería.
Mi llamada .ajax está envuelta en una función que pasa postdata como parámetro. No pude encontrar ninguna documentación sobre ese parámetro, pero pensé que tal vez era allí donde estaba contenido el valor de la página. Como puede ver, hice una alerta con postdata.page y baja y he aquí que obtuve un valor (basado en el clic del siguiente botón).
Así que creé un parámetro en mi servicio web llamado página (entero).
Solo como nota al margen, le pasa un valor entero de jQuery a su servicio web ASP.Net de la siguiente manera:
data: "{''page'':''" + postdata.page + "''}"
Debajo está la función completa:
function processrequest(postdata) {
alert(postdata.page);
$(".loading").show();
$.ajax({
type: "POST",
data: "{''page'':''" + postdata.page + "''}",
datatype: "json",
url: "../webServices/myTestWS.asmx/testMethod",
contentType: "application/json; charset-utf-8",
complete: function (jsondata, stat) {
if (stat == "success") {
var thegrid = jQuery("#list")[0];
var jsonObject = (eval("(" + jsondata.responseText + ")"));
thegrid.addJSONData(jsonObject.d);
$(".loading").hide();
} else {
$(".loading").hide();
alert("Error with AJAX callback");
}
}
});
}
Estoy intentando descubrir cómo usar la funcionalidad de paginación de jqGrid. Actualmente estoy atascado en la página 1 de 4. No importa si presiono el botón Siguiente o no. Simplemente permanece en 1.
Estoy usando ASP.Net con un servicio web para completar mis datos JSON. ¿Cómo capturar el evento del cliente para poblar la propiedad en el servicio web para recuperar el valor correcto?
Cualquier ayuda es apreciada.
Si se presiona el botón "Siguiente", se enviará una nueva solicitud al servidor. La solicitud contendrá la page=2
y, por ejemplo, rows=10
parámetros como parte de la URL (si uno quiere obtener las siguientes 10 filas de la segunda página).
El código del servidor debe leer estos parámetros y enviar de vuelta las filas de datos correspondientes. El envío de datos JSON desde el servidor debería verse como sigue
{
"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"]},
]
}
(ver http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data ). Entonces los datos deben contener el valor correcto para la page
(página = 2). En general, es posible que ahora tenga menos datos que antes y que devuelva el número de página 1 en la solicitud para obtener el número de página 2.
Así que sugiero que actualmente su código de servidor no devuelva el valor correcto de la page
en la salida.
ACTUALIZADO : OK Jeff. Continúo mi respuesta en jqgrid setGridParam datatype: local y publico cómo se le promete un código, cómo hacer paginación, clasificación y búsqueda del lado del servidor (o búsqueda avanzada).
En primer lugar, en el ejemplo, en realidad no implementaré la ordenación y la búsqueda, y solo simularé la búsqueda donde tengas problemas ahora. La paginación real, la clasificación y la búsqueda se deben implementar como las SELECT
correspondientes a la base de datos SQL donde existen los datos. La ordenación sigue a ORDER BY
, buscando WHERE
y paginando construcciones como TOP(x)
, TOP(x)
con LEFT OUTER JOIN
o el uso de ROW_NUMBER() OVER(...)
. Pero estos no son el tema de tu pregunta. Así que reduzco todo a la simple simulación de paginación de datos.
Comienzo con el código del Método web ASMX:
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
};
}
donde las clases JqGridData
y TableRow
se definen de la siguiente manera:
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; }
}
Salteamos cualquier verificación de los parámetros de entrada de TestMethod
para que el ejemplo del código sea más legible.
Ahora el código del cliente:
$("#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
// );
En el código uso la misma técnica que en jqgrid setGridParam datatype: local pero el código de la función serializeGridData
es un poco diferente. Debido a que utilizamos el método POST y no GET para obtener los datos del servidor, todos los parámetros de entrada del método web deben configurarse siempre . Por otro lado, jqGrid no siempre establece los parámetros searchField
, searchOper
y searchString
, sino solo si _search=true
. Por ejemplo, en la primera carga de jqGrid, _search=false
y searchField
, searchOper
y searchString
no están definidos en el postData
. Para solucionar el problema inicializamos parámetros indefinidos con null
.
Para implementar la ordenación, es necesario utilizar los sidx
(ordenar índice) y sord
(ordenar dirección: "asc"
o "desc"
).
Para implementar la búsqueda uno necesita usar otros parámetros _search
, searchField
, searchOper
, searchString
.
Durante la búsqueda avanzada en lugar de los searchField
, searchField
, searchOper
, se deben usar los filters
parámetros (ver líneas comentadas). Los datos deben decodificarse con respecto a un deserializador JSON. Entonces debe establecerse multipleSearch : true
en jqgrid. La función serializeGridData
debe ser reemplazada por
serializeGridData: function (postData) {
if (postData.filters === undefined) postData.filters = null;
return JSON.stringify(postData);
}
y el prototipo del método web debe cambiarse a
public JqGridData TestMethod (int page, int rows, string sidx, string sord,
bool _search, string filters)
Para decodificar los filters
parámetros uno puede usar un código tan simple:
if (_search && !String.IsNullOrEmpty (filters)) {
JavaScriptSerializer serializer = new JavaScriptSerializer ();
jqGridSearchFilter searchFilter =
serializer.Deserialize<jqGridSearchFilter> (filters);
// use the searchFilter here
}
donde la clase jqGridSearchFilter
se puede definir de la siguiente manera:
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; }
}
Espero que esta información sea suficiente para implementar cualquier tipo de uso de jqGrid con respecto al Método web ASMX.
Utilicé aquí un envío de datos más simple desde el servidor al cliente con una id
adicional fuera de los datos principales. Si una de las columnas que tiene en la tabla es la id
, puede reducir un poco el envío de datos al servidor. Ver Jqgrid 3.7 no muestra filas en Internet Explorer para más detalles.