jqGrid:使用多种方法来过滤数据

我的要求是显示一个包含多个filter的页面,以应用于网格数据。

假设我们正在谈论订单,订单具有以下属性

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

在jqgrid对象内部,我显示除了OrderStatus之外的所有属性

要求是创build一个视图

  • 左边的jqGrid
  • 在右边的一个小组

在右侧面板中,用户将看到代表每个可能的OrderStatus值的checkbox列表,并且希望使用两种方法进行search(例如,选中复制框“发货订单”,然后使用大于某个值的数值过滤网格)

我已经在jqGrid对象中configuration了高级过滤( multiplesearch:true ),并且能够创build结合了字段和逻辑运算符的复杂filter。

关于如何在用户按下searchbutton时从右侧面板提交数据的任何想法?

更新1

序言:奥列格样品是太棒了,但不幸的是不符合我的客户的要求:(

@ Oleg:我不明白你为什么这么想:

如果数据不在网格中,则仅在所选行的右窗格中显示订单详细信息。 所以用户将不会有那么好的数据概览。

也许我的描述不是很清楚,但我不打算显示任何订单的细节。 为了更好地阐明我的要求,我修改了你的示例,向你展示了如下图所示的最终用户界面: 作为客户需要的UI

客户想要使用两种方法或两者一起过滤网格中的数据:

  • 使用网格自身提供的multiplesearchfunction(感谢提供的解决方法)
  • 提供使用自定义search面板(右侧的checkbox)

从function的angular度来看,这个要求非常容易expression:当用户点击一个checkbox或使用本地multiplesearchsearch进行search时,我应该将值发送到服务器,包括checkbox状态。

总结一下,我应该:

  • 当通过本地multiplesearch进行发布时,添加checkbox状态
  • 当用户点击一个checkbox时,添加当前的multiplesearch状态(如果有的话)

有没有办法做到这一点?

我理解这个要求非常好。 在closures的情况下,我用jqGrid中的checkbox。 在jqGrid里面获取信息的最大好处不仅在于search容易, 如果数据不在网格中,则仅在所选行的右窗格中显示订单详细信息。 所以用户将不会有那么好的数据概览

为了能够在表格中放置许多checkbox而没有永久的水平滚动,我使用基于JavaScript的SVG库在表格标题中使用垂直文本中描述的技术来旋转列的标题,这种旋转在IE中看起来并不完美。在其他浏览器中它是完美的。

您可以将OrderStatus字段中的数据保存在隐藏列中,并将位掩码解码为布尔值,从而在客户端或服务器端构buildcheckbox。

因为使用想要使用multiplesearch:true我不得不提到jQuery.clone中的一个错误,跟随所有版本的IE浏览器中的jqGrid多search中的错误。 如果将多个searchfilter定义为只有第一个searchfilter,则将使用第一个searchfilter,因为所有其他filter的操作字段将被读取为undefined 。 很遗憾,但这个bug在刚刚发布的jQuery 1.4.3中也没有解决。 为了能够使用multiplesearch:true您可以使用Jirand Han在trirand.com论坛上提供的解决方法build议。

所有在一起,你可以看到产生网格的演示例子

替代文字

在那里你可以search多个领域

替代文字

相应的代码:

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

其中rotateCheckboxColumnHeaders和bugfix在高级search定义如此

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

如果你更喜欢把checkbox保持在网格之外,你可以在onSelectRow事件处理程序中进行位掩码OrderStatus的解码。

更新 :我真的有些事情在开始的时候误解了你的要求。 看看修改的例子 。 现在看起来像 替代文字

它更接近你所需要的。

就像跟进一样,我在这里还包括另一种我发现能够得到同样结果的方法。

这个方法假设使用postData参数。 在这个方法里面,我定义了各种函数来validationcheckbox的当前状态,并向服务器发送一个参数,用于过滤。

这是一个样本

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

这个解决scheme相对于Oleg描述的优点是可以在服务器端使用混合逻辑运算符(AND / OR),而在Oleg应答中使用filter部分是不可能的。

快乐的编码!