使用多 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
。
例子
- Select 'Analyte A' -> 过滤网格数据源仅显示 'Analyte A'
- Select 'Method A' -> 过滤网格数据源以显示 'Analyte A' and 'Method A'
- Select 'Method B' -> 过滤网格数据源以显示 'Analyte A' and 'Method A' or 'Method B'
是否可以将过滤逻辑运算符与 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"
}]
});
}
我有一个网格,在工具栏中包含三个多选控件,用于根据所做的选择过滤网格数据源。
目前,我有以下功能,在任何多选控件的 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
。
例子
- Select 'Analyte A' -> 过滤网格数据源仅显示 'Analyte A'
- Select 'Method A' -> 过滤网格数据源以显示 'Analyte A' and 'Method A'
- Select 'Method B' -> 过滤网格数据源以显示 'Analyte A' and 'Method A' or 'Method B'
是否可以将过滤逻辑运算符与 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"
}]
});
}