使用多 select 下拉菜单进行自定义过滤

Custom filtering with multi-select drop downs

我有一个网格,在工具栏中包含三个多选控件,用于根据所做的选择过滤网格数据源。

目前,我有以下功能,在任何多选控件的 change 事件期间触发。此函数接受 values,其中包含已更改的多选控件中的选定项,以及 filterID,这是过滤期间要使用的 field 名称。

function applyClientFilters(values, filterID) {
var grid = $("#grid").data("kendoGrid");
var gridDataSource = grid.dataSource;
var filter = gridDataSource.filter();
// does the selected drop down contain a value
// if yes, then apply this filter to the necessary drop down
// otherwise remove the filter
if (values.length > 0) {
    // has a filter been setup yet on the datasource?
    if (filter && filter.filters.length > 0) {            
        // firstly check to see if filter has already been applied and if so remove
        for (var i = 0; i < filter.filters.length; ++i) {
            // check to see if filter field already exists i.e. analyte has already been filtered
            // and check to see if the value at this field already exists as a filtered item
            if (filter.filters[i].field === filterID && values.indexOf(filter.filters[i].value) > -1) {
                filter.filters.splice(i, 1);
            }
        }
        // apply new filter(s)
        for (var i = 0; i < values.length; ++i) {
            filter.filters.push({ field: filterID, operator: "eq", value: parseInt(values[i]) });
        }
        gridDataSource.query({
            filter: filter,
            pageSize: 10,
            page: 1,
            group: [{
                field: "InstrumentName",
                dir: "asc"
            }, {
                field: "AnalyteName",
                dir: "asc"
            }, {
                field: "MethodName",
                dir: "asc"
            }]
        });
    }
    else {
        // apply new filter
        gridDataSource.filter({
            logic: "or",
            filters: [
              {
                  field: filterID,
                  operator: "eq",
                  value: parseInt(values),
              }
            ]
        });
    }

} else {
    if (filter && filter.filters.length > 0) {
        // remove existing filter 
        for (var i = 0; i < filter.filters.length; ++i) {
            if (filter.filters[i].field === filterID) {
                filter.filters.splice(i, 1);
            }
        }
        gridDataSource.query({
            filter: filter,
            pageSize: 10,
            page: 1,
            group: [{
                field: "InstrumentName",
                dir: "asc"
            }, {
                field: "AnalyteName",
                dir: "asc"
            }, {
                field: "MethodName",
                dir: "asc"
            }]
        });
    }
}
}

在过滤时仅使用 or 逻辑对单个多选选择很好,即选择多个方法将按预期过滤它们。但是,当跨不同的多选控件使用时,逻辑需要 and

例子

是否可以将过滤逻辑运算符与 Kendo 数据源过滤相结合来实现上述场景?

我想出了一个大大简化过滤的解决方案。我没有 adding/removing/updating 过滤器,而是在任何多选组件的 change 事件期间清除数据源过滤器,根据每个多选中的选定项目确定要应用的过滤器,并构建一个根据选择过滤对象,如下所示:

function applyClientFilters() {
var grid = $("#reportGrid").data("kendoGrid");
var gridDataSource = grid.dataSource;    
// clear existing datasource
gridDataSource.filter([]);
// extract selected items from each of the three multiselect controls
var selectedAnalytes = $("#analyte").data("kendoMultiSelect").value();
var selectedMethods = $("#method").data("kendoMultiSelect").value();
var selectedInstruments = $("#instrument").data("kendoMultiSelect").value();
// setup filter object (using and logic)
var filter = {
    logic: "and",
    filters: [] // ready for filter from each of the three multiselect controls
};
// loop over each of the three extracted selected items variables
// push new filter into array of filters with or logic on each filter
if (selectedAnalytes.length > 0) {
    var analyteFilter = {
        logic: "or",
        filters: [] // ready for filter for each of the selected analytes
    };

    for (var i = 0; i < selectedAnalytes.length; ++i) {
        analyteFilter.filters.push( { field: "AnalyteID", operator: "eq", value: parseInt(selectedAnalytes[i]) } )
    }
    filter.filters.push(analyteFilter);
}
if (selectedMethods.length > 0) {
    var methodFilter = {
        logic: "or",
        filters: [] // ready for filter for each of the selected methods
    };

    for (var i = 0; i < selectedMethods.length; ++i) {
        methodFilter.filters.push({ field: "MethodID", operator: "eq", value: parseInt(selectedMethods[i]) })
    }
    filter.filters.push(methodFilter);
}
if (selectedInstruments.length > 0) {
    var instrumentFilter = {
        logic: "or",
        filters: [] // ready for filter for each of the selected instruments
    };

    for (var i = 0; i < selectedInstruments.length; ++i) {
        instrumentFilter.filters.push({ field: "InstrumentID", operator: "eq", value: parseInt(selectedInstruments[i]) })
    }
    filter.filters.push(instrumentFilter);
}
// apply filter query to datasource
gridDataSource.query({
    filter: filter,
    pageSize: 10,
    page: 1,
    group: [{
        field: "InstrumentName",
        dir: "asc"
    }, {
        field: "AnalyteName",
        dir: "asc"
    }, {
        field: "MethodName",
        dir: "asc"
    }]
});
}