This is a migrated thread and some comments may be shown as answers.

Does TreeList support pagination

6 Answers 1169 Views
TreeList
This is a migrated thread and some comments may be shown as answers.
Vincent
Top achievements
Rank 1
Vincent asked on 11 Feb 2015, 09:16 AM
There is an example named "Example - set dataSource as an existing kendo.data.TreeListDataSource instance" in the document at "http://docs.telerik.com/kendo-ui/api/javascript/ui/treelist".

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

Sort by
0
Alex Gyoshev
Telerik team
answered on 11 Feb 2015, 02:56 PM

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
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Morten
Top achievements
Rank 1
answered on 29 Apr 2015, 01:41 PM

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 
Expansion depth can be controlled via $expand=Children($levels=#) if nessarcy

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.

0
T. Tsonev
Telerik team
answered on 02 May 2015, 07:17 AM
Hi,

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
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Morten
Top achievements
Rank 1
answered on 15 May 2015, 12:13 PM

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!
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!

0
T. Tsonev
Telerik team
answered on 19 May 2015, 07:12 AM

Hello Morten,

Thanks for sharing this solution.

Regards,
T. Tsonev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Nayana
Top achievements
Rank 1
answered on 06 Jan 2016, 10:03 AM

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.

Tags
TreeList
Asked by
Vincent
Top achievements
Rank 1
Answers by
Alex Gyoshev
Telerik team
Morten
Top achievements
Rank 1
T. Tsonev
Telerik team
Nayana
Top achievements
Rank 1
Share this question
or