Sorting

The KendoReact TreeList enables you to sort single and multiple data-bound columns.

Getting Started

To enable sorting:

  1. Set the sortable option of the TreeList.
  2. Set the field option of the TreeList column.
  3. Utilize the sort option to apply the sorting styles and buttons to the affected columns.
  4. When sortable is configured and the user tries to sort a column, the onSortChange event is emitted. Handle the onSortChange event where you have the option to sort the data programmatically, to make a request to the server for server sorting, or to use the orderBy function which automatically processes the data.

The following example demonstrates the minimum required configuration for sorting the TreeList records.

import React from 'react';
import ReactDOM from 'react-dom';
import { TreeList, orderBy, mapTree, extendDataItem } from '@progress/kendo-react-treelist';
import employees from './data';

const subItemsField = 'employees';
const expandField = 'expanded';
const columns = [
    { field: 'name', title: 'Name', width: 310, expandable: true },
    { field: 'position', title: 'Position', width: 260 },
    { field: 'hireDate', title: 'Hire Date', width: 160, format: '{0:d}' },
    { field: 'timeInPosition', title: 'Year(s) in Position', width: 160 },
    { field: 'fullTime', title: 'Full Time', width: 150 }
];

class App extends React.Component {
    state = {
        data: [ ...employees ],
        sort: [
            { field: 'name', dir: 'asc' }
        ],
        expanded: [1, 2, 32]
    }

    onExpandChange = (e) => {
        this.setState({
            expanded: e.value ?
                this.state.expanded.filter(id => id !== e.dataItem.id) :
                [ ...this.state.expanded, e.dataItem.id ]
        });
    }

    handleSortChange = (event) => {
        this.setState({
            sort: event.sort
        })
    }

    addExpandField = (dataTree) => {
        const expanded = this.state.expanded;
        return mapTree(dataTree, subItemsField, (item) =>
            extendDataItem(item, subItemsField, {
                [expandField]: expanded.includes(item.id)
            })
        );
    }

    processData = () => {
       const { data, sort } = this.state;
        return this.addExpandField(orderBy(data, sort, subItemsField));
    }

    render() {
        return (
            <TreeList
                style={{ maxHeight: '510px', overflow: 'auto' }}
                expandField={expandField}
                subItemsField={subItemsField}
                onExpandChange={this.onExpandChange}
                sortable={true}
                sort={this.state.sort}
                data={this.processData()}
                onSortChange={this.handleSortChange}
                columns={columns}
            />
        );
    }
}

ReactDOM.render(
    <App />,
    document.querySelector('my-app')
);

Customizing the Sorting

The sorting feature of the TreeList enables you to unsort the columns and sort the records by multiple columns.

  • To enable the unsorting of columns, utilize the sortable.allowUnsort option which determines if the columns can be unsorted.
  • To enable the sorting of multiple columns, set the sortable.mode option which accepts a single or multiple value.
import React from 'react';
import ReactDOM from 'react-dom';
import { TreeList, orderBy, extendDataItem, mapTree } from '@progress/kendo-react-treelist';
import employees from './data';

const subItemsField = 'employees';
const expandField = 'expanded';
const columns = [
    { field: 'name', title: 'Name', width: 310, expandable: true },
    { field: 'position', title: 'Position', width: 260 },
    { field: 'hireDate', title: 'Hire Date', width: 160, format: '{0:d}' },
    { field: 'timeInPosition', title: 'Year(s) in Position', width: 160 },
    { field: 'fullTime', title: 'Full Time', width: 150 }
];

class App extends React.Component {
    state = {
        data: [ ...employees ],
        sort: [{
            field: "name", dir: "asc"
        }],
        expanded: [1, 2, 32],
        allowUnsort: true,
        multiple: true
    }

    onExpandChange = (e) => {
        this.setState({
            expanded: e.value ?
                this.state.expanded.filter(id => id !== e.dataItem.id) :
                [ ...this.state.expanded, e.dataItem.id ]
        });
    }

    handleSortChange = (event) => {
        this.setState({
            sort: event.sort
        })
    }

    addExpandField = (dataTree) => {
        const expanded = this.state.expanded;
        return mapTree(dataTree, subItemsField, (item) =>
            extendDataItem(item, subItemsField, {
                [expandField]: expanded.includes(item.id)
            })
        );
    }

    processData = () => {
        const { data, sort } = this.state;
         return this.addExpandField(orderBy(data, sort, subItemsField));
     }

    render() {
        return (
            <div>
                <div className="example-config">
                    <input
                        type="checkbox"
                        className="k-checkbox"
                        id="unsort"
                        checked={this.state.allowUnsort}
                        onChange={(e) => this.setState({
                            allowUnsort: e.target.checked
                        })}
                    />
                    <label htmlFor="unsort" className="k-checkbox-label" style={{ lineHeight: '1.2', marginBottom: '1em' }}>
                        Enable unsorting
                    </label>
                    <br />
                    <input
                        type="checkbox"
                        className="k-checkbox"
                        id="multiSort"
                        checked={this.state.multiple}
                        onChange={(e) => this.setState({
                            multiple: e.target.checked
                        })}
                    />
                    <label htmlFor="multiSort" className="k-checkbox-label" style={{ lineHeight: '1.2' }}>
                        Enable multiple columns sorting
                    </label>
                </div>
                <TreeList
                    style={{ maxHeight: '510px', overflow: 'auto' }}
                    expandField={expandField}
                    subItemsField={subItemsField}
                    onExpandChange={this.onExpandChange}
                    sortable={{
                        allowUnsort: this.state.allowUnsort,
                        mode: this.state.multiple ? 'multiple' : 'single'
                    }}
                    sort={this.state.sort}
                    data={this.processData()}
                    onSortChange={this.handleSortChange}
                    columns={columns}
                />
            </div>
        );
    }
}

ReactDOM.render(
    <App />,
    document.querySelector('my-app')
);
 /