I tried the example and got nothing. I then traced the code of the kendo.treelist.js file and found no pageable property in it.
I'm wondering whether TreeList support pagination. Thanks.
6 Answers, 1 is accepted
Hello Vincent,
No, the TreeList does not support paging by design. Implementing paging over a hierarchical collection is not optimal as an algorithm (because it involves getting the complete hierarchy from the database), nor is the end-result user-friendly (because navigation via paging does not make sense to users). If you need to show a large amount of data in the TreeList, use remote loading.
Regards,Alex Gyoshev
Telerik
Hi, while I agree that paging on a single root hierarchy makes little sense.
However if the hierarchy consists of multiple roots. Then paging by roots is just as user-friendly as any other grid with paging. Hierarchies with many children per node is a problem, but that's problem for another day :)
Solving this problem using OData makes extracting data quite simple.
Example getting roots with paging:
GET ~/Products?$filter=ParentId eq null&$expand=Children&$top={pagesize}&$skip={skipnumber}&$count=true
The result would be:
{
"@odata.count"
: 33,
"value"
: [
{
"Id"
: 1,
"ParentId"
:
null
,
...,
"Children"
: [
{
"Id"
: 2,
"ParentId"
: 1,
...,
}
]
},
...
]
}
And for filtering the query would look like:
GET ~/Products?$filter={expr}&$expand=Parent&$top={pagesize}&$skip={skipnumber}&$count=true
Where {expr} could be something like: contains(Name, 'some value')
The result would be:
{
"@odata.count"
: 3,
"value"
: [
{
"Id"
: 3,
"ParentId"
: 1,
...,
"Parent"
: {
"Id"
: 1,
"ParentId"
:
null
,
...,
}
},
...
]
}
Note that the structure is flipped (Child -> Parent, duplicate Parent objects is also a problem). But that's workable. A javascript function could fix it.
Thank you for sharing this idea for paging in the TreeList.
It demonstrates that this is possible to to with an OData back-end. It also shows that the process is somewhat involved.
My main concern here is that we can't rely on OData for a specific feature. Customers will have to be able to implement it with their own services. This is where things start to get challenging.
What we can do is to take a working implemetation of this and publish it as how-to guide. This will allow us to highlight any specific requirements and will make it clear that this is not an universal solution.
Regards,
T. Tsonev
Telerik
Here's a working Angular example using OData.
Paging, filtering and sorting works :-)
View:
<
kendo-treelist
k-options
=
"treeListOptions"
></
kendo-treelist
>
<
kendo-pager
k-options
=
"pagerOptions"
></
kendo-pager
>
Controller logic:
// default filtering and sorting
var
defaultFilter = { field:
"ParentId"
, operator:
"eq"
, value:
null
};
var
defaultSort = { field:
"Name"
, dir:
"asc"
};
var
myODataSource =
new
kendo.data.DataSource({
type:
"odata-v4"
,
transport: {
read: {
url:
"/odata/Products"
,
data: {
"$expand"
:
"Children($levels=max)"
}
}
},
pageSize: 15,
serverPaging:
true
,
serverSorting:
true
,
serverFiltering:
true
,
filter: defaultFilter,
sort: defaultSort,
schema: {
parse:
function
(response) {
if
(myODataSource.transport.options.read.data.$expand ==
"Parent($levels=max)"
) {
// if "$expand=Parent($levels=max)" then the hierarchy will be reversed Children -> Parent
// thus we need to flatten Parents
var
ary = _.flattenHierarchy(response.value,
'Parent'
);
// and remove duplicate parents coming from different tree branches
response.value = _.uniq(ary);
}
else
{
// if "$expand=Children($levels=max)" then the hierarchy will be as expected Parent -> Children
// thus we need to flatten Children
response.value = _.flattenHierarchy(response.value,
'Children'
);
}
return
response;
}
},
change:
function
(e) {
treeListDataSource.read();
}
});
// filter hack!
// http://www.telerik.com/forums/any-filtering-event#--cNXsvF5U6zinsTsyL4eg
var
originalFilterFn = kendo.data.TreeListDataSource.fn.filter;
kendo.data.TreeListDataSource.fn.filter =
function
(e) {
if
(arguments.length > 0) {
if
(e ===
null
) {
// if e is null, then the filter is cleared. So we need to filter by roots to get the normal tree
myODataSource.transport.options.read.data.$expand =
"Children($levels=max)"
;
myODataSource.filter(defaultFilter);
}
else
{
// else we're filtering and the result nodes need to include parents to maintain the tree hierarchy
myODataSource.transport.options.read.data.$expand =
"Parent($levels=max)"
;
myODataSource.filter(e);
}
}
return
originalFilterFn.apply(
this
, arguments);
};
// sort hack!
var
originalSortFn = kendo.data.TreeListDataSource.fn.sort;
kendo.data.TreeListDataSource.fn.sort =
function
(e) {
if
(arguments.length > 0) {
myODataSource.sort(e);
}
return
originalSortFn.apply(
this
, arguments);
};
var
treeListDataSource =
new
kendo.data.TreeListDataSource({
transport: {
read:
function
(options) {
var
data = myODataSource.data().toJSON();
options.success(data);
}
},
sort: defaultSort,
schema: {
model: {
id:
"Id"
,
fields: {
parentId: { field:
"ParentId"
, type:
"number"
, nullable:
true
},
Id: { field:
"Id"
, type:
"number"
}
},
expanded:
true
}
}
});
$scope.treeListOptions = {
autoBind:
false
,
dataSource: treeListDataSource,
filterable:
true
,
//{ mode: "row"}, not supported (yet) by treelist
sortable:
true
,
resizable:
true
,
reorderable:
true
,
columns: [
{ field:
"Name"
},
{ field:
"Description"
}
]
};
$scope.pagerOptions = {
autoBind:
false
,
dataSource: myODataSource,
info:
true
,
pageSizes: [2, 3, 4, 5, 6],
refresh:
true
,
};
myODataSource.read();
Underscore function
_.mixin({
flattenHierarchy:
function
self(objAry, childPropertyName) {
// default values
childPropertyName =
typeof
childPropertyName !==
'undefined'
? childPropertyName :
'children'
;
var
result = [];
_.each(objAry,
function
(obj) {
// the object it self without children
var
strippedObj = _.omit(obj, childPropertyName);
result.push(strippedObj);
if
(obj.hasOwnProperty(childPropertyName) && obj[childPropertyName] !==
null
) {
// child object(s)
var
children = obj[childPropertyName];
if
(!_.isArray(children))
children = [children];
result.pushArray(self(children, childPropertyName));
}
});
return
result;
}
});
Enjoy!
Hello Morten,
Thanks for sharing this solution.
Regards,T. Tsonev
Telerik
Hello,
Is there a way we can sort the column on all pages? I have implemented treeList as mentioned above. I need to sort on column for all pages? How can this be done?
Thanks in advance.