2010-07-01 27 views
6

Estoy tratando de averiguar 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.jqgrid Página 1 de x pager

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.

Respuesta

17

Si presiona el botón "Siguiente", se enviará una nueva solicitud al servidor. La solicitud contendrá page=2 y, por ejemplo, rows=10 parámetros como parte de la URL (si desea obtener las siguientes 10 filas de la segunda página).

El código del servidor debe leer estos parámetros y devolver las filas de datos correspondientes. Los datos JSON envían desde el servidor debe ser similar después de

{ 
    "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). Por lo tanto, los datos deben contener el valor correcto para page (página = 2). En general, es posible que ahora tenga menos datos que antes y 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 devuelve el número de página valor correcto de 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, como buscar, clasificar y buscar en el lado del servidor (o búsqueda avanzada).

Antes que nada en el ejemplo, realmente no implementaré la ordenación y la búsqueda, y solo simularé la búsqueda donde tenga un problema ahora. La paginación real, la clasificación y la búsqueda se deben implementar como las declaraciones SELECT correspondientes a la base de datos SQL donde existen los datos. La clasificación sigue al ORDER BY, buscando WHERE y paginando a construcciones como TOP(x), TOP(x) con LEFT OUTER JOIN o el uso de construcciones 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 como la siguiente:

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; } 
} 

nos saltamos cualquier verificación de parámetros de entrada del TestMethod a hacer que el ejemplo de código sea más legible.

Ahora el código de 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 que utiliza la misma técnica como en jqgrid setGridParam datatype:local pero el código de serializeGridData función es un poco diferente. Como utilizamos el método POST y no el método 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 clasificación es necesario utilizar los parámetros sidx (ordenar índice) y sord (ordenar dirección: "asc" o "desc").

Para poner en práctica la búsqueda es necesario utilizar otros parámetros _search, searchField, searchOper, searchString.

Durante la búsqueda avanzada en lugar de searchField, searchOper, searchString parámetros filters el parámetro debe ser utilizado (ver líneas de comentarios). Los datos deben decodificarse con respecto a un deserializador JSON. Por lo tanto, debe establecerse en multipleSearch : true en jqgrid. La función serializeGridData debe reemplazar a

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

y el prototipo del método de la tela debe ser cambiado a

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

para decodificar el parámetro filters se puede utilizar como código 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 que implemente cualquier tipo de uso de jqGrid con respecto al Método ASMX Web.

Utilicé aquí un envío de datos más simple del servidor al cliente con id adicional fuera de los datos principales. Si una de las columnas que tiene en la tabla es id, puede reducir un poco el envío de datos al servidor. Vea Jqgrid 3.7 does not show rows in internet explorer para más detalles.

+0

Gracias por la respuesta, sin embargo, me sacó el valor de la página por completo y que todavía no está funcionando . Actualmente mi servicio web está tomando todo el conjunto de registros del DB cada vez que se llama. ¿Cómo puedo capturar el clic de los botones "siguiente" o "anterior" para poder pasar algo a mi servicio web? ¿Alguna idea? – webdad3

+0

¿Hay alguna manera de capturar lo que se devuelve al servicio web cuando hago clic en el botón "Siguiente"? – webdad3

+0

Para capturar el tráfico HTTP utilizo principalmente Fiddler (vea http://www.fiddler2.com/). El uso es muy fácil. El único problema que puede tener si el servidor se ejecuta localmente. En el caso, debe reemplazar en el URL localhost por el pseudo-nombre ipv4.fiddler. – Oleg

0

Ok, estoy respondiendo a esto, ya que tomé lo que Oleg había dicho antes, pero descubrí exactamente lo que quería decir.

Mi llamada a .ajax está envuelta en una función que pasa datos 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).

Como nota al margen, se pasa un valor entero de jQuery a su ASP.servicio web neto de esta manera:

data: "{'page':'" + postdata.page + "'}" 

A continuación se muestra 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"); 
     } 
    } 
}); 

}

+0

En http://stackoverflow.com/questions/3151565/can-you-use-jqgrid-within-asp-net-using-a-webservice-and-javascript/3151997#3151997 Intenté explicar que no utiliza ' $ .ajax' y use 'ajaxGridOptions: {contentType: 'application/json; charset = utf-8 '} 'en su lugar. Si publica el código de su 'testMethod' (puede devolver algunos datos de prueba directamente en una declaración de devolución) lo cambiaré para mostrar cómo puede usar fácilmente jqGrid sin el uso de' addJSONData'. – Oleg

+0

Oleg, si no utiliza .ajax para llamar a su servicio web, ¿cómo lo configuraría utilizando ajaxGridOptions? No pude encontrar ejemplos que claramente configuran esto. – webdad3

+0

testMethod Función Pública() Como myTest Dim miCadena Como Nueva myTest myString.records = 2 myString.total = 2 myString.page = 1 Dim myName como los nuevos nombres Dim myName2 como los nuevos nombres Dim MiListaDeNombres Como nueva lista (De los nombres) myName.name = "Jeff" myName.title = "programador" myName2.name = "Steve" myName2.title = "programador" myNamesList.Add (myName) myNamesList.Add (myName2) myString.rows = myNamesList Devuelve myString End Function – webdad3