2010-10-20 5 views
9

Il mio requisito è mostrare una pagina con più filtri da applicare ai dati della griglia.jqGrid: utilizzo di più metodi per filtrare i dati

Supponiamo che stiamo parlando di ordini e di un ordine ha i seguenti attributi

public class Order { 
    public int OrderID 
    public DateTime OrderDate 
    public DateTime ShipmentDate 
    public int OrderTotal 
    public int OrderStatus 
} 

All'interno dell'oggetto jqGrid sto mostrando tutti gli attributi tranne l'OrderStatus

L'esigenza è quella di creare una vista che ha

  • il jqGrid sulla parte sinistra
  • un pannello sulla destra

All'interno del pannello di destra l'utente vedrà una lista di caselle di controllo che rappresenta ogni possibile valore OrderStatus e lui vuole effettuare la ricerca utilizzando entrambi i metodi (ad esempio selezionando la casella di controllo "gli ordini spediti" e poi filtrando la griglia con Importo maggiore di un valore)

Ho già configurato il filtro avanzato (multiplesearch:true) all'interno dell'oggetto jqGrid e sono in grado di creare filtri complessi che combinano campi e operatori logici.

Qualche idea su come posso inviare anche i dati dal pannello di destra quando l'utente preme il pulsante di ricerca?

Update 1:

