如何在两个日期之间定义 Kendo 网格列过滤器? [英] How to define a Kendo grid Column filter between two dates?

查看:21
本文介绍了如何在两个日期之间定义 Kendo 网格列过滤器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In our application we want the filter on a date column to prompt the user for a start date and an end date, with the filter returning rows where the field in question falls between (or on) those two dates.

初步方法

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

Our initial approach was to restrict date types to use gte and lte operators, and add the "extra : true" filterable option on the column. This came close, but presented the following problems: A) Each date input could use either the gte (Start) or lte (End) operator, providing undesired flexibility and the option for the user to create a filter that would never return results, and B) Presented a logical comparison (And / Or) that we don't want.

更好的方法

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

This question has an answer by Matthew Erwin that gets us very close: it allows us to completely re-style the filter entirely, so we can present simply a Start Date input and an End date input. However, what I can't get working is associating the right filter operation with the right input (gte for the Start date, lte for the End date). My custom filter is as follows:

    $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>"
        );
    }
};

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

With this approach, the Odata filter option is generated for each of the dates, however it uses the eq Equal To operator, so no values are ever returned. We aren't building filters specifically on the data source.

是否有一种简单的方法可以将每个日期输入与特定的过滤器运算符相关联?有没有更好的方法来处理这个主题?似乎通常需要根据开始 - 结束范围过滤日期.

Is there a simple way I can associate each of those date inputs with a specific filter operator? Is there a better way to approach this subject? It seems like filtering dates based on a Start - End range would be commonly desired.

其他详情

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

We are using AngularJS, and WebAPI with Odata.

推荐答案

与 Telerik 合作后,我找到了答案.我打开的线程可以是 在这里找到,但我也会在这个答案中进行总结.

After working with Telerik, I came to an answer. The thread that I opened can be found here, but I'll also summarize in this answer.

最终的解决方案是:

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

最终结果

列可过滤

使用了以下可过滤选项:

The following filterable options were used:

filterable: { "extra": "true", "messages": { "info": "Show items between dates:" }}

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

Extra gives us the second date selector, and the "info" message customizes the text displayed at the top of the filter menu.

网格可过滤

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

I used the "operators" option in the grid-level "filterable" option to make date filters only provide the gte and lte operators, and to customize the text for those operators. This is what the operators configuration object wound up looking like:

"date": {
                "gte": "Begin Date",
                "lte": "End Date"
            }

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

Because we want this to apply for all dates, we put that in a factory and reuse it in each angular controller / view.

filterMenuInit 事件

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

By providing a handler for the filterMenuInit event, you can access and configure the individual controls in the filter menu as it is created. The handler function that I created looks like this:

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

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

Specifically, for any date field, this function sets the first and last dropdown operators to "gte" and "lte" respectfully (Those are the dropdowns for the first date operator and the second date operator), and sets all of the dropdowns to read-only so the user can't change them (the only other dropdown, which is at index 1, is the logical comparison - only And makes sense, so we don't let users change it.)

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

This function applies this configuration for any fields that are of "date" type. I did it this way so that I could create this function once, put it in an Angular factory, and then reuse it for any grid that I needed. If you don't want to apply this as a blanket configuration across all of your date columns, you can change the conditional to check for fields by name. Example:

if (e.field == "fieldName")

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

Hopefully this will be helpful to someone else. This doesn't give you ultimate customization of the UI in the filter menu, but it does let you simply set up a filter between two dates. I'm sure someone clever could merge this with my original strategy (replacing the markup for the filter menu entirely) to come up with something completely customized.

这篇关于如何在两个日期之间定义 Kendo 网格列过滤器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