如何在两个日期之间定义一个Kendo网格列过滤器?

MWi*_*ead 9 html javascript filter angularjs kendo-grid

在我们的应用程序中,我们希望日期列上的过滤器提示用户输入开始日期和结束日期,过滤器返回有关字段位于这两个日期之间(或之上)的行.

初步方法

我们最初的方法是限制日期类型以使用gte和lte运算符,并在列上添加"extra:true"可过滤选项.这很接近,但是出现了以下问题:A)每个日期输入可以使用gte(Start)或lte(End)运算符,提供不期望的灵活性以及用户创建永远不会返回结果的过滤器的选项,以及B)提出我们不想要的逻辑比较(和/或).

更好的方法

这个问题得到了Matthew Erwin的回答,它让我们非常接近:它允许我们完全重新设置过滤器的样式,因此我们可以简单地提供一个开始日期输入和一个结束日期输入.但是,我无法正常工作的是将正确的过滤操作与正确的输入相关联(开始日期为gte,结束日期为lte).我的自定义过滤器如下:

    $scope.dateFilter = {
    extra: true,
    operators: {},
    ui: function (element) {
        var parent = element.parent();
        while (parent.children().length > 1)
            $(parent.children()[0]).remove();

        parent.prepend(
            "Start Date:<br/><span class=\"k-widget k-datepicker k-header\">" +
            "<span class=\"k-picker-wrap k-state-default\">" +
            "<input data-bind=\"value: filters[0].value\" class=\"k-input\" type=\"text\" data-role=\"datepicker\"" +
            " style=\"width: 100%\" role=\"textbox\" aria-haspopup=\"true\" aria-expanded=\"false\" aria-disabled=\"false\" " +
            " aria-readonly=\"false\" aria-label=\"Choose a date\">" +
            "<span unselectable=\"on\" class=\"k-select\" role=\"button\">" +
            "<span unselectable=\"on\" class=\"k-icon k-i-calendar\">select</span></span></span></span>" +

            "<br/>End Date:<br/>" +
            "<span class=\"k-widget k-datepicker k-header\"><span class=\"k-picker-wrap k-state-default\">" +
            "<input data-bind=\"value: filters[1].value\" class=\"k-input\" type=\"text\" data-role=\"datepicker\"" +
            " style=\"width: 100%\" role=\"textbox\" aria-haspopup=\"true\" aria-expanded=\"false\" " +
            " aria-disabled=\"false\" aria-readonly=\"false\" aria-label=\"Choose a date\">" +
            "<span unselectable=\"on\" class=\"k-select\" role=\"button\">" +
            "<span unselectable=\"on\" class=\"k-icon k-i-calendar\">select</span></span></span></span>"
        );
    }
};
Run Code Online (Sandbox Code Playgroud)

使用此方法,将为每个日期生成Odata过滤器选项,但它使用eq Equal To运算符,因此不会返回任何值.我们没有专门针对数据源构建过滤器.

有没有一种简单的方法可以将每个日期输入与特定的过滤器运算符相关联?有没有更好的方法来解决这个问题?看起来通常需要基于开始 - 结束范围的过滤日期.

其他详情

我们正在使用AngularJS和使用Odata的WebAPI.

MWi*_*ead 13

在与Telerik合作之后,我得到了答案.我打开的帖子可以在这里找到,但我也会在这个答案中总结一下.

最终的解决方案是:

  • 使用"filterable"列中的"Messages"选项可自定义过滤器显示消息.
  • 使用"filterable"列选项的"Extra"选项可以在过滤器菜单中获取额外的Date选择器.
  • 在网格可过滤选项中配置"运算符"选项,以设置可用于日期(gte,lte)的运算符以及为每个运算符显示的文本(开始日期,结束日期).
  • 使用filterMenuInit事件配置筛选器控件.

最终结果

在此输入图像描述

列可过滤

使用了以下可过滤选项:

filterable: { "extra": "true", "messages": { "info": "Show items between dates:" }}
Run Code Online (Sandbox Code Playgroud)

Extra为我们提供了第二个日期选择器,"info"消息自定义了过滤器菜单顶部显示的文本.

网格可过滤

我在网格级"可过滤"选项中使用了"运算符"选项,使日期过滤器仅提供gte和lte运算符,并自定义这些运算符的文本.这是运算符配置对象看起来像:

"date": {
                "gte": "Begin Date",
                "lte": "End Date"
            }
Run Code Online (Sandbox Code Playgroud)

因为我们希望这适用于所有日期,所以我们将它放在工厂中并在每个角度控制器/视图中重复使用它.

filterMenuInit事件

通过为filterMenuInit事件提供处理程序,您可以在创建过滤器菜单时访问和配置其中的各个控件.我创建的处理函数如下所示:

function (e) {
            if (e.sender.dataSource.options.schema.model.fields[e.field].type == "date") {
                var beginOperator = e.container.find("[data-role=dropdownlist]:eq(0)").data("kendoDropDownList");
                beginOperator.value("gte");
                beginOperator.trigger("change");
                beginOperator.readonly();

                var logicOperator = e.container.find("[data-role=dropdownlist]:eq(1)").data("kendoDropDownList");
                logicOperator.readonly();

                var endOperator = e.container.find("[data-role=dropdownlist]:eq(2)").data("kendoDropDownList");
                endOperator.value("lte");
                endOperator.trigger("change");
                beginOperator.readonly();
            }
Run Code Online (Sandbox Code Playgroud)

具体来说,对于任何日期字段,此函数将第一个和最后一个下拉运算符设置为"gte"和"lte"(这些是第一个日期运算符和第二个日期运算符的下拉列表),并将所有下拉列表设置为读取 - 因此用户无法更改它们(唯一的其他下拉列表,即索引1,是逻辑比较 - 仅有意义,因此我们不允许用户更改它.)

此函数将此配置应用于"日期"类型的任何字段.我是这样做的,这样我就可以创建一次这个函数,把它放在Angular工厂中,然后将它重用于我需要的任何网格.如果您不想在所有日期列中将其应用为总括性配置,则可以更改条件以按名称检查字段.例:

if (e.field == "fieldName")
Run Code Online (Sandbox Code Playgroud)

希望这会对其他人有所帮助.这并不能让您在过滤器菜单中对UI进行最终自定义,但它确实让您只需在两个日期之间设置过滤器.我确信聪明的人可以将其与我的原始策略(完全替换过滤器菜单的标记)合并,以提出完全自定义的内容.