2010-10-20 64 views
9

Mi requisito es mostrar una página con múltiples filtros para aplicarla a los datos de la grilla.jqGrid: uso de varios métodos para filtrar datos

Supongamos que estamos hablando de órdenes y una orden tiene los siguientes atributos

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

dentro del objeto jqGrid estoy mostrando todos los atributos , excepto el OrderStatus

El requisito es crear un punto de vista que tiene

  • la jqGrid en la parte izquierda
  • un panel a la derecha

En el interior del panel de la derecha el usuario verá una lista de casillas de verificación que representa cada valor posible OrderStatus y buscar usando ambos métodos (por ejemplo, la selección de la casilla de verificación "Pedidos enviados" y luego filtrando la grilla con una cantidad mayor que un valor)

Ya he configurado el filtrado avanzado (multiplesearch:true) dentro del objeto jqGrid y puedo crear filtros complejos que combinan campos y operadores lógicos.

¿Alguna idea sobre cómo puedo enviar incluso los datos del panel derecho cuando el usuario presiona el botón de búsqueda?

Actualización 1:

Preámbulo: muestra de Oleg es fantástica, pero por desgracia no se ajusta a los requisitos de mi cliente :(

@Oleg: No entiendo por qué piensa que:

Si los datos están fuera de la cuadrícula se mostrarán los detalles de la orden en el panel derecho solo para la fila seleccionada. Así el usuario no tendrá que ir od resumen de los datos.

Quizás mi descripción no fue tan clara, pero no voy a mostrar ningún detalle de su pedido. Para aclarar mejor mi requerimiento he modificado su muestra para mostrarle la interfaz de usuario final deseado, que es como en la siguiente imagen: UI as teh customer want it

El cliente desea filtrar los datos de la cuadrícula utilizando dos métodos o ambos a la vez:

  • Usando los multiplesearch facilidades proporcionadas por la red en sí mismo (gracias por la mención solución)
  • Uso del panel de búsqueda personalizada (el que tiene las casillas de verificación a la derecha), siempre

Desde un punto de vista funcional, el requisito es muy fácil de expresar: cuando el usuario hace clic en una casilla de verificación o hace una búsqueda usando el multiplesearch nativo, debo publicar valores en el servidor incluyendo también el estado de las casillas de verificación.

Para resumir lo que debería:

  • Añadir el estado casillas de verificación cuando un mensaje se hace a través de la nativa multiplesearch
  • Añadir la multiplesearch estado actual (si existe) cuando el usuario haga clic en una casilla de verificación

¿Hay alguna manera de hacerlo?

Respuesta

18

Entiendo este requisito muy bien. En el caso cerrado, utilicé las casillas de verificación dentro de jqGrid. La mayor ventaja de tener la información dentro de jqGrid no es solo la posibilidad de una búsqueda fácil. Si los datos están fuera de la cuadrícula, se mostrarán los detalles de la orden en el panel derecho solo para la fila seleccionada. Por lo tanto, el usuario no tendrá tan buena información de los datos.

Para poder colocar muchas casillas de verificación en la tabla sin desplazamiento horizontal permanente Roté los encabezados de las columnas que tienen "casilla de verificación con la técnica descrita en Vertical text inside table headers using a JavaScript-based SVG library. Esta rotación no parece perfecta en IE, pero en otro navegador funciona perfectamente.

puede mantener los datos del campo OrderStatus en una columna oculta y decodificar la máscara de bits a booleano que construyen casillas de verificación, ya sea en el cliente o en el servidor.

Dado que el uso quieran utilizar multiplesearch:true tengo que mencionar sobre un error en jQuery.clone que sigue al error en la búsqueda múltiple de jqGrid en todos los versos iones de navegadores IE. Si define más como un filtro de búsqueda, solo se usará el primero porque el campo de operación de todos los demás filtros se leerá como undefined. Es una pena, pero el error tampoco está solucionado en el jQuery 1.4.3 recién publicado. Para poder usar multiplesearch:true, puede usar la sugerencia de solución provisional en Jiho Han on trirand.com forum.

Todos juntos se puede ver en the demo example que producen la red

alt text

donde se puede buscar varios campos

alt text

El código correspondiente:

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

donde rotateCheckboxColumnHeaders y la corrección de errores en la búsqueda avanzada define por lo

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

Si prefiere mantener las casillas de verificación externa de la rejilla que puede hacer la decodificación de la máscara de bits OrderStatus interior de onSelectRow controlador de eventos.

ACTUALIZADO: Realmente entendí mal sus requisitos al principio. Mira el modified example. Ahora parece que alt text

y está más cerca de lo que necesita.

+0

wow !!! muestra fantástica Gracias por pasar el tiempo para armar las cosas. De todos modos, esto no se ajusta a mis requisitos y, además, creo que no lo expliqué en el mejor de los casos. Por favor, eche un vistazo a mi publicación para tener más detalles. ¡Gracias! – Lorenzo

+0

@Lorenzo: No estoy seguro de haber visto la parte m ** "UDPATED" ** que he escrito después de haber eliminado su pregunta. ¿Está esto más cerca de resolver su problema? – Oleg

+0

¡Genial! Tuve tiempo de ver tu actualización solo hoy. Esto es exactamente lo que estaba buscando. No puedo dar un +5 pero seguro: ¡gracias! :) – Lorenzo

