Javascript 如何在两个日期之间定义剑道网格列过滤器?

Javascript 如何在两个日期之间定义剑道网格列过滤器?,javascript,html,angularjs,filter,kendo-grid,Javascript,Html,Angularjs,Filter,Kendo Grid,在我们的应用程序中,我们希望date列上的过滤器提示用户输入开始日期和结束日期,过滤器返回相关字段位于这两个日期之间(或在这两个日期上)的行 初始进近 我们最初的方法是限制日期类型使用gte和lte运营商,并在列中添加“extra:true”可过滤选项。这很接近,但出现了以下问题:A)每个日期输入可以使用gte(开始)或lte(结束)运营商,为用户提供了不希望的灵活性和选项,以创建一个永远不会返回结果的过滤器;B)提供了我们不希望的逻辑比较(和/或) 更好的方法 Matthew Erwin的回答

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

初始进近

我们最初的方法是限制日期类型使用gte和lte运营商,并在列中添加“extra:true”可过滤选项。这很接近,但出现了以下问题:A)每个日期输入可以使用gte(开始)或lte(结束)运营商,为用户提供了不希望的灵活性和选项,以创建一个永远不会返回结果的过滤器;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>"
        );
    }
};
$scope.dateFilter={
额外:是的,
运算符:{},
ui:功能(元素){
var parent=element.parent();
while(parent.children().length>1)
$(parent.children()[0]).remove();
parent.prepend(
“开始日期:
”+ "" + "" + "" + “选择”+ “
结束日期:
”+ "" + "" + "" + “选择” ); } };
使用这种方法,将为每个日期生成Odata筛选器选项,但它使用eq Equal To运算符,因此不会返回任何值。我们没有专门针对数据源构建过滤器

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

其他详细信息


我们正在将AngularJS和WebAPI与Odata一起使用。

与Telerik合作后,我得到了一个答案。我打开的线程可以是,但我也将在这个答案中进行总结

最终的解决办法是:

  • 使用“filterable”列选项的“Messages”选项自定义过滤器显示消息
  • 使用列“filterable”选项的“Extra”选项在filter菜单中获取额外日期选择器
  • 在grid filterable选项中配置“Operators”(操作员)选项,以设置哪些操作员可用于日期(gte、lte)以及每个日期显示的文本(开始日期、结束日期)
  • 使用FilterManuInit事件配置筛选器控件
最终结果

可过滤列

使用了以下可过滤选项:

filterable: { "extra": "true", "messages": { "info": "Show items between dates:" }}
Extra为我们提供了第二个日期选择器,“info”消息自定义显示在过滤器菜单顶部的文本

可过滤网格

我在网格级别的“filterable”选项中使用了“operators”选项,使日期过滤器只提供gte和lte运营商,并为这些运营商定制文本。这就是operators配置对象的最终外观:

"date": {
                "gte": "Begin Date",
                "lte": "End Date"
            }
因为我们希望它适用于所有日期,所以我们将它放在工厂中,并在每个角度控制器/视图中重用它

过滤器初始化事件

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

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处,是逻辑比较-仅限,有意义,因此我们不允许用户更改它。)

此函数将此配置应用于任何“日期”字段键入。我这样做是为了可以创建此函数一次,将其放入角度工厂,然后将其重新用于我需要的任何网格。如果不想将其作为覆盖配置应用于所有日期列,可以更改条件以按名称检查字段。示例:

if (e.field == "fieldName")

希望这会对其他人有所帮助。这不会给你在“过滤器”菜单中的用户界面提供最终自定义,但它可以让你在两个日期之间设置一个过滤器。我相信聪明的人可以将此与我的原始策略合并(完全替换“过滤器”菜单的标记)您可以尝试以下方法,该方法提供了两种过滤选项:使用两个过滤字段和网格列

<div>
    From: <input id="from" /> To: <input id="to" />
    <br />
    <br />
    <button id="filter" class="k-button">Filter</button>
</div>
<br />
<br />
<div id="grid"></div>
<script>
    var grid = $("#grid").kendoGrid({
        dataSource: {
            type: "json",
            transport: {
                read: "/Controller/Action"
            },
            pageSize: 10,
            schema: {
                model: {
                    fields: {
                        OrderId: { type: 'number' },
                        OrderItem: { type: 'string' },
                        OrderDate: { type: 'date' }
                    }
                }
            }
        },
        pageable: true,
        filterable: true,
        navigatable: true,
        selectable: true,
        columns:
        [
            { field: "OrderID", width: 100, title: "Order ID", filterable: false },
            { field: "OrderItem", width: 100, title: "Order Item", filterable: false },
            {
                field: "OrderDate", type: "date", width: 125, title: "Order Date",
                template: "#= kendo.toString(kendo.parseDate(EventTime, 'dd.MM.yyyy hh:mm tt'), 'dd.MM.yyyy hh:mm tt') #",
                filterable: {
                    ui: "datetimepicker"
                }
            },
        ]
    }).data("kendoGrid");

    $("#from, #to").kendoDatePicker({
    });

    $("#filter").on("click", function () {
        //var from = $("#from").data("kendoDatePicker").value();
        //var to = $("#to").data("kendoDatePicker").value();

        //If there is a problem regarding to the two lines above, you can also try this:
        var from = $("#from").val();
        var to = $("#to").val();

        var filter = [
            { field: "OrderDate", operator: "gte", value: from },
            { field: "OrderDate", operator: "lte", value: to }
        ];
        grid.dataSource.filter(filter);
    });
</script>

从:到:


滤器

var grid=$(“#grid”).kendoGrid({ 数据源:{ 键入:“json”, 运输:{ 阅读:“/Controller/Action” }, 页面大小:10, 模式:{ 型号:{ 字段:{ OrderId:{type:'number'}, OrderItem:{type:'string'}, OrderDate:{type:'date'} } } } }, pageable:对, 可过滤:正确, 可导航:是的, 是的, 柱: [ {字段:“订单ID”,宽度:100,标题:“订单ID”,可过滤:false}, {字段:“OrderItem”,宽度:100,标题:“OrderItem”,可过滤:false}, {