我们有一个Kendo Jquery Grid,并且我们试图在Column上提供过滤器,以逗号分隔的形式显示值。代码如下所示,我试图在dataBound事件中捕获过滤器对象,并尝试通过数据源过滤出记录,但无济于事。请提出我们如何实现这一目标。
我们需要实现的字段是 ProviderSpecialty
<script>
var grid;
var dataSource;
var gridView = 'updatesRequired';
$(document).ready(function () {
$('#selectGridView').change(function () {
gridView = $('#selectGridView').val();
$('#grid').kendoGrid('destroy').empty();
renderGrid();
});
renderGrid();
});
function renderGrid() {
var fieldsSchema =
{
'ProviderDelegateId': { type: 'number' },
'EndDate': {type: 'date' }
};
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: providerProfileApiBaseUrl)
}
},
error: function (e) {
if (e.xhr.responseText != '') {
var jsonError = JSON.parse(e.xhr.responseText);
if (myApp.Web.utility.displacolumns !== undefined) {
myApp.Web.utility.displacolumns.push({
field: 'EndDate', template: '#= kendo.toString(kendo.parseDate(EndDate), "MM/dd/yyyy")#', title: 'Campaign End Dt', width: '125px', filterable: {
ui: function (element) {
element.kendoDatePicker({
format: "MM/dd/yyyy"
});
}
}
});
}
myApp.Web.utility.displayErrorDialog(jsonError.error);
}
},
pageSize: myApp.Web.config.grid.pageable.pageSize,
schema: {
model: {
id: 'UniqueId',
fields: fieldsSchema
}
},
sort: { field: "ProviderLastName", dir: "asc" }
});
var columns = [];
columns.push({ field: 'ProviderDelegateId', hidden: true });
if (gridView === 'updatesRequired') {
columns.push({ field: 'ProviderLastName', title: 'Last Name', width: '125px', template: '<a href="/ProviderLanding/ProviderUpdate/Index/#=CampaignTrackingId#">#=ProviderLastName#</a>' });
columns.push({ field: 'ProviderFirstName', title: 'First Name', width: '125px', template: '<a href="/ProviderLanding/ProviderUpdate/Index/#=CampaignTrackingId#">#=ProviderFirstName#</a>' });
columns.push({ field: 'ProviderNPI', title: 'NPI', width: '125px', template: '<a href="/ProviderLanding/ProviderUpdate/Index/#=CampaignTrackingId#">#=ProviderNPI != null ? ProviderNPI : \'\' #</a>' });
} else {
columns.push({ field: 'ProviderLastName', title: 'Last Name', width: '125px', template: '<a href="/ProviderUpdate/UpdateProfile?providerId=#=ProviderId#">#=ProviderLastName#</a>' });
columns.push({ field: 'ProviderFirstName', title: 'First Name', width: '125px', template: '<a href="/ProviderUpdate/UpdateProfile?providerId=#=ProviderId#">#=ProviderFirstName#</a>' });
columns.push({ field: 'ProviderNPI', title: 'NPI', width: '125px', template: '<a href="/ProviderUpdate/UpdateProfile?providerId=#=ProviderId#">#=ProviderNPI != null ? ProviderNPI : \'\' #</a>' });
};
columns.push({ field: 'ProviderSpecialty', title: 'Specialty', width: '125px', template: '#= getSpecialties(ProviderSpecialties) #' });
columns.push({ field: 'ProviderEmail', title: 'Email', width: '125px' });
columns.push({ field: 'LocationName', title: 'Location', width: '125px', template: '#= getLocations(ProviderLocations) #' });
if (gridView === 'updatesRequired') {
columns.push({ field: 'CampaignName', title: 'Campaign', width: '125px', template: '<a href="/ProviderLanding/ProviderUpdate/Index/#=CampaignTrackingId#">#=CampaignName#</a>' });
columns.push({
field: 'EndDate', template: '#= kendo.toString(kendo.parseDate(EndDate), "MM/dd/yyyy")#', title: 'Campaign End Dt', width: '125px', filterable : {
ui: function (element) {
element.kendoDatePicker({
format: "MM/dd/yyyy"
});
}
} });
} else {
columns.push({ field: 'IsPendingChangeAvailable', title: 'Pending Changes', width: '125px', template: '#if (IsPendingChangeAvailable) {# Yes #} else {# No #}#' });
};
grid = $("#grid").kendoGrid({
dataSource: dataSource,
columns: columns,
scrollable: false,
filterable: myApp.Web.config.grid.filterable,
sortable: myApp.Web.config.grid.sortable,
pageable: myAppWeb.config.grid.pageable,
}).data('kendoGrid');
};
function getSpecialties(specialties) {
// remove duplicates and then join...
var result = [];
$.each(specialties, function(i, e) {
if ($.inArray(e.SpecialtyName, result) == -1) result.push(e.SpecialtyName);
});
return result.join(',');
};
function getLocations(locations) {
return locations.map(function (location) {
return location.LocationName
}).join(',');
};
$(document).ajaxStart(function () {
$('#overlay-screen').show();
});
$(document).ajaxStop(function () {
$('#overlay-screen').hide();
});
</script>
答案 0 :(得分:0)
过滤器框不允许您添加逗号。我不确定您是否可以使用逗号来完成此操作,除非您覆盖UI以显示自己的过滤器框,并在更改时通过jquery / javascript应用过滤器,如下所示。如果我正确理解您的话。
//After user enters their values. Imagine "Tom,John" would be what the user entered
//After you exploded the comma list yourself
$('#grid').data('kendoGrid').dataSource.filter({
logic: "or",
filters: [
{ field: "Name", operator: "contains", value: 'Tom' },
{ field: "Name", operator: "contains", value: 'John' },
]
});
很明显,如果您还允许过滤其他列,那将更加先进。相反,您将修改过滤器而不是覆盖它们。请注意,我的示例使用了contains。如果您需要的话,这可以是等式。但是,假设要过滤的列是文本,则可以在可过滤对象上使用“ mulit:true”。这允许用户使用kendo的UI元素来管理选择
//On the column property
filterable: {
multi:true
}
这将为您提供该列中每个可能值的复选框。请注意,如果您将网格的可过滤对象的模式设置为行。这是行不通的
//On the grid
filterable: {
mode: "row"
}
从dojo中的以下链接打开代码 https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/configuration/columns.filterable.multi
希望这会有所帮助
答案 1 :(得分:0)
可以通过在三个位置更改网格的默认行为来解决此问题。
1。更改给定列的配置
在列可过滤配置中添加一个附加属性,以指示应应用特殊逻辑。 column.filterable = {multi:true,isCommaSeparatedList:true}
2。在过滤器菜单初始化(filterMenuInit事件)期间更改多重选择的数据源
从网格列集合中获取该列,并检查可过滤对象是否包含用户定义的属性“ isCommaSeparatedList”。
filterMenuInit(event: kendo.ui.GridFilterMenuInitEvent) {
const field = event.field;
//Get the column where the user wants to set the filter
filteredColumn = event.sender.columns.filter((column) => { return column.field === field })[0] as kendo.ui.GridColumn;
if (filteredColumn && typeof filteredColumn.filterable === "object" && filteredColumn.filterable["isCommaSeparatedList"]) {
//Declare an array to hold the unique select items
var selectItems = new Array();
//Declare an dictionary for fast lookup
var valuesDictionary = new Object();
//Get the data from the grid
const gridRecords = event.sender.dataSource.data().toJSON();
//Loop the records an find the individual values in the comma separated list
for (let gridRecord of gridRecords) {
const values = gridRecord[field].toString().split(",") as Array<string>;
values.forEach((value) => {
value = value.trim();
//If the value is not found in the dictionary then the value is added to the dictionary and the selectItems Array
if (!valuesDictionary[value]) {
valuesDictionary[value] = true;
selectItems.push({ [field]: value });
}
});
}
//Sort the selectItems
selectItems.sort((a, b) => {
if (a[field] < b[field]) return -1;
else if (a[field] > b[field]) return 1;
return 0;
});
//Set the datasource for the multi select column to the items found
const filterable = filteredColumn.filterable as any as kendo.ui.GridColumnFilterable;
filterable.dataSource.data(selectItems);
}
3。用户选中或取消选中一个或多个项目(过滤器事件)后更改过滤器
如果将列的可过滤属性设置为{multi:true},则在通过选中或取消选中过滤器菜单中的复选框更改过滤器时,将导致将运算符设置为“ eq”的过滤器。这不是我们想要的水。因为基础数据源包含逗号分隔的列表。因此,我们希望运算符为“包含”。我使用的技巧是在网格“ filter”事件中复制过滤器表达式。我遍历应用于给定列的所有过滤器,并添加相同的过滤器,但使用operator =“ contains”
filter: (event: kendo.ui.GridFilterEvent) => {
//This function is called each time the filter in the grid is changed.
if (event.filter) {
//Try to get the column definition from the columns dictionary for the column where the filter has changed.
const column = event.sender.columns.filter((column) => { return column.field === event.field })[0] as kendo.ui.GridColumn;
//Find out if the filterable property of the column is set to an object and if the object has a property "isList"
if (column && column.filterable && typeof column.filterable === "object" && column.filterable["isCommaSeparatedList"]) {
//Duplicate all the filters with an operator = "eq" to a filter with operator = "contains"
for (let filter of event.filter.filters) {
if (filter.operator === "eq" && !filter["handled"]) {
//Add a handled property to check if the filter has already been duplicated to prevent an endless loop
filter["handled"] = true;
event.filter.filters.push({ value: filter.value, operator: "contains", field: filter.field });
}
}
}
}
}