0

Al igual que un seguimiento, incluyo aquí otro método que he encontrado para obtener el mismo resultado.

Este método supone el uso del parámetro postData de jqGrid. Dentro del método he definido varias funciones que verifican el estado actual de las casillas de verificación y envía un parámetro al servidor donde se puede usar para filtrar.

Esta es una muestra

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

La ventaja de esta solución respecto a la representada por Oleg es que es posible utilizar operadores lógicos mixtos (y/o) en el lado servidor, mientras que el uso de los filtros sección como en el Oleg answer no es posible.

Happy coding!

+2

Para sugerirle lo mismo fue mi primera idea. Sugiero que muchas personas lo hagan (ver http://stackoverflow.com/questions/2928371/how-to-filter-the-jqgrid-data-not-using-the-built-in-search-filter-box/2928819 # 2928819), pero rápidamente encontré algunos problemas. 1) Usted no escribe qué tipo de datos ('json', 'local', ...) usa 2) No se sabe si usa 'loadonce: frue' y entonces la búsqueda del lado del cliente. 3) Lo más importante es que puede haber ** conflictos ** entre el filtro de la búsqueda múltiple (avanzada) y las casillas de verificación del filtro externo. Debería explicar el problema en más detalles: – Oleg

+0

Como uno de sus requisitos es el uso de las instalaciones de "múltiples búsquedas", debe contener la información sobre el estado booleano (como "pendiente") ** dentro de jqGrid **. Puede modificar el cuadro de diálogo de búsqueda múltiple dentro de 'afterShowSearch' (consulte, por ejemplo, la sugerencia de Justin Ethier desde http://stackoverflow.com/questions/3981874/multiple-search-with-multiplefields-default.It encontrar el camino de poco a complejo, pero funcionará. El problema más grande que veo ** es un conflicto ** entre el filtro. Tengamos por ejemplo una columna oculta "pendiente" y use la búsqueda avanzada para establecer "fasle" – Oleg

+0

Luego verificamos el filtro externo y marque "Pendiente" que corresponde a "pendiente: verdadero". ¿Qué valor tiene que usar? Al menos debe reiniciar el filtro de búsqueda múltiple como describí en http://stackoverflow.com/questions/3989786/jqgrid-clear -search-criteria Después de entender todos los problemas, decido elegir el camino desde mi respuesta http://stackoverflow.com/questions/3981874/multiple-search-with-multiplefields-by-default/3981986#3981986. Sincronizo filtros externos con filtros internos y ayuda a evitar conflictos. – Oleg

Cuestiones relacionadas