2010-10-20 11 views
9

Meine Anforderung besteht darin, eine Seite mit mehreren Filtern für Rasterdaten anzuzeigen.jqGrid: Verwenden mehrerer Methoden zum Filtern von Daten

Angenommen, wir sprechen über Aufträge und ein Auftrag das Folgende Attribute

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

Im Inneren des jqGrid Objekt ich alle Attribute mit Ausnahme der Orderstatus

Die Forderung zeige, ist eine Ansicht zu erstellen das hat

  • die jqGrid auf dem linken Teil
  • ein Panel auf der rechten

Innerhalb der rechten Seite wird der Benutzer eine Liste von Kontrollkästchen sehen, dass jede mögliche Orderstatus Wert darstellt und er beide Methoden gesucht werden soll (zum Beispiel das Kontrollkästchen „geliefert Aufträge“ auswählen und dann Filtern des Gitters mit Betrag größer als ein Wert)

Ich habe bereits die erweiterte Filterung (multiplesearch:true) im jqGrid-Objekt konfiguriert und bin in der Lage, komplexe Filter zu erstellen, die Felder und logische Operatoren kombinieren.

Irgendwelche Ideen, wie kann ich sogar die Daten aus dem rechten Panel, wenn der Benutzer die Such-Taste drücken?

Update 1:

Präambel: Oleg Probe ist fantastisch, aber leider passt nicht die Anforderungen meines Kunden :(

@Oleg: Ich verstehe nicht, warum Sie denken, dass:

Wenn die Daten außerhalb des Rasters liegen werden Sie die Bestelldetails auf das rechte Fenster nur für ausgewählte Zeile anzeigen So wird der Benutzer nicht so gehen od Übersicht der Daten.

vielleicht war meine Beschreibung nicht so klar, aber ich werde keine Bestelldetails zeigen. Um zu klären, besser meine Anforderung habe ich geändert Ihre Probe Sie die gewünschte endgültige UI zu zeigen, die wie im folgenden Bild ist: UI as teh customer want it

Der Kunde möchte die Daten im Raster mit zwei Methoden oder beide zusammen filtern:

  • mit den multiplesearch Einrichtungen durch das Gitter selbst zur Verfügung gestellt (vielen dank für die Abhilfe Erwähnung)
  • Verwendung der benutzerdefinierten Suchfeld (die mit den Kontrollkästchen auf der rechten Seite) vorgesehen

Aus funktioneller Sicht ist die Anforderung sehr einfach auszudrücken: Wenn der Benutzer auf ein Kontrollkästchen klickt oder eine Suche mit dem nativen multiplesearch durchführt, sollte ich Werte auf dem Server veröffentlichen, einschließlich der Kontrollkästchen.

Zusammengefasst sollte ich:

  • das Kontrollkästchen Zustand hinzufügen, wenn ein Beitrag über die native multiplesearch
  • den aktuellen multiplesearch Zustand hinzufügen gemacht wird (falls vorhanden), wenn der Benutzer klicken auf eine Checkbox

Gibt es eine Möglichkeit, dies zu tun?

Antwort

18

Ich verstehe diese Anforderung sehr gut. Im engeren Fall habe ich die Kontrollkästchen innerhalb jqGrid verwendet. Der größte Vorteil darin, die Informationen innerhalb von jqGrid zu haben, ist nicht nur die Möglichkeit der einfachen Suche. Wenn sich die Daten außerhalb des Rasters befinden, werden die Bestelldetails im rechten Teilfenster nur für die ausgewählte Zeile angezeigt. So wird der Benutzer der Daten nicht so gut haben.

Um viele Checkboxen in der Tabelle ohne permanentes horizontales Scrollen platzieren zu können, habe ich Header der Spalten mit "Checkbox" mit der in Vertical text inside table headers using a JavaScript-based SVG library beschriebenen Technik gedreht. Diese Rotation sieht im IE nicht perfekt aus, aber in anderen Browsern funktioniert es perfekt.

Sie können die Daten aus dem OrderStatus Feld in einer versteckten Spalte halten und die Bitmaske zu boolean dekodieren, die Kontrollkästchen bauen entweder auf dem Client oder auf der Serverseite.

Weil Verwendung multiplesearch:true verwenden will, muss ich erwähnen, über einen Fehler in jQuery.clone, die auf den Fehler in jqGrid Multi-Suche in allen vers IE-Browser. Wenn Sie mehr als einen Suchfilter definieren, wird nur der erste verwendet, da das Operationsfeld aller anderen Filter als undefined gelesen wird. Es ist schade, aber der Fehler ist auch nicht in der gerade veröffentlichten jQuery 1.4.3 behoben. Um multiplesearch:true verwenden zu können, können Sie den Umgehungsvorschlag von Jiho Han on trirand.com forum verwenden.

Alle zusammen können Sie in the demo example sehen, die das Netz erzeugen

alt text

, wo Sie für mehrere Felder

alt text

Der entsprechende Code suchen:

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

wo rotateCheckboxColumnHeaders und der Bugfix in der erweiterten Suche so

// 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); 
      } 
     } 
    } 
}; 
definiert Wenn Sie außerhalb des Gitters der Kontrollkästchen zu halten, bevorzugen Sie die Decodierung der Bit-Maske OrderStatus innerhalb von onSelectRow Ereignishandler tun.

