如何在Kendo Filter组件中实现类似Grid的多值复选框过滤功能?
问题:Kendo Filter组件实现多值过滤的标准方法?
在Kendo Grid中可通过Filter Multi Checkboxes实现单列多值过滤,现需在Kendo Filter组件中复刻该功能,尝试使用kendoMultiSelect作为editorTemplate,但因filter.value不接受数组参数导致功能无法生效,请问是否有标准方法让Kendo Filter基于多值创建过滤规则?
用户尝试的代码如下:
$(document).ready(function () { var dataSource = new kendo.data.DataSource({ pageSize: 20, data: products, autoSync: true, schema: { model: { id: "ProductID", fields: { ProductID: { editable: false, nullable: true }, ProductName: { validation: { required: true } } } } } }); $("#filter").kendoFilter({ dataSource: dataSource, applyButton: true, fields: [ { name: "ProductName", label: "Product Name", editorTemplate: productDropDownEditor }, ], expression: { logic: "and", filters: [ { field: "ProductName", value: "", operator: "eq" } ] } }); $("#grid").kendoGrid({ dataSource: dataSource, pageable: true, height: 550, columns: [ { field: "ProductName", title: "Product Name" }, { field: "UnitsInStock", title: "Units In Stock", width: "130px" } ] }); }); function productDropDownEditor(container, options) { $('<input data-bind="value: value" name="' + options.field + '"/>') .appendTo(container) .kendoMultiSelect({ dataTextField: "ProductName", dataValueField: "ProductName", autoclose: false, dataSource: { type: "odata", transport: { read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Products" } } }); }
解决方案
Kendo Filter本身不直接支持数组作为单个过滤条件的value,但有两种标准方式实现多值过滤:
1. 将多值转换为or逻辑组合的过滤项
监听MultiSelect的选择变化,把选中的多个值拆分为多个eq操作的子过滤条件,用or逻辑包裹后替换原过滤规则:
function productDropDownEditor(container, options) { $('<input data-bind="value: value" name="' + options.field + '"/>') .appendTo(container) .kendoMultiSelect({ dataTextField: "ProductName", dataValueField: "ProductName", autoclose: false, dataSource: { type: "odata", transport: { read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Products" } }, change: function(e) { var filterWidget = $("#filter").data("kendoFilter"); var selectedValues = this.value(); var expression = filterWidget.expression(); // 移除原ProductName相关过滤项 expression.filters = expression.filters.filter(item => item.field !== "ProductName"); if (selectedValues.length > 0) { // 构建or逻辑的过滤组 var multiFilters = selectedValues.map(val => ({ field: "ProductName", operator: "eq", value: val })); expression.filters.push({ logic: "or", filters: multiFilters }); } filterWidget.setExpression(expression); } }); }
2. 自定义in操作符支持数组值
扩展Kendo的过滤操作符,新增支持数组匹配的in操作,让Filter直接接收数组作为value:
// 扩展in操作符的过滤逻辑 kendo.data.Query.prototype.filter.filters["in"] = function(filter, value) { return filter.value.indexOf(value) !== -1; }; $(document).ready(function () { var dataSource = new kendo.data.DataSource({ pageSize: 20, data: products, autoSync: true, schema: { model: { id: "ProductID", fields: { ProductID: { editable: false, nullable: true }, ProductName: { validation: { required: true } } } } } }); $("#filter").kendoFilter({ dataSource: dataSource, applyButton: true, fields: [ { name: "ProductName", label: "Product Name", editorTemplate: productDropDownEditor, operators: { string: [ { name: "Equals", operator: "eq" }, { name: "Is in", operator: "in" } // 添加自定义操作符 ] } }, ], expression: { logic: "and", filters: [ { field: "ProductName", value: [], operator: "in" } ] } }); // Grid配置保持不变 }); function productDropDownEditor(container, options) { $('<input data-bind="value: value" name="' + options.field + '"/>') .appendTo(container) .kendoMultiSelect({ dataTextField: "ProductName", dataValueField: "ProductName", autoclose: false, dataSource: { type: "odata", transport: { read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Products" } } }); }
注意事项
- 第一种方法需注意维护Filter表达式结构,避免重复添加过滤项
- 第二种方法若使用远程数据源,需后端配合支持
in操作的参数解析
内容的提问来源于stack exchange,提问作者The_Black_Smurf
相关产品推荐
相关产品推荐

