I am building a website using MVC 4, Web API, and Kendo UI controls.
On my page I am using a Kendo UI Listview to filter my grid. I'm trying to add an "ALL" option as the first item in my listview.
Here is the listview:
var jobsfilter = $("#jobfilter").kendoListView({
selectable: "single",
loadOnDemand: false,
template: "<div class='pointercursor' id=${FilterId}>${FilterName}</div>",
dataSource: filterDataSource,
change: function (e) {
var itm = this.select().index(), dataItem = this.dataSource.view()[itm];
if (dataItem.FilterId !== 0) {
var $filter = new Array();
$filter.push({ field: "JobStatusId", operator: "eq", value: dataItem.FilterId });
jgrid.dataSource.filter($filter);
} else {
jgrid.dataSource.filter({});
}
}
});
Here is my datasource:
var filterDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "api/Filter"
}
},
schema: {
model: { id: "FilterId" }
}
});
I have tried a few different methods to make this happen:
Based on what I've read, I think that I should be able to do it in the dataBound event of the listview and that my implementation is incorrect. Here is the listview with dataBound event added that crashes my browser (Firefox) - or adds about 50 "All" items to the listview (IE).
var jobsfilter = $("#jobfilter").kendoListView({
selectable: "single",
loadOnDemand: false,
template: "<div class='pointercursor' id=${FilterId}>${FilterName}</div>",
dataSource: {
transport: {
read: {
url: "api/Filter"
}
}
},
dataBound: function (e) {
var dsource = $("#jobfilter").data("kendoListView").dataSource;
dsource.insert(0, { FilterId: 0, FilterName: "All" });
e.preventDefault();
},
change: function (e) {
var itm = this.select().index(), dataItem = this.dataSource.view()[itm];
if (dataItem.FilterId !== 0) {
var $filter = new Array();
$filter.push({ field: "JobStatusId", operator: "eq", value: dataItem.FilterId });
jgrid.dataSource.filter($filter);
} else {
jgrid.dataSource.filter({});
}
}
});
Any help would be greatly appreciated.
Why don't you add it server-side?
Anyway, if you want to do it in dataBound
, just check whether it exists and only add if it doesn't:
dataBound: function (e) {
var dsource = this.dataSource;
if (dsource.at(0).FilterName !== "All") {
dsource.insert(0, {
FilterId: 0,
FilterName: "All"
});
}
},
As an explanation to the problem you're seeing: you're creating an infinite loop since inserting an element in the data source will trigger the change event and the list view will refresh and bind again (and thus trigger dataBound
).
You could also encapsulate this in a custom widget:
(function ($, kendo) {
var ui = kendo.ui,
ListView = ui.ListView;
var CustomListView = ListView.extend({
init: function (element, options) {
// base call to widget initialization
ListView.fn.init.call(this, element, options);
this.dataSource.insert(0, {
FilterId: 0,
FilterName: "All"
});
},
options: {
name: "CustomListView"
}
});
ui.plugin(CustomListView);
})(window.jQuery, window.kendo);