2010-07-01 15 views
6

Sto cercando di capire come utilizzare la funzionalità di paging di jqGrid. Attualmente sono bloccato a pagina 1 di 4. Non importa se premo il pulsante Avanti o no. Continua a 1.jqgrid Pagina 1 di x pager

Sto usando ASP.Net con un servizio web per popolare i miei dati JSON. Come catturare l'evento dal client per popolare la proprietà sul webservice per riportare il valore corretto?

Qualsiasi aiuto è apprezzato.

risposta

17

Se si preme il pulsante "Avanti", una nuova richiesta verrà inviata al server. La richiesta conterrà page=2 e, ad esempio, i parametri rows=10 come parte dell'URL (se si desidera ottenere le 10 righe successive della seconda pagina).

Il codice del server dovrebbe leggere questi parametri e inviare indietro le righe di dati corrispondenti. I dati JSON inviano dal server dovrebbe essere simile seguenti

{ 
    "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"]}, 
    ] 
} 

(vedi http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data). Quindi i dati devono contenere il valore corretto per page (pagina = 2). In generale è possibile, ora hai meno dati come prima e restituisci il numero di pagina 1 sulla richiesta per ottenere il numero di pagina 2.

Quindi suggerisco che al momento il tuo codice server non restituisca il valore corretto di page nell'output.

AGGIORNATO: OK Jeff. Continuo la mia risposta in jqgrid setGridParam datatype:local e pubblichiamo come viene promesso un codice su come eseguire il paging lato server, l'ordinamento e la ricerca (o la ricerca avanzata).

Prima di tutto nell'esempio non implementerò realmente l'ordinamento e la ricerca e simulerò solo il cercapersone in cui si hanno problemi ora. Le vere paging, ordinamento e ricerca dovrebbero essere implementate come le corrispondenti istruzioni SELECT nel database SQL in cui i dati esistono. L'ordinamento segue allo ORDER BY, alla ricerca su WHERE e al paging su costruzioni come TOP(x), TOP(x) con LEFT OUTER JOIN o sull'utilizzo dei costrutti ROW_NUMBER() OVER(...). Ma questi non sono l'argomento della tua domanda. Quindi riduco tutto alla semplice simulazione di paging dei dati.

inizio con il codice del metodo 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 
    }; 
} 

dove classi JqGridData e TableRow sono definiti come segue:

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

Abbiamo saltare alcuna verifica dei parametri di ingresso del TestMethod a rendere l'esempio di codice più leggibile.

Ora il codice del client:

$("#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 
//    ); 

Nel codice Io uso la stessa tecnica come nella jqgrid setGridParam datatype:local ma il codice di serializeGridData funzione è un po 'diverso. Poiché utilizziamo il metodo POST e non GET per ottenere i dati dal server , tutti i parametri di input del metodo web devono essere sempre impostati su.Dall'altro lato jqGrid non imposta sempre i parametri searchField, searchOper e searchString, ma solo se _search=true. Ad esempio, al primo caricamento di jqGrid, _search=false e e searchString non sono definiti nello postData. Per risolvere il problema inizializziamo i parametri non definiti con null.

Per implementare l'ordinamento è necessario utilizzare i parametri sidx (indice di ordinamento) e sord (ordinamento: "asc" o "desc").

per implementare la ricerca si ha la necessità di utilizzare altri parametri _search, searchField, searchOper, searchString.

Durante la ricerca avanzata, invece di searchField, searchOper, searchString parametri il parametro filters deve essere utilizzato (vedi righe commentate). I dati devono essere decodificati rispetto a un deserializzatore JSON. Quindi deve essere impostato multipleSearch : true in jqgrid. La funzione serializeGridData dovrebbe essere sostituito da

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

e il prototipo del metodo web dovrebbe essere modificata per

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

per decodificare il parametro filters si può utilizzare tale codice semplice:

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

dove la classe jqGridSearchFilter può essere definita come segue:

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

Spero che questa informazione sia sufficiente per implementare qualsiasi tipo di utilizzo di jqGrid con il metodo Web ASMX.

Ho utilizzato qui un semplice invio di dati dal server al client con id aggiuntivo al di fuori dei dati principali. Se una delle colonne che hai nella tabella è id, puoi ridurre un po 'i dati inviati al server. Vedi Jqgrid 3.7 does not show rows in internet explorer per maggiori dettagli.

+0

Grazie per la risposta, però, ho tirato fuori il valore della pagina del tutto e ancora non funziona . Attualmente il mio webservice sta acquisendo l'intero recordset dal DB ogni volta che viene chiamato. Come posso catturare il clic dei pulsanti "successivo" o "precedente" così posso passare qualcosa al mio webservice? Qualche idea? – webdad3

+0

C'è un modo per catturare ciò che viene passato al servizio web quando faccio clic sul pulsante "successivo"? – webdad3

+0

Per catturare il traffico HTTP uso principalmente Fiddler (vedi http://www.fiddler2.com/). L'utilizzo è molto semplice. L'unico problema che si può avere se il server viene eseguito localmente. Nel caso dovresti sostituire l'URL localhost con lo pseudo-nome ipv4.fiddler. – Oleg

0

Ok, rispondo a questo mentre ho preso ciò che Oleg aveva detto sopra, ma ho capito esattamente che cosa intendesse.

La mia chiamata .ajax è racchiusa in una funzione che passa i dati postdatati come parametro. Non sono riuscito a trovare alcuna documentazione su quel parametro, ma ho pensato che forse era lì che il valore della pagina era contenuto. Come puoi vedere ho fatto un avviso con postdata.page e basso ed ecco che ho ottenuto un valore (basato sul clic del pulsante successivo).

Così ho creato un parametro nel mio webservice chiamato page (intero).

Proprio come una nota a margine, si passa un valore intero da jQuery al proprio ASP.webservice netto in questo modo:

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

seguito è la funzione 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

In http://stackoverflow.com/questions/3151565/can-you-use-jqgrid-within-asp-net-using-a-webservice-and-javascript/3151997#3151997 ho provato a spiegare che non si usa ' $ .ajax' e utilizzare 'ajaxGridOptions: {contentType: 'application/json; charset = utf-8 '} 'invece. Se inserisci il codice del tuo 'testMethod' (può restituire alcuni dati di test direttamente in una dichiarazione di ritorno) lo cambierò per mostrare come puoi usare facilmente jqGrid senza l'uso di' addJSONData'. – Oleg

+0

Oleg, se non usi .ajax per chiamare il tuo webservice come lo configureresti usando ajaxGridOptions? Non sono riuscito a trovare esempi che lo mettessero in chiaro. – webdad3

+0

Funzione Pubblica testMethod() Come myTest Dim myString come nuovo myTest myString.records = 2 myString.total = 2 myString.page = 1 Dim myName come nuovi nomi Dim myName2 come nuovi nomi Dim MyNamesList come nuovo elenco (di nomi) myName.name = "Jeff" myName.title = "programmatore" myName2.name = "Steve" myName2.title = "programmatore" myNamesList.Add (myName) myNamesList.Add (myName2) myString.rows = myNamesList Restituisci myString End Function – webdad3