asp.net - jqGrid: utilizando múltiples métodos para filtrar datos
asp.net-mvc search (2)
Mi requisito es mostrar una página con múltiples filtros para aplicarla a los datos de la grilla.
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 una vista que tenga
- el jqGrid en la parte izquierda
- un panel a la derecha
Dentro del panel derecho el usuario verá una lista de casillas de verificación que representa cada valor de OrderStatus posible y desea buscar utilizando ambos métodos (por ejemplo, seleccionando la casilla de verificación "Órdenes enviadas" y luego filtrando la grilla con una cantidad mayor que un valor)
Ya he configurado el filtrado avanzado ( multiplesearch:true
search 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: la muestra de Oleg es fantástica pero desafortunadamente no se ajusta a los requisitos de mi cliente :(
@Oleg: No entiendo por qué piensas eso:
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á una visión general tan buena de los datos.
tal vez mi descripción no fue tan clara, pero no voy a mostrar ningún detalle del pedido. Para aclarar mejor mi requerimiento, he modificado su muestra para mostrarle la IU final deseada que se muestra en la siguiente imagen:
El cliente desea filtrar los datos en la cuadrícula usando dos métodos o ambos juntos:
- Uso de las instalaciones de búsqueda
multiplesearch
proporcionadas por la red en sí (gracias por la referencia de la solución) - Usando el panel de búsqueda personalizado (el que tiene las casillas de verificación a la derecha) proporcionado
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 realiza una búsqueda utilizando la búsqueda multiplesearch
nativa, debo publicar valores en el servidor, incluyendo también las casillas de verificación.
Para resumir, debería:
- Agregue el estado de las casillas de verificación cuando se realice una publicación a través de la búsqueda
multiplesearch
nativa - Agregue el estado actual de
multiplesearch
(si corresponde) cuando el usuario haga clic en una casilla de verificación
¿Hay alguna forma de hacer esto?
Entiendo este requisito muy bien. En el caso cerrado usé 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á una visión general tan buena de los datos.
Para poder colocar muchas casillas de verificación en la tabla sin desplazamiento horizontal permanente, giré los encabezados de las columnas que tienen "casilla de verificación con la técnica descrita en Texto vertical dentro de encabezados de tabla usando una biblioteca SVG basada en JavaScript . Esta rotación no parece perfecta en IE, pero en otro navegador funciona perfecto.
Puede mantener los datos del campo OrderStatus
en una columna oculta y decodificar la máscara de bits en boolean, que crean casillas de verificación en el cliente o en el servidor.
Porque uso quiero usar la búsqueda multiplesearch:true
debo mencionar un error en jQuery.clone que sigue al error en la búsqueda múltiple jqGrid en todas las versiones 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 otros 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 la búsqueda multiplesearch:true
, puede usar la sugerencia de solución por parte de Jiho Han en el foro de trirand.com .
Todos juntos pueden ver en el ejemplo de demostración que producen la grilla
donde puedes buscar múltiples campos
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 rotateCheckboxColumnHeaders
en la búsqueda avanzada definida de manera
// 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 fuera de la cuadrícula, puede decodificar la máscara de bits OrderStatus
dentro del controlador de eventos onSelectRow .
ACTUALIZADO : Realmente entendí mal tus requerimientos al principio. Mira el ejemplo modificado . Ahora parece
y está más cerca de lo que necesitas.
Solo como seguimiento incluyo aquí otro método que he encontrado para obtener el mismo resultado.
Este método supone usar el 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 usar operadores lógicos mixtos (Y / O) en el lado del servidor, mientras que usar la sección de filtros como en la respuesta de Oleg no es posible.
Feliz codificación!