Preambolo: campione Oleg è fantastica, ma purtroppo non si adatta esigenze del mio cliente :(

@Oleg: non capisco il motivo per cui si pensa che:

Se i dati sono al di fuori della griglia verranno visualizzati i dettagli dell'ordine su il riquadro destro solo per la riga selezionata. Quindi l'utente non sarà così via od panoramica dei dati.

forse la mia descrizione non era chiara ma non ho intenzione di mostrare alcun dettaglio dell'ordine. Per chiarire meglio la mia richiesta ho modificato il campione visualizzare la desiderata interfaccia utente finale, che è come la seguente immagine: UI as teh customer want it

Il cliente desidera filtrare i dati nella griglia utilizzando due metodi o entrambi insieme:

  • Utilizzando le multiplesearch servizi forniti dalla rete stessa (grazie per la menzione soluzione)
  • Uso del pannello personalizzato di ricerca (quello con le caselle di controllo a destra), a condizione

Dal punto di vista funzionale il requisito è molto semplice da esprimere: quando l'utente fa clic su una casella di controllo o effettua una ricerca utilizzando il numero nativo multiplesearch, dovrei pubblicare i valori sul server includendo anche lo stato delle caselle di controllo.

Per riassumere dovrei:

  • Aggiungere lo stato caselle di controllo quando un post viene effettuata attraverso il nativo multiplesearch
  • Aggiungere la corrente multiplesearch stato (se presente) quando l'utente fa clic su una casella di controllo

C'è un modo per farlo?

risposta

18

Capisco molto bene questo requisito. Nel caso in questione ho utilizzato le caselle di controllo all'interno di jqGrid. Il vantaggio maggiore di avere le informazioni all'interno di jqGrid non è solo la possibilità di una facile ricerca. Se i dati sono al di fuori della griglia, verranno visualizzati i dettagli dell'ordine nel riquadro destro solo per la riga selezionata. Pertanto, l'utente non avrà una panoramica così buona dei dati.

Per poter posizionare molti checkbox nella tabella senza scorrimento orizzontale permanente ho ruotato le intestazioni delle colonne avendo "checkbox con la tecnica descritta in Vertical text inside table headers using a JavaScript-based SVG library. Questa rotazione non sembra perfetta in IE, ma in altri browser funziona perfettamente.

È possibile tenere i dati dal campo OrderStatus in una colonna nascosta e decodificare il maschera di bit per booleano che costruiscono caselle di controllo sia sul client o sul lato server.

Poiché l'uso vuole utilizzare multiplesearch:true devo menzionare su un bug in jQuery.clone che segue l'errore in jqGrid multi-search in tutti vers ioni di browser IE. Se si definisce più come filtri di ricerca, verrà utilizzato solo il primo perché il campo operativo di tutti gli altri filtri verrà letto come undefined. È un peccato, ma il bug non è stato corretto anche in jQuery 1.4.3 appena pubblicato. Per poter utilizzare multiplesearch:true è possibile utilizzare il suggerimento di soluzione alternativa tramite Jiho Han on trirand.com forum.

Tutti insieme si può vedere in the demo example che producono la griglia

alt text

dove è possibile cercare per più campi

alt text

Il codice corrispondente:

var myData = [ 
    { orderID: "10", orderDate: "2010-09-18", shipmentDate: "2010-09-20", orderStatus: "2" }, 
    { orderID: "15", orderDate: "2010-09-20", shipmentDate: "2010-09-24", orderStatus: "3" }, 
    { orderID: "20", orderDate: "2010-10-16", shipmentDate: "2010-10-17", orderStatus: "1" } 
]; 
// decode 'orderStatus' column and add additional boolean data based on the bitmap mask 
for (var i=0, l=myData.length; i<l; i++) { 
    var myRow = myData[i]; 
    var orderStatus = parseInt(myRow.orderStatus, 10); 
    myRow.airPost = (orderStatus & 2) != 0? "1": "0"; 
    myRow.heavy = (orderStatus & 1) != 0? "1": "0"; 
} 
var grid = jQuery('#list'); 
grid.jqGrid({ 
    data: myData, 
    datatype: 'local', 
    caption: 'Order Details', 
    height: 'auto', 
    gridview: true, 
    rownumbers: true, 
    viewrecords: true, 
    pager: '#pager', 
    rownumbers: true, 
    colNames: ['Order ID', 'Order', 'Shipment', 'Air-Post', 'Heavy', 'RowVersion'], 
    colModel: [ 
     { name: 'orderID', index: 'orderID', key:true, width: 120, sorttype: 'int' }, 
     { name: 'orderDate', index: 'orderDate', width: 180, 
      sorttype: 'date', formatter: 'date' }, 
     { name: 'shipmentDate', index: 'shipmentDate', width: 180, 
      sorttype: 'date', formatter: 'date' }, 
     { name: 'airPost', width: 21, index: 'airPost', formatter: 'checkbox', align: 'center', 
      editoptions: { value: "1:0" }, stype: 'select', searchoptions: { value: "1:Yes;0:No" } }, 
     { name: 'heavy', width: 21, index: 'heavy', formatter: 'checkbox', align: 'center', 
      editoptions: { value: "1:0" }, stype: "select", searchoptions: { value: "1:Yes;0:No" } }, 
     { name: 'orderStatus', index: 'orderStatus', width: 50, hidden: true } 
    ] 
}).jqGrid ('navGrid', '#pager', { edit: false, add: false, del: false, refresh: true, view: false }, 
      {},{},{},{multipleSearch:true}) 
    .jqGrid ('navButtonAdd', '#pager', { caption: "", buttonicon: "ui-icon-calculator", title: "choose columns", 
     onClickButton: function() { 
      grid.jqGrid('columnChooser'); 
     } 
    }); 

dove rotateCheckboxColumnHeaders e bugfix nella ricerca avanzata definita in modo

// we use workaround from http://www.trirand.com/blog/?page_id=393/bugs/in-multiple-search-second-and-subsequent-ops-are-sent-as-undefined-in-ie6/ 
// to fix the bug in the jQuery.clone (see http://bugs.jquery.com/ticket/6793 and 
// dscussion on the http://api.jquery.com/clone/ 
jQuery.event.special.click = { 
    setup: function() { 
     if (jQuery(this).hasClass("ui-search")) { 
      jQuery(this).bind("click", jQuery.event.special.click.handler); 
     } 
     return false; 
    }, 
    teardown: function() { 
     jQuery(this).unbind("click", jQuery.event.special.click.handler); 
     return false; 
    }, 
    handler: function(event) { 
     jQuery(".ui-searchFilter td.ops select").attr("name", "op"); 
    } 
}; 
var rotateCheckboxColumnHeaders = function (grid, headerHeight) { 
    // we use grid as context (if one have more as one table on tnhe page) 
    var trHead = jQuery("thead:first tr", grid.hdiv); 
    var cm = grid.getGridParam("colModel"); 
    jQuery("thead:first tr th").height(headerHeight); 
    headerHeight = jQuery("thead:first tr th").height(); 

    for (var iCol = 0; iCol < cm.length; iCol++) { 
     var cmi = cm[iCol]; 
     if (cmi.formatter === 'checkbox') { 
      // we must set width of column header div BEFOR adding class "rotate" to 
      // prevent text cutting based on the current column width 
      var headDiv = jQuery("th:eq(" + iCol + ") div", trHead); 
      headDiv.width(headerHeight).addClass("rotate"); 
      if (!jQuery.browser.msie) { 
       if (jQuery.browser.mozilla) { 
        headDiv.css("left", (cmi.width - headerHeight)/2 + 3).css("bottom", 7); 
       } 
       else { 
        headDiv.css("left", (cmi.width - headerHeight)/2); 
       } 
      } 
      else { 
       var ieVer = jQuery.browser.version.substr(0, 3); 
       // Internet Explorer 
       if (ieVer !== "6.0" && ieVer !== "7.0") { 
        jQuery("span", headDiv).css("left", 0); 
        headDiv.css("left", cmi.width/2 - 4).css("bottom", headerHeight/2); 
       } 
       else { 
        headDiv.css("left", 3); 
       } 
       headDiv.parent().css("zoom",1); 
      } 
     } 
    } 
}; 

Se preferite tenere le caselle di controllo al di fuori della griglia che si può fare la decodifica del bit-maschera OrderStatus all'interno di onSelectRow gestore di eventi.

AGGIORNATO: Ho davvero frainteso le tue esigenze all'inizio. Guarda lo modified example. Ora sembra alt text

ed è più vicino a quello che ti serve.

+0

wow !!! fantastico esempio. Grazie per aver dedicato del tempo a mettere insieme le cose. Ad ogni modo questo non si adatta alle mie esigenze e inoltre penso di non averlo spiegato al meglio. Si prega di dare un'occhiata al mio post modificare per avere ulteriori dettagli. Grazie! – Lorenzo

+0

@Lorenzo: Non sono sicuro di aver visto la mia parte ** "UDPATED" ** che ho scritto dopo aver annullato la tua domanda. È più vicino a risolvere il tuo problema? – Oleg

+0

Ottimo! Ho avuto il tempo di vedere il tuo aggiornamento solo oggi. Questo e 'esattamente quello che stavo cercando. Non posso dare un +5 ma di sicuro: grazie! :) – Lorenzo

0

Proprio come follow-up sto includendo qui un altro metodo che ho trovato per ottenere lo stesso risultato.

Questo metodo suppone di utilizzare il parametro postData di jqGrid. All'interno del metodo ho definito varie funzioni che verificano lo stato attuale delle caselle di controllo e invia un parametro al server in cui può essere utilizzato per il filtraggio.

Questo è un esempio

postData: { 
    pending: function() { 
     if ($("#cb_pending").is(':checked')) { 
      return true; 
     } else { 
      return false; 
     } 
    } 
} 

Il vantaggio di questa soluzione rispetto a quello descritto da Oleg è che è possibile utilizzare operatori logici misti (E/O) sul lato server che usando i filtri sezione come nel Oleg answer non è possibile.

Felice codifica!

+2

Suggerire lo stesso è stata la mia prima idea. Suggerisco a molte persone di farlo (vedi http://stackoverflow.com/questions/2928371/how-to-filter-the-jqgrid-data-not-using-the-built-in-search-filter-box/2928819 # 2928819), ma ho trovato rapidamente alcuni problemi. 1) Non hai scritto quale tipo di dati ('json', 'local', ...) usi 2) Non è noto se tu usi 'loadonce: frue' e quindi la ricerca lato client. 3) Il più importante è che può essere ** conflitti ** tra il filtro dalla ricerca multipla (avanzata) e le caselle di controllo dal filtro esterno. Dovrei spiegare il problema in ulteriori dettagli: – Oleg

+0

Poiché uno dei tuoi requisiti è l'utilizzo delle strutture 'multiplesearch' devi tenere le informazioni sullo stato booleano (come" in sospeso ") ** all'interno di jqGrid **. È possibile modificare la finestra di dialogo multisearch all'interno di 'afterShowSearch' (vedi ad esempio il suggerimento di Justin Ethier da http://stackoverflow.com/questions/3981874/multiple-search-with-multiplefields-by-default. Trovo il modo un po 'complesso, ma funzionerà.Il problema più grande che vedo ** conflitti ** tra il filtro.Avremmo per esempio una colonna nascosta "in sospeso" e utilizzato la ricerca avanzata per impostare "fasle" – Oleg

+0

Quindi controlliamo il filtro esterno e selezionare "In sospeso" che corrisponde a "in sospeso: true". Quale valore deve utilizzare? Almeno devi reimpostare il filtro multisearch come descritto in http://stackoverflow.com/questions/3989786/jqgrid-clear criteri di ricerca Dopo aver compreso tutti i problemi, decido di scegliere la strada dalla mia risposta http://stackoverflow.com/questions/3981874/multiple-search-with-multiplefields-by-default/3981986#3981986. filtri esterni con filtri interni e aiuta ad evitare conflitti – Oleg