10

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

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

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

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

要求是创建一个具有

  • 左侧的 jqGrid
  • 右侧的面板

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

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

当用户按下搜索按钮时,关于如何从右侧面板提交数据的任何想法?

更新 1

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

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

如果数据在网格之外,您将仅在右侧窗格中显示所选行的订单详细信息。因此,用户将无法很好地概览数据。

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

客户希望使用两种方法或同时使用两种方法来过滤网格中的数据:

  • 使用multiplesearch网格本身提供的设施(感谢提到的解决方法)
  • 使用提供的自定义搜索面板(右侧带有复选框的那个)

从功能的角度来看,需求很容易表达:当用户单击复选框或使用本机进行搜索时,multiplesearch我应该将值发布到服务器,包括复选框状态。

总结一下,我应该:

  • 当通过本机发布帖子时添加复选框状态multiplesearch
  • multiplesearch当用户单击复选框时添加当前状态(如果有)

有没有办法做到这一点?

4

2 回答 2

20

我非常理解这个要求。在关闭的情况下,我jqGrid 中使用了复选框。将信息包含在 jqGrid 中的最大优势不仅在于易于搜索。如果数据在网格之外,您将仅在右侧窗格中显示所选行的订单详细信息。因此,用户将无法很好地概览数据。

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

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

因为要使用,multiplesearch:true所以不得不提一下jQuery.clone中的一个bug,它跟在所有版本的IE 浏览器中的jqGrid multi-search 中的bug 一样。如果您将多个搜索过滤器定义为一个,则只会使用第一个搜索过滤器,因为所有其他过滤器的操作字段将被读取为undefined。很可惜,但是刚刚发布的 jQuery 1.4.3 也没有修复这个 bug。为了能够使用multiplesearch:true,您可以在 trirand.com 论坛上使用 Jiho Han提出的解决方法建议。

总之,您可以在生成网格的演示示例中看到

替代文字

您可以在其中搜索多个字段

替代文字

对应代码:

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高级搜索中的错误修复在哪里定义

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

OrderStatus如果您确实希望将复选框保留在网格之外,您可以在onSelectRow事件处理程序中对位掩码进行解码。

更新:一开始我真的误解了你的要求。看修改后的例子。现在看起来像 替代文字

它更接近您的需要。

于 2010-10-20T15:23:52.183 回答
0

作为后续行动,我在这里包括另一种我发现获得相同结果的方法。

该方法假设使用postDatajqGrid 的参数。在该方法中,我定义了各种函数来验证复选框的当前状态并将参数发送到可用于过滤的服务器。

这是一个样本

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

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

快乐编码!

于 2010-10-24T00:09:08.993 回答