AKTUALISIERT: Ich habe wirklich etwas missverstanden Ihre Anforderungen am Anfang. Schau dir die modified example an. Jetzt sieht es aus wie alt text

und es ist näher, was Sie brauchen.

+0

wow !!! fantastische Probe. Danke, dass du die Zeit verbracht hast, um die Dinge zusammen zu bringen. Jedenfalls passt das nicht zu meiner Anforderung und außerdem denke ich, dass ich es nicht am besten erklärt habe. Bitte werfen Sie einen Blick auf meine Postbearbeitung, um weitere Details zu erhalten. Vielen Dank! – Lorenzo

+0

@Lorenzo: Ich bin mir nicht sicher, dass du den ** ** UDPATED ** -Teil gesehen hast, den ich geschrieben habe, nachdem du deine Frage undatiert hast. Ist das näher an der Lösung Ihres Problems? – Oleg

+0

Großartig! Ich hatte die Zeit, dein Update erst heute zu sehen. Genau das habe ich gesucht. Ich kann keine +5 geben, aber sicher: Danke! :) – Lorenzo

0

Genau wie ein Follow-up ich hier eine andere Methode, die ich gefunden habe, um das gleiche Ergebnis zu erhalten.

Diese Methode soll den Parameter postData von jqGrid verwenden. Innerhalb der Methode habe ich verschiedene Funktionen definiert, die den aktuellen Status der Checkboxen überprüfen und einen Parameter an den Server senden, wo er für die Filterung verwendet werden kann.

Dies ist ein Beispiel

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

Der Vorteil dieser Lösung gegenüber dem von Oleg dargestellt ist, dass es möglich ist, gemischte logische Operatoren (AND/OR) auf der Serverseite, während der Filterbox Abschnitt wie in der Oleg answer ist es nicht möglich.

Glückliche Codierung!

+2

Um Ihnen das gleiche zu empfehlen, war meine erste Idee. Ich schlage vielen Leuten vor, dies zu tun (siehe http://stackoverflow.com/questions/2928371/how-to-filter-the-jqgrid-data-not-using-the-built-in-search-filter-box/2928819 # 2928819), aber ich habe schnell ein paar Probleme gefunden. 1) Sie haben nicht geschrieben, welchen Datentyp ('json', 'local', ...) Sie verwenden 2) Es war unbekannt, ob Sie 'loadonce: frue' verwenden und so die clientseitige Suche. 3) Am wichtigsten ist, dass es ** Konflikte ** zwischen dem Filter von der mehrfachen (erweiterten) Suche und den Checkboxen vom externen Filter sein kann. Ich sollte das Problem in mehr Details erklären: – Oleg

+0

Weil eine Ihrer Anforderung die Verwendung von 'multipleSearch' Einrichtungen ist, müssen Sie die Information über den booleschen Status (wie" ausstehend ") ** innerhalb von jqGrid ** halten. Sie können den Multisearch-Dialog innerhalb von 'afterShowSearch' natürlich ändern (siehe zum Beispiel den Vorschlag von Justin Ethier aus http://stackoverflow.com/questions/3981874/multiple-search-with-multiplefields-by-default. Ich finde den Weg ein wenig zu komplex, aber es wird funktionieren. Das größte Problem sehe ich ** Konflikte ** zwischen dem Filter. Lassen Sie uns zum Beispiel eine versteckte Spalte "ausstehend" und erweiterte Suche verwendet, um "fasle" – Oleg

+0

Dann überprüfen wir die Externer Filter und check "Pending" was "pending: true" entspricht. Welchen Wert muss man verwenden? Zumindest muss man den Multisearch-Filter zurücksetzen, wie ich es in http://stackoverflow.com/questions/3989786/jqgrid-clear beschrieben habe -Suchkriterien.Nach dem Verständnis aller Probleme entscheide ich mich für den Weg aus meiner Antwort http://stackoverflow.com/questions/3981874/multiple-search-with-multiplefields-by-default/3981986#3981986 Ich synchronisiere externe Filter mit internen Filtern und hilft, Konflikte zu vermeiden – Oleg

Verwandte Themen