JavaScript/jQuery TreeList - Getting Started
jQuery
Angular
Vue
React
The TreeList component uses a multi-column tree view to display data from a local or remote storage and allows users to sort, group, filter, and perform other data operations.
Need to create printable documents simply? Try our .NET-based DevExpress Reports: they ship with an intuitive Visual Studio Report Designer, Web Report Designer for end-user ad-hoc reporting, and a rich set of report controls, including cross tabs and charts.
You can generate a variety of report types — from simple mail-merge, table, and vertical reports to master-detail (hierarchical) and cross-tab reports, print or export them to PDF, Excel, and other formats.
Develop using VS Code? Leverage the capabilities of a brand new VS Code Report Designer extension to create and edit reports/documents on any platform, be it Windows, macOS, or Linux.
Get Started with DevExpress Reports | Explore Demos
Use our DevExpress BI Dashboard to embed interactive business intelligence into your next web app.
The Web Dashboard is a data analysis UI component that you can embed into your ASP.NET Core or Angular, React, and Vue applications with .NET backend. Dashboards allow you to display multiple inter-connected data analysis elements such as grids, charts, maps, gauges, and others: all within an automatically-arranged layout.
The set of components allows you to deploy an all-in-one solution and switch between Viewer and Designer modes directly on the web client (includes adaptive layouts for tablet & mobile).
The Web Dashboard is available as a part of a Universal subscription.
This tutorial shows how to add the TreeList to a page, bind it to data, and configure its core features. As a result, you will get a UI component that looks as follows:
Each section in this tutorial covers a single configuration step. You can also find the full code in the following GitHub repository: getting-started-with-treelist.
Create a TreeList
jQuery
Add DevExtreme to your jQuery application and use the following code to create a TreeList:
$(function() { $("#treeList").dxTreeList({ // Configuration goes here }); });
<html> <head> <!-- ... --> <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script> <link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/24.2.3/css/dx.light.css"> <link rel="stylesheet" href="index.css"> <script type="text/javascript" src="https://cdn3.devexpress.com/jslib/24.2.3/js/dx.all.js"></script> <script type="text/javascript" src="index.js"></script> </head> <body class="dx-viewport"> <div id="treeList"></div> </body> </html>
#treeList { height: 500px; }
Angular
Add DevExtreme to your Angular application and use the following code to create a TreeList:
<dx-tree-list id="treeList" <!-- Configuration goes here --> > </dx-tree-list>
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { }
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { DxTreeListModule } from 'devextreme-angular'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, DxTreeListModule ], providers: [ ], bootstrap: [AppComponent] }) export class AppModule { }
#treeList { height: 500px; }
Vue
Add DevExtreme to your Vue application and use the following code to create a TreeList:
<template> <div id="app-container"> <DxTreeList id="treeList"> <!-- Configuration goes here --> </DxTreeList> </div> </template> <script> import 'devextreme/dist/css/dx.light.css'; import { DxTreeList } from 'devextreme-vue/tree-list'; export default { components: { DxTreeList } } </script> <style> #treeList { height: 500px; } </style>
React
Add DevExtreme to your React application and use the following code to create a TreeList:
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TreeList } from 'devextreme-react/tree-list'; function App() { return ( <div className="App"> <TreeList id="treeList"> {/* Configuration goes here */} </TreeList> </div> ); } export default App;
#treeList { height: 500px; }
Bind the TreeList to Data
TreeList supports plain and hierarchical data structures. If a data source has a hierarchical structure, set the dataStructure property to "tree" and use the itemsExpr property to specify the data field that contains child nodes. The TreeList automatically generates identifiers for all nodes and links them with each other. Refer to the following demo for more information: Simple Array: Hierarchical Structure.
In a plain data structure, each node must have a unique identifier and a reference to its parent node. To specify data fields that store the identifiers and the references, use the keyExpr and parentIdExpr properties. Top-level nodes descend from the root node. To specify its identifier, use the rootValue property. In this tutorial, we use a plain data structure.
The TreeList component can load and update data from different data source types. To use a local array as in this tutorial, assign it to the dataSource property. If you want to use another data source type, refer to one of the following articles:
jQuery
$(function() { $("#treeList").dxTreeList({ dataSource: employees, rootValue: -1, keyExpr: "ID", parentIdExpr: "HeadID" }); });
const employees = [{ "ID": 1, "HeadID": -1, "FullName": "John Heart", "Prefix": "Mr.", "Position": "CEO", "City": "Los Angeles", "State": "California", "Email": "jheart@dx-email.com", "Skype": "jheart_DX_skype", "MobilePhone": "(213) 555-9392", "BirthDate": "1964-03-16", "HireDate": "1995-01-15" }, { "ID": 2, "HeadID": 1, "FullName": "Samantha Bright", "Prefix": "Dr.", "Position": "COO", "City": "Los Angeles", "State": "California", "Email": "samanthab@dx-email.com", "Skype": "samanthab_DX_skype", "MobilePhone": "(213) 555-2858", "BirthDate": "1966-05-02", "HireDate": "2004-05-24" }, { "ID": 3, "HeadID": 1, "FullName": "Arthur Miller", "Prefix": "Mr.", "Position": "CTO", "City": "Denver", "State": "Colorado", "Email": "arthurm@dx-email.com", "Skype": "arthurm_DX_skype", "MobilePhone": "(310) 555-8583", "BirthDate": "1972-07-11", "HireDate": "2007-12-18" }, { "ID": 4, "HeadID": 1, "FullName": "Robert Reagan", "Prefix": "Mr.", "Position": "CMO", "City": "Bentonville", "State": "Arkansas", "Email": "robertr@dx-email.com", "Skype": "robertr_DX_skype", "MobilePhone": "(818) 555-2387", "BirthDate": "1974-09-07", "HireDate": "2002-11-08" }, { "ID": 5, "HeadID": 1, "FullName": "Greta Sims", "Prefix": "Ms.", "Position": "HR Manager", "City": "Atlanta", "State": "Georgia", "Email": "gretas@dx-email.com", "Skype": "gretas_DX_skype", "MobilePhone": "(818) 555-6546", "BirthDate": "1977-11-22", "HireDate": "1998-04-23" }, { "ID": 6, "HeadID": 3, "FullName": "Brett Wade", "Prefix": "Mr.", "Position": "IT Manager", "City": "Reno", "State": "Nevada", "Email": "brettw@dx-email.com", "Skype": "brettw_DX_skype", "MobilePhone": "(626) 555-0358", "BirthDate": "1968-12-01", "HireDate": "2009-03-06" }, { "ID": 7, "HeadID": 5, "FullName": "Sandra Johnson", "Prefix": "Mrs.", "Position": "Controller", "City": "Beaver", "State": "Utah", "Email": "sandraj@dx-email.com", "Skype": "sandraj_DX_skype", "MobilePhone": "(562) 555-2082", "BirthDate": "1974-11-15", "HireDate": "2005-05-11" }, { "ID": 8, "HeadID": 4, "FullName": "Ed Holmes", "Prefix": "Dr.", "Position": "Sales Manager", "City": "Malibu", "State": "California", "Email": "edwardh@dx-email.com", "Skype": "edwardh_DX_skype", "MobilePhone": "(310) 555-1288", "BirthDate": "1973-07-14", "HireDate": "2005-06-19" }, { "ID": 9, "HeadID": 3, "FullName": "Barb Banks", "Prefix": "Mrs.", "Position": "Support Manager", "City": "Phoenix", "State": "Arizona", "Email": "barbarab@dx-email.com", "Skype": "barbarab_DX_skype", "MobilePhone": "(310) 555-3355", "BirthDate": "1979-04-14", "HireDate": "2002-08-07" }, { "ID": 10, "HeadID": 2, "FullName": "Kevin Carter", "Prefix": "Mr.", "Position": "Shipping Manager", "City": "San Diego", "State": "California", "Email": "kevinc@dx-email.com", "Skype": "kevinc_DX_skype", "MobilePhone": "(213) 555-2840", "BirthDate": "1978-01-09", "HireDate": "2009-08-11" }, { "ID": 11, "HeadID": 5, "FullName": "Cindy Stanwick", "Prefix": "Ms.", "Position": "HR Assistant", "City": "Little Rock", "State": "Arkansas", "Email": "cindys@dx-email.com", "Skype": "cindys_DX_skype", "MobilePhone": "(818) 555-6655", "BirthDate": "1985-06-05", "HireDate": "2008-03-24" }, { "ID": 12, "HeadID": 8, "FullName": "Sammy Hill", "Prefix": "Mr.", "Position": "Sales Assistant", "City": "Pasadena", "State": "California", "Email": "sammyh@dx-email.com", "Skype": "sammyh_DX_skype", "MobilePhone": "(626) 555-7292", "BirthDate": "1984-02-17", "HireDate": "2012-02-01" }, { "ID": 13, "HeadID": 10, "FullName": "Davey Jones", "Prefix": "Mr.", "Position": "Shipping Assistant", "City": "Pasadena", "State": "California", "Email": "davidj@dx-email.com", "Skype": "davidj_DX_skype", "MobilePhone": "(626) 555-0281", "BirthDate": "1983-03-06", "HireDate": "2011-04-24" }, { "ID": 14, "HeadID": 10, "FullName": "Victor Norris", "Prefix": "Mr.", "Position": "Shipping Assistant", "City": "Little Rock", "State": "Arkansas", "Email": "victorn@dx-email.com", "Skype": "victorn_DX_skype", "MobilePhone": "(213) 555-9278", "BirthDate": "1986-07-23", "HireDate": "2012-07-23" }, { "ID": 15, "HeadID": 10, "FullName": "Mary Stern", "Prefix": "Ms.", "Position": "Shipping Assistant", "City": "Beaver", "State": "Utah", "Email": "marys@dx-email.com", "Skype": "marys_DX_skype", "MobilePhone": "(818) 555-7857", "BirthDate": "1982-04-08", "HireDate": "2012-08-12" }, { "ID": 16, "HeadID": 10, "FullName": "Robin Cosworth", "Prefix": "Mrs.", "Position": "Shipping Assistant", "City": "Los Angeles", "State": "California", "Email": "robinc@dx-email.com", "Skype": "robinc_DX_skype", "MobilePhone": "(818) 555-0942", "BirthDate": "1981-06-12", "HireDate": "2012-09-01" }, { "ID": 17, "HeadID": 9, "FullName": "Kelly Rodriguez", "Prefix": "Ms.", "Position": "Support Assistant", "City": "Boise", "State": "Idaho", "Email": "kellyr@dx-email.com", "Skype": "kellyr_DX_skype", "MobilePhone": "(818) 555-9248", "BirthDate": "1988-05-11", "HireDate": "2012-10-13" }, { "ID": 18, "HeadID": 9, "FullName": "James Anderson", "Prefix": "Mr.", "Position": "Support Assistant", "City": "Atlanta", "State": "Georgia", "Email": "jamesa@dx-email.com", "Skype": "jamesa_DX_skype", "MobilePhone": "(323) 555-4702", "BirthDate": "1987-01-29", "HireDate": "2012-10-18" }, { "ID": 19, "HeadID": 9, "FullName": "Antony Remmen", "Prefix": "Mr.", "Position": "Support Assistant", "City": "Boise", "State": "Idaho", "Email": "anthonyr@dx-email.com", "Skype": "anthonyr_DX_skype", "MobilePhone": "(310) 555-6625", "BirthDate": "1986-02-19", "HireDate": "2013-01-19" }, { "ID": 20, "HeadID": 8, "FullName": "Olivia Peyton", "Prefix": "Mrs.", "Position": "Sales Assistant", "City": "Atlanta", "State": "Georgia", "Email": "oliviap@dx-email.com", "Skype": "oliviap_DX_skype", "MobilePhone": "(310) 555-2728", "BirthDate": "1981-06-03", "HireDate": "2012-05-14" }, { "ID": 21, "HeadID": 6, "FullName": "Taylor Riley", "Prefix": "Mr.", "Position": "Network Admin", "City": "San Jose", "State": "California", "Email": "taylorr@dx-email.com", "Skype": "taylorr_DX_skype", "MobilePhone": "(310) 555-7276", "BirthDate": "1982-08-14", "HireDate": "2012-04-14" }, { "ID": 22, "HeadID": 6, "FullName": "Amelia Harper", "Prefix": "Mrs.", "Position": "Network Admin", "City": "Los Angeles", "State": "California", "Email": "ameliah@dx-email.com", "Skype": "ameliah_DX_skype", "MobilePhone": "(213) 555-4276", "BirthDate": "1983-11-19", "HireDate": "2011-02-10" }, { "ID": 23, "HeadID": 6, "FullName": "Wally Hobbs", "Prefix": "Mr.", "Position": "Programmer", "City": "Chatsworth", "State": "California", "Email": "wallyh@dx-email.com", "Skype": "wallyh_DX_skype", "MobilePhone": "(818) 555-8872", "BirthDate": "1984-12-24", "HireDate": "2011-02-17" }, { "ID": 24, "HeadID": 6, "FullName": "Brad Jameson", "Prefix": "Mr.", "Position": "Programmer", "City": "San Fernando", "State": "California", "Email": "bradleyj@dx-email.com", "Skype": "bradleyj_DX_skype", "MobilePhone": "(818) 555-4646", "BirthDate": "1988-10-12", "HireDate": "2011-03-02" }, { "ID": 25, "HeadID": 6, "FullName": "Karen Goodson", "Prefix": "Miss", "Position": "Programmer", "City": "South Pasadena", "State": "California", "Email": "kareng@dx-email.com", "Skype": "kareng_DX_skype", "MobilePhone": "(626) 555-0908", "BirthDate": "1987-04-26", "HireDate": "2011-03-14" }, { "ID": 26, "HeadID": 5, "FullName": "Marcus Orbison", "Prefix": "Mr.", "Position": "Travel Coordinator", "City": "Los Angeles", "State": "California", "Email": "marcuso@dx-email.com", "Skype": "marcuso_DX_skype", "MobilePhone": "(213) 555-7098", "BirthDate": "1982-03-02", "HireDate": "2005-05-19" }, { "ID": 27, "HeadID": 5, "FullName": "Sandy Bright", "Prefix": "Ms.", "Position": "Benefits Coordinator", "City": "Denver", "State": "Colorado", "Email": "sandrab@dx-email.com", "Skype": "sandrab_DX_skype", "MobilePhone": "(818) 555-0524", "BirthDate": "1983-09-11", "HireDate": "2005-06-04" }, { "ID": 28, "HeadID": 6, "FullName": "Morgan Kennedy", "Prefix": "Mrs.", "Position": "Graphic Designer", "City": "San Fernando Valley", "State": "California", "Email": "morgank@dx-email.com", "Skype": "morgank_DX_skype", "MobilePhone": "(818) 555-8238", "BirthDate": "1984-07-17", "HireDate": "2012-01-11" }, { "ID": 29, "HeadID": 28, "FullName": "Violet Bailey", "Prefix": "Ms.", "Position": "Jr Graphic Designer", "City": "La Canada", "State": "California", "Email": "violetb@dx-email.com", "Skype": "violetb_DX_skype", "MobilePhone": "(818) 555-2478", "BirthDate": "1985-06-10", "HireDate": "2012-01-19" }, { "ID": 30, "HeadID": 5, "FullName": "Ken Samuelson", "Prefix": "Dr.", "Position": "Ombudsman", "City": "St. Louis", "State": "Missouri", "Email": "kents@dx-email.com", "Skype": "kents_DX_skype", "MobilePhone": "(562) 555-9282", "BirthDate": "1972-09-11", "HireDate": "2009-04-22" }];
Angular
<dx-tree-list [dataSource]="employees" [rootValue]="-1" keyExpr="ID" parentIdExpr="HeadID"> </dx-tree-list>
import { Component } from '@angular/core'; import { Employee, EmployeesService } from './employees.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { employees: Employee[] = []; constructor(service: EmployeesService) { this.employees = service.getEmployees(); } }
import { Injectable } from '@angular/core'; export interface Employee { ID: Number, HeadID: Number, FullName: String, Position: String, City: String, State: String, Email: String, Skype: String, MobilePhone: String, BirthDate: String, HireDate: String, } const employees: Employee[] = [{ "ID": 1, "HeadID": -1, "FullName": "John Heart", "Position": "CEO", "City": "Los Angeles", "State": "California", "Email": "jheart@dx-email.com", "Skype": "jheart_DX_skype", "MobilePhone": "(213) 555-9392", "BirthDate": "1964-03-16", "HireDate": "1995-01-15" }, { "ID": 2, "HeadID": 1, "FullName": "Samantha Bright", "Position": "COO", "City": "Los Angeles", "State": "California", "Email": "samanthab@dx-email.com", "Skype": "samanthab_DX_skype", "MobilePhone": "(213) 555-2858", "BirthDate": "1966-05-02", "HireDate": "2004-05-24" }, { "ID": 3, "HeadID": 1, "FullName": "Arthur Miller", "Position": "CTO", "City": "Denver", "State": "Colorado", "Email": "arthurm@dx-email.com", "Skype": "arthurm_DX_skype", "MobilePhone": "(310) 555-8583", "BirthDate": "1972-07-11", "HireDate": "2007-12-18" }, { "ID": 4, "HeadID": 1, "FullName": "Robert Reagan", "Position": "CMO", "City": "Bentonville", "State": "Arkansas", "Email": "robertr@dx-email.com", "Skype": "robertr_DX_skype", "MobilePhone": "(818) 555-2387", "BirthDate": "1974-09-07", "HireDate": "2002-11-08" }, { "ID": 5, "HeadID": 1, "FullName": "Greta Sims", "Position": "HR Manager", "City": "Atlanta", "State": "Georgia", "Email": "gretas@dx-email.com", "Skype": "gretas_DX_skype", "MobilePhone": "(818) 555-6546", "BirthDate": "1977-11-22", "HireDate": "1998-04-23" }, { "ID": 6, "HeadID": 3, "FullName": "Brett Wade", "Position": "IT Manager", "City": "Reno", "State": "Nevada", "Email": "brettw@dx-email.com", "Skype": "brettw_DX_skype", "MobilePhone": "(626) 555-0358", "BirthDate": "1968-12-01", "HireDate": "2009-03-06" }, { "ID": 7, "HeadID": 5, "FullName": "Sandra Johnson", "Position": "Controller", "City": "Beaver", "State": "Utah", "Email": "sandraj@dx-email.com", "Skype": "sandraj_DX_skype", "MobilePhone": "(562) 555-2082", "BirthDate": "1974-11-15", "HireDate": "2005-05-11" }, { "ID": 8, "HeadID": 4, "FullName": "Ed Holmes", "Position": "Sales Manager", "City": "Malibu", "State": "California", "Email": "edwardh@dx-email.com", "Skype": "edwardh_DX_skype", "MobilePhone": "(310) 555-1288", "BirthDate": "1973-07-14", "HireDate": "2005-06-19" }, { "ID": 9, "HeadID": 3, "FullName": "Barb Banks", "Position": "Support Manager", "City": "Phoenix", "State": "Arizona", "Email": "barbarab@dx-email.com", "Skype": "barbarab_DX_skype", "MobilePhone": "(310) 555-3355", "BirthDate": "1979-04-14", "HireDate": "2002-08-07" }, { "ID": 10, "HeadID": 2, "FullName": "Kevin Carter", "Position": "Shipping Manager", "City": "San Diego", "State": "California", "Email": "kevinc@dx-email.com", "Skype": "kevinc_DX_skype", "MobilePhone": "(213) 555-2840", "BirthDate": "1978-01-09", "HireDate": "2009-08-11" }, { "ID": 11, "HeadID": 5, "FullName": "Cindy Stanwick", "Position": "HR Assistant", "City": "Little Rock", "State": "Arkansas", "Email": "cindys@dx-email.com", "Skype": "cindys_DX_skype", "MobilePhone": "(818) 555-6655", "BirthDate": "1985-06-05", "HireDate": "2008-03-24" }, { "ID": 12, "HeadID": 8, "FullName": "Sammy Hill", "Position": "Sales Assistant", "City": "Pasadena", "State": "California", "Email": "sammyh@dx-email.com", "Skype": "sammyh_DX_skype", "MobilePhone": "(626) 555-7292", "BirthDate": "1984-02-17", "HireDate": "2012-02-01" }, { "ID": 13, "HeadID": 10, "FullName": "Davey Jones", "Position": "Shipping Assistant", "City": "Pasadena", "State": "California", "Email": "davidj@dx-email.com", "Skype": "davidj_DX_skype", "MobilePhone": "(626) 555-0281", "BirthDate": "1983-03-06", "HireDate": "2011-04-24" }, { "ID": 14, "HeadID": 10, "FullName": "Victor Norris", "Position": "Shipping Assistant", "City": "Little Rock", "State": "Arkansas", "Email": "victorn@dx-email.com", "Skype": "victorn_DX_skype", "MobilePhone": "(213) 555-9278", "BirthDate": "1986-07-23", "HireDate": "2012-07-23" }, { "ID": 15, "HeadID": 10, "FullName": "Mary Stern", "Position": "Shipping Assistant", "City": "Beaver", "State": "Utah", "Email": "marys@dx-email.com", "Skype": "marys_DX_skype", "MobilePhone": "(818) 555-7857", "BirthDate": "1982-04-08", "HireDate": "2012-08-12" }, { "ID": 16, "HeadID": 10, "FullName": "Robin Cosworth", "Position": "Shipping Assistant", "City": "Los Angeles", "State": "California", "Email": "robinc@dx-email.com", "Skype": "robinc_DX_skype", "MobilePhone": "(818) 555-0942", "BirthDate": "1981-06-12", "HireDate": "2012-09-01" }, { "ID": 17, "HeadID": 9, "FullName": "Kelly Rodriguez", "Position": "Support Assistant", "City": "Boise", "State": "Idaho", "Email": "kellyr@dx-email.com", "Skype": "kellyr_DX_skype", "MobilePhone": "(818) 555-9248", "BirthDate": "1988-05-11", "HireDate": "2012-10-13" }, { "ID": 18, "HeadID": 9, "FullName": "James Anderson", "Position": "Support Assistant", "City": "Atlanta", "State": "Georgia", "Email": "jamesa@dx-email.com", "Skype": "jamesa_DX_skype", "MobilePhone": "(323) 555-4702", "BirthDate": "1987-01-29", "HireDate": "2012-10-18" }, { "ID": 19, "HeadID": 9, "FullName": "Antony Remmen", "Position": "Support Assistant", "City": "Boise", "State": "Idaho", "Email": "anthonyr@dx-email.com", "Skype": "anthonyr_DX_skype", "MobilePhone": "(310) 555-6625", "BirthDate": "1986-02-19", "HireDate": "2013-01-19" }, { "ID": 20, "HeadID": 8, "FullName": "Olivia Peyton", "Position": "Sales Assistant", "City": "Atlanta", "State": "Georgia", "Email": "oliviap@dx-email.com", "Skype": "oliviap_DX_skype", "MobilePhone": "(310) 555-2728", "BirthDate": "1981-06-03", "HireDate": "2012-05-14" }, { "ID": 21, "HeadID": 6, "FullName": "Taylor Riley", "Position": "Network Admin", "City": "San Jose", "State": "California", "Email": "taylorr@dx-email.com", "Skype": "taylorr_DX_skype", "MobilePhone": "(310) 555-7276", "BirthDate": "1982-08-14", "HireDate": "2012-04-14" }, { "ID": 22, "HeadID": 6, "FullName": "Amelia Harper", "Position": "Network Admin", "City": "Los Angeles", "State": "California", "Email": "ameliah@dx-email.com", "Skype": "ameliah_DX_skype", "MobilePhone": "(213) 555-4276", "BirthDate": "1983-11-19", "HireDate": "2011-02-10" }, { "ID": 23, "HeadID": 6, "FullName": "Wally Hobbs", "Position": "Programmer", "City": "Chatsworth", "State": "California", "Email": "wallyh@dx-email.com", "Skype": "wallyh_DX_skype", "MobilePhone": "(818) 555-8872", "BirthDate": "1984-12-24", "HireDate": "2011-02-17" }, { "ID": 24, "HeadID": 6, "FullName": "Brad Jameson", "Position": "Programmer", "City": "San Fernando", "State": "California", "Email": "bradleyj@dx-email.com", "Skype": "bradleyj_DX_skype", "MobilePhone": "(818) 555-4646", "BirthDate": "1988-10-12", "HireDate": "2011-03-02" }, { "ID": 25, "HeadID": 6, "FullName": "Karen Goodson", "Position": "Programmer", "City": "South Pasadena", "State": "California", "Email": "kareng@dx-email.com", "Skype": "kareng_DX_skype", "MobilePhone": "(626) 555-0908", "BirthDate": "1987-04-26", "HireDate": "2011-03-14" }, { "ID": 26, "HeadID": 5, "FullName": "Marcus Orbison", "Position": "Travel Coordinator", "City": "Los Angeles", "State": "California", "Email": "marcuso@dx-email.com", "Skype": "marcuso_DX_skype", "MobilePhone": "(213) 555-7098", "BirthDate": "1982-03-02", "HireDate": "2005-05-19" }, { "ID": 27, "HeadID": 5, "FullName": "Sandy Bright", "Position": "Benefits Coordinator", "City": "Denver", "State": "Colorado", "Email": "sandrab@dx-email.com", "Skype": "sandrab_DX_skype", "MobilePhone": "(818) 555-0524", "BirthDate": "1983-09-11", "HireDate": "2005-06-04" }, { "ID": 28, "HeadID": 6, "FullName": "Morgan Kennedy", "Position": "Graphic Designer", "City": "San Fernando Valley", "State": "California", "Email": "morgank@dx-email.com", "Skype": "morgank_DX_skype", "MobilePhone": "(818) 555-8238", "BirthDate": "1984-07-17", "HireDate": "2012-01-11" }, { "ID": 29, "HeadID": 28, "FullName": "Violet Bailey", "Position": "Jr Graphic Designer", "City": "La Canada", "State": "California", "Email": "violetb@dx-email.com", "Skype": "violetb_DX_skype", "MobilePhone": "(818) 555-2478", "BirthDate": "1985-06-10", "HireDate": "2012-01-19" }, { "ID": 30, "HeadID": 5, "FullName": "Ken Samuelson", "Position": "Ombudsman", "City": "St. Louis", "State": "Missouri", "Email": "kents@dx-email.com", "Skype": "kents_DX_skype", "MobilePhone": "(562) 555-9282", "BirthDate": "1972-09-11", "HireDate": "2009-04-22" }]; @Injectable({ providedIn: 'root' }) export class EmployeesService { getEmployees(): Employee[] { return employees; } }
Vue
<template> <div id="app-container"> <DxTreeList :data-source="employees" :root-value="-1" key-expr="ID" parent-id-expr="HeadID"> </DxTreeList> </div> </template> <script> // ... import service from './employees.service'; export default { // ... data() { return { employees: service.getEmployees(), } }, } </script>
const employees = [{ "ID": 1, "HeadID": -1, "FullName": "John Heart", "Position": "CEO", "City": "Los Angeles", "State": "California", "Email": "jheart@dx-email.com", "Skype": "jheart_DX_skype", "MobilePhone": "(213) 555-9392", "BirthDate": "1964-03-16", "HireDate": "1995-01-15" }, { "ID": 2, "HeadID": 1, "FullName": "Samantha Bright", "Position": "COO", "City": "Los Angeles", "State": "California", "Email": "samanthab@dx-email.com", "Skype": "samanthab_DX_skype", "MobilePhone": "(213) 555-2858", "BirthDate": "1966-05-02", "HireDate": "2004-05-24" }, { "ID": 3, "HeadID": 1, "FullName": "Arthur Miller", "Position": "CTO", "City": "Denver", "State": "Colorado", "Email": "arthurm@dx-email.com", "Skype": "arthurm_DX_skype", "MobilePhone": "(310) 555-8583", "BirthDate": "1972-07-11", "HireDate": "2007-12-18" }, { "ID": 4, "HeadID": 1, "FullName": "Robert Reagan", "Position": "CMO", "City": "Bentonville", "State": "Arkansas", "Email": "robertr@dx-email.com", "Skype": "robertr_DX_skype", "MobilePhone": "(818) 555-2387", "BirthDate": "1974-09-07", "HireDate": "2002-11-08" }, { "ID": 5, "HeadID": 1, "FullName": "Greta Sims", "Position": "HR Manager", "City": "Atlanta", "State": "Georgia", "Email": "gretas@dx-email.com", "Skype": "gretas_DX_skype", "MobilePhone": "(818) 555-6546", "BirthDate": "1977-11-22", "HireDate": "1998-04-23" }, { "ID": 6, "HeadID": 3, "FullName": "Brett Wade", "Position": "IT Manager", "City": "Reno", "State": "Nevada", "Email": "brettw@dx-email.com", "Skype": "brettw_DX_skype", "MobilePhone": "(626) 555-0358", "BirthDate": "1968-12-01", "HireDate": "2009-03-06" }, { "ID": 7, "HeadID": 5, "FullName": "Sandra Johnson", "Position": "Controller", "City": "Beaver", "State": "Utah", "Email": "sandraj@dx-email.com", "Skype": "sandraj_DX_skype", "MobilePhone": "(562) 555-2082", "BirthDate": "1974-11-15", "HireDate": "2005-05-11" }, { "ID": 8, "HeadID": 4, "FullName": "Ed Holmes", "Position": "Sales Manager", "City": "Malibu", "State": "California", "Email": "edwardh@dx-email.com", "Skype": "edwardh_DX_skype", "MobilePhone": "(310) 555-1288", "BirthDate": "1973-07-14", "HireDate": "2005-06-19" }, { "ID": 9, "HeadID": 3, "FullName": "Barb Banks", "Position": "Support Manager", "City": "Phoenix", "State": "Arizona", "Email": "barbarab@dx-email.com", "Skype": "barbarab_DX_skype", "MobilePhone": "(310) 555-3355", "BirthDate": "1979-04-14", "HireDate": "2002-08-07" }, { "ID": 10, "HeadID": 2, "FullName": "Kevin Carter", "Position": "Shipping Manager", "City": "San Diego", "State": "California", "Email": "kevinc@dx-email.com", "Skype": "kevinc_DX_skype", "MobilePhone": "(213) 555-2840", "BirthDate": "1978-01-09", "HireDate": "2009-08-11" }, { "ID": 11, "HeadID": 5, "FullName": "Cindy Stanwick", "Position": "HR Assistant", "City": "Little Rock", "State": "Arkansas", "Email": "cindys@dx-email.com", "Skype": "cindys_DX_skype", "MobilePhone": "(818) 555-6655", "BirthDate": "1985-06-05", "HireDate": "2008-03-24" }, { "ID": 12, "HeadID": 8, "FullName": "Sammy Hill", "Position": "Sales Assistant", "City": "Pasadena", "State": "California", "Email": "sammyh@dx-email.com", "Skype": "sammyh_DX_skype", "MobilePhone": "(626) 555-7292", "BirthDate": "1984-02-17", "HireDate": "2012-02-01" }, { "ID": 13, "HeadID": 10, "FullName": "Davey Jones", "Position": "Shipping Assistant", "City": "Pasadena", "State": "California", "Email": "davidj@dx-email.com", "Skype": "davidj_DX_skype", "MobilePhone": "(626) 555-0281", "BirthDate": "1983-03-06", "HireDate": "2011-04-24" }, { "ID": 14, "HeadID": 10, "FullName": "Victor Norris", "Position": "Shipping Assistant", "City": "Little Rock", "State": "Arkansas", "Email": "victorn@dx-email.com", "Skype": "victorn_DX_skype", "MobilePhone": "(213) 555-9278", "BirthDate": "1986-07-23", "HireDate": "2012-07-23" }, { "ID": 15, "HeadID": 10, "FullName": "Mary Stern", "Position": "Shipping Assistant", "City": "Beaver", "State": "Utah", "Email": "marys@dx-email.com", "Skype": "marys_DX_skype", "MobilePhone": "(818) 555-7857", "BirthDate": "1982-04-08", "HireDate": "2012-08-12" }, { "ID": 16, "HeadID": 10, "FullName": "Robin Cosworth", "Position": "Shipping Assistant", "City": "Los Angeles", "State": "California", "Email": "robinc@dx-email.com", "Skype": "robinc_DX_skype", "MobilePhone": "(818) 555-0942", "BirthDate": "1981-06-12", "HireDate": "2012-09-01" }, { "ID": 17, "HeadID": 9, "FullName": "Kelly Rodriguez", "Position": "Support Assistant", "City": "Boise", "State": "Idaho", "Email": "kellyr@dx-email.com", "Skype": "kellyr_DX_skype", "MobilePhone": "(818) 555-9248", "BirthDate": "1988-05-11", "HireDate": "2012-10-13" }, { "ID": 18, "HeadID": 9, "FullName": "James Anderson", "Position": "Support Assistant", "City": "Atlanta", "State": "Georgia", "Email": "jamesa@dx-email.com", "Skype": "jamesa_DX_skype", "MobilePhone": "(323) 555-4702", "BirthDate": "1987-01-29", "HireDate": "2012-10-18" }, { "ID": 19, "HeadID": 9, "FullName": "Antony Remmen", "Position": "Support Assistant", "City": "Boise", "State": "Idaho", "Email": "anthonyr@dx-email.com", "Skype": "anthonyr_DX_skype", "MobilePhone": "(310) 555-6625", "BirthDate": "1986-02-19", "HireDate": "2013-01-19" }, { "ID": 20, "HeadID": 8, "FullName": "Olivia Peyton", "Position": "Sales Assistant", "City": "Atlanta", "State": "Georgia", "Email": "oliviap@dx-email.com", "Skype": "oliviap_DX_skype", "MobilePhone": "(310) 555-2728", "BirthDate": "1981-06-03", "HireDate": "2012-05-14" }, { "ID": 21, "HeadID": 6, "FullName": "Taylor Riley", "Position": "Network Admin", "City": "San Jose", "State": "California", "Email": "taylorr@dx-email.com", "Skype": "taylorr_DX_skype", "MobilePhone": "(310) 555-7276", "BirthDate": "1982-08-14", "HireDate": "2012-04-14" }, { "ID": 22, "HeadID": 6, "FullName": "Amelia Harper", "Position": "Network Admin", "City": "Los Angeles", "State": "California", "Email": "ameliah@dx-email.com", "Skype": "ameliah_DX_skype", "MobilePhone": "(213) 555-4276", "BirthDate": "1983-11-19", "HireDate": "2011-02-10" }, { "ID": 23, "HeadID": 6, "FullName": "Wally Hobbs", "Position": "Programmer", "City": "Chatsworth", "State": "California", "Email": "wallyh@dx-email.com", "Skype": "wallyh_DX_skype", "MobilePhone": "(818) 555-8872", "BirthDate": "1984-12-24", "HireDate": "2011-02-17" }, { "ID": 24, "HeadID": 6, "FullName": "Brad Jameson", "Position": "Programmer", "City": "San Fernando", "State": "California", "Email": "bradleyj@dx-email.com", "Skype": "bradleyj_DX_skype", "MobilePhone": "(818) 555-4646", "BirthDate": "1988-10-12", "HireDate": "2011-03-02" }, { "ID": 25, "HeadID": 6, "FullName": "Karen Goodson", "Position": "Programmer", "City": "South Pasadena", "State": "California", "Email": "kareng@dx-email.com", "Skype": "kareng_DX_skype", "MobilePhone": "(626) 555-0908", "BirthDate": "1987-04-26", "HireDate": "2011-03-14" }, { "ID": 26, "HeadID": 5, "FullName": "Marcus Orbison", "Position": "Travel Coordinator", "City": "Los Angeles", "State": "California", "Email": "marcuso@dx-email.com", "Skype": "marcuso_DX_skype", "MobilePhone": "(213) 555-7098", "BirthDate": "1982-03-02", "HireDate": "2005-05-19" }, { "ID": 27, "HeadID": 5, "FullName": "Sandy Bright", "Position": "Benefits Coordinator", "City": "Denver", "State": "Colorado", "Email": "sandrab@dx-email.com", "Skype": "sandrab_DX_skype", "MobilePhone": "(818) 555-0524", "BirthDate": "1983-09-11", "HireDate": "2005-06-04" }, { "ID": 28, "HeadID": 6, "FullName": "Morgan Kennedy", "Position": "Graphic Designer", "City": "San Fernando Valley", "State": "California", "Email": "morgank@dx-email.com", "Skype": "morgank_DX_skype", "MobilePhone": "(818) 555-8238", "BirthDate": "1984-07-17", "HireDate": "2012-01-11" }, { "ID": 29, "HeadID": 28, "FullName": "Violet Bailey", "Position": "Jr Graphic Designer", "City": "La Canada", "State": "California", "Email": "violetb@dx-email.com", "Skype": "violetb_DX_skype", "MobilePhone": "(818) 555-2478", "BirthDate": "1985-06-10", "HireDate": "2012-01-19" }, { "ID": 30, "HeadID": 5, "FullName": "Ken Samuelson", "Position": "Ombudsman", "City": "St. Louis", "State": "Missouri", "Email": "kents@dx-email.com", "Skype": "kents_DX_skype", "MobilePhone": "(562) 555-9282", "BirthDate": "1972-09-11", "HireDate": "2009-04-22" }]; export default { getEmployees() { return employees; } }
React
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TreeList } from 'devextreme-react/tree-list'; import { employees } from './employees'; function App() { return ( <div className="App"> <TreeList dataSource={employees} rootValue={-1} keyExpr="ID" parentIdExpr="HeadID"> </TreeList> </div> ); } export default App;
export const employees = [{ "ID": 1, "HeadID": -1, "FullName": "John Heart", "Position": "CEO", "City": "Los Angeles", "State": "California", "Email": "jheart@dx-email.com", "Skype": "jheart_DX_skype", "MobilePhone": "(213) 555-9392", "BirthDate": "1964-03-16", "HireDate": "1995-01-15" }, { "ID": 2, "HeadID": 1, "FullName": "Samantha Bright", "Position": "COO", "City": "Los Angeles", "State": "California", "Email": "samanthab@dx-email.com", "Skype": "samanthab_DX_skype", "MobilePhone": "(213) 555-2858", "BirthDate": "1966-05-02", "HireDate": "2004-05-24" }, { "ID": 3, "HeadID": 1, "FullName": "Arthur Miller", "Position": "CTO", "City": "Denver", "State": "Colorado", "Email": "arthurm@dx-email.com", "Skype": "arthurm_DX_skype", "MobilePhone": "(310) 555-8583", "BirthDate": "1972-07-11", "HireDate": "2007-12-18" }, { "ID": 4, "HeadID": 1, "FullName": "Robert Reagan", "Position": "CMO", "City": "Bentonville", "State": "Arkansas", "Email": "robertr@dx-email.com", "Skype": "robertr_DX_skype", "MobilePhone": "(818) 555-2387", "BirthDate": "1974-09-07", "HireDate": "2002-11-08" }, { "ID": 5, "HeadID": 1, "FullName": "Greta Sims", "Position": "HR Manager", "City": "Atlanta", "State": "Georgia", "Email": "gretas@dx-email.com", "Skype": "gretas_DX_skype", "MobilePhone": "(818) 555-6546", "BirthDate": "1977-11-22", "HireDate": "1998-04-23" }, { "ID": 6, "HeadID": 3, "FullName": "Brett Wade", "Position": "IT Manager", "City": "Reno", "State": "Nevada", "Email": "brettw@dx-email.com", "Skype": "brettw_DX_skype", "MobilePhone": "(626) 555-0358", "BirthDate": "1968-12-01", "HireDate": "2009-03-06" }, { "ID": 7, "HeadID": 5, "FullName": "Sandra Johnson", "Position": "Controller", "City": "Beaver", "State": "Utah", "Email": "sandraj@dx-email.com", "Skype": "sandraj_DX_skype", "MobilePhone": "(562) 555-2082", "BirthDate": "1974-11-15", "HireDate": "2005-05-11" }, { "ID": 8, "HeadID": 4, "FullName": "Ed Holmes", "Position": "Sales Manager", "City": "Malibu", "State": "California", "Email": "edwardh@dx-email.com", "Skype": "edwardh_DX_skype", "MobilePhone": "(310) 555-1288", "BirthDate": "1973-07-14", "HireDate": "2005-06-19" }, { "ID": 9, "HeadID": 3, "FullName": "Barb Banks", "Position": "Support Manager", "City": "Phoenix", "State": "Arizona", "Email": "barbarab@dx-email.com", "Skype": "barbarab_DX_skype", "MobilePhone": "(310) 555-3355", "BirthDate": "1979-04-14", "HireDate": "2002-08-07" }, { "ID": 10, "HeadID": 2, "FullName": "Kevin Carter", "Position": "Shipping Manager", "City": "San Diego", "State": "California", "Email": "kevinc@dx-email.com", "Skype": "kevinc_DX_skype", "MobilePhone": "(213) 555-2840", "BirthDate": "1978-01-09", "HireDate": "2009-08-11" }, { "ID": 11, "HeadID": 5, "FullName": "Cindy Stanwick", "Position": "HR Assistant", "City": "Little Rock", "State": "Arkansas", "Email": "cindys@dx-email.com", "Skype": "cindys_DX_skype", "MobilePhone": "(818) 555-6655", "BirthDate": "1985-06-05", "HireDate": "2008-03-24" }, { "ID": 12, "HeadID": 8, "FullName": "Sammy Hill", "Position": "Sales Assistant", "City": "Pasadena", "State": "California", "Email": "sammyh@dx-email.com", "Skype": "sammyh_DX_skype", "MobilePhone": "(626) 555-7292", "BirthDate": "1984-02-17", "HireDate": "2012-02-01" }, { "ID": 13, "HeadID": 10, "FullName": "Davey Jones", "Position": "Shipping Assistant", "City": "Pasadena", "State": "California", "Email": "davidj@dx-email.com", "Skype": "davidj_DX_skype", "MobilePhone": "(626) 555-0281", "BirthDate": "1983-03-06", "HireDate": "2011-04-24" }, { "ID": 14, "HeadID": 10, "FullName": "Victor Norris", "Position": "Shipping Assistant", "City": "Little Rock", "State": "Arkansas", "Email": "victorn@dx-email.com", "Skype": "victorn_DX_skype", "MobilePhone": "(213) 555-9278", "BirthDate": "1986-07-23", "HireDate": "2012-07-23" }, { "ID": 15, "HeadID": 10, "FullName": "Mary Stern", "Position": "Shipping Assistant", "City": "Beaver", "State": "Utah", "Email": "marys@dx-email.com", "Skype": "marys_DX_skype", "MobilePhone": "(818) 555-7857", "BirthDate": "1982-04-08", "HireDate": "2012-08-12" }, { "ID": 16, "HeadID": 10, "FullName": "Robin Cosworth", "Position": "Shipping Assistant", "City": "Los Angeles", "State": "California", "Email": "robinc@dx-email.com", "Skype": "robinc_DX_skype", "MobilePhone": "(818) 555-0942", "BirthDate": "1981-06-12", "HireDate": "2012-09-01" }, { "ID": 17, "HeadID": 9, "FullName": "Kelly Rodriguez", "Position": "Support Assistant", "City": "Boise", "State": "Idaho", "Email": "kellyr@dx-email.com", "Skype": "kellyr_DX_skype", "MobilePhone": "(818) 555-9248", "BirthDate": "1988-05-11", "HireDate": "2012-10-13" }, { "ID": 18, "HeadID": 9, "FullName": "James Anderson", "Position": "Support Assistant", "City": "Atlanta", "State": "Georgia", "Email": "jamesa@dx-email.com", "Skype": "jamesa_DX_skype", "MobilePhone": "(323) 555-4702", "BirthDate": "1987-01-29", "HireDate": "2012-10-18" }, { "ID": 19, "HeadID": 9, "FullName": "Antony Remmen", "Position": "Support Assistant", "City": "Boise", "State": "Idaho", "Email": "anthonyr@dx-email.com", "Skype": "anthonyr_DX_skype", "MobilePhone": "(310) 555-6625", "BirthDate": "1986-02-19", "HireDate": "2013-01-19" }, { "ID": 20, "HeadID": 8, "FullName": "Olivia Peyton", "Position": "Sales Assistant", "City": "Atlanta", "State": "Georgia", "Email": "oliviap@dx-email.com", "Skype": "oliviap_DX_skype", "MobilePhone": "(310) 555-2728", "BirthDate": "1981-06-03", "HireDate": "2012-05-14" }, { "ID": 21, "HeadID": 6, "FullName": "Taylor Riley", "Position": "Network Admin", "City": "San Jose", "State": "California", "Email": "taylorr@dx-email.com", "Skype": "taylorr_DX_skype", "MobilePhone": "(310) 555-7276", "BirthDate": "1982-08-14", "HireDate": "2012-04-14" }, { "ID": 22, "HeadID": 6, "FullName": "Amelia Harper", "Position": "Network Admin", "City": "Los Angeles", "State": "California", "Email": "ameliah@dx-email.com", "Skype": "ameliah_DX_skype", "MobilePhone": "(213) 555-4276", "BirthDate": "1983-11-19", "HireDate": "2011-02-10" }, { "ID": 23, "HeadID": 6, "FullName": "Wally Hobbs", "Position": "Programmer", "City": "Chatsworth", "State": "California", "Email": "wallyh@dx-email.com", "Skype": "wallyh_DX_skype", "MobilePhone": "(818) 555-8872", "BirthDate": "1984-12-24", "HireDate": "2011-02-17" }, { "ID": 24, "HeadID": 6, "FullName": "Brad Jameson", "Position": "Programmer", "City": "San Fernando", "State": "California", "Email": "bradleyj@dx-email.com", "Skype": "bradleyj_DX_skype", "MobilePhone": "(818) 555-4646", "BirthDate": "1988-10-12", "HireDate": "2011-03-02" }, { "ID": 25, "HeadID": 6, "FullName": "Karen Goodson", "Position": "Programmer", "City": "South Pasadena", "State": "California", "Email": "kareng@dx-email.com", "Skype": "kareng_DX_skype", "MobilePhone": "(626) 555-0908", "BirthDate": "1987-04-26", "HireDate": "2011-03-14" }, { "ID": 26, "HeadID": 5, "FullName": "Marcus Orbison", "Position": "Travel Coordinator", "City": "Los Angeles", "State": "California", "Email": "marcuso@dx-email.com", "Skype": "marcuso_DX_skype", "MobilePhone": "(213) 555-7098", "BirthDate": "1982-03-02", "HireDate": "2005-05-19" }, { "ID": 27, "HeadID": 5, "FullName": "Sandy Bright", "Position": "Benefits Coordinator", "City": "Denver", "State": "Colorado", "Email": "sandrab@dx-email.com", "Skype": "sandrab_DX_skype", "MobilePhone": "(818) 555-0524", "BirthDate": "1983-09-11", "HireDate": "2005-06-04" }, { "ID": 28, "HeadID": 6, "FullName": "Morgan Kennedy", "Position": "Graphic Designer", "City": "San Fernando Valley", "State": "California", "Email": "morgank@dx-email.com", "Skype": "morgank_DX_skype", "MobilePhone": "(818) 555-8238", "BirthDate": "1984-07-17", "HireDate": "2012-01-11" }, { "ID": 29, "HeadID": 28, "FullName": "Violet Bailey", "Position": "Jr Graphic Designer", "City": "La Canada", "State": "California", "Email": "violetb@dx-email.com", "Skype": "violetb_DX_skype", "MobilePhone": "(818) 555-2478", "BirthDate": "1985-06-10", "HireDate": "2012-01-19" }, { "ID": 30, "HeadID": 5, "FullName": "Ken Samuelson", "Position": "Ombudsman", "City": "St. Louis", "State": "Missouri", "Email": "kents@dx-email.com", "Skype": "kents_DX_skype", "MobilePhone": "(562) 555-9282", "BirthDate": "1972-09-11", "HireDate": "2009-04-22" }];
If you run this code, a TreeList is created with a column for each data field. All the columns have equal widths and the same order as their data fields.
Expand Rows
You can use the expandedRowKeys property to expand individual rows. Alternatively, you can enable the autoExpandAll property to expand all rows, as shown in the following code:
jQuery
$(function() { $("#treeList").dxTreeList({ // ... autoExpandAll: true }); });
Angular
<dx-tree-list ... [autoExpandAll]="true"> <!-- ... --> </dx-tree-list>
Vue
<template> <div id="app-container"> <DxTreeList ... :auto-expand-all="true"> <!-- ... --> </DxTreeList> </div> </template> <script> // ... </script>
React
// ... function App() { return ( <div className="App"> <TreeList ... autoExpandAll={true}> {/* ... */} </TreeList> </div> ); } export default App;
Reorder Columns
To reorder columns, change their order in the columns array. Users can also reorder columns if you enable the allowColumnReordering property.
jQuery
$(function() { $("#treeList").dxTreeList({ // ... columns: [ "FullName", "Position", { dataField: "BirthDate", dataType: "date", }, { dataField: "HireDate", dataType: "date", }, "City", "State", "Email", "MobilePhone", "Skype"], allowColumnReordering: true }); });
Angular
<dx-tree-list ... [allowColumnReordering]="true"> <dxi-column dataField="FullName"></dxi-column> <dxi-column dataField="Position"></dxi-column> <dxi-column dataField="BirthDate" dataType="date"> </dxi-column> <dxi-column dataField="HireDate" dataType="date"> </dxi-column> <dxi-column dataField="City"></dxi-column> <dxi-column dataField="State"></dxi-column> <dxi-column dataField="Email"></dxi-column> <dxi-column dataField="MobilePhone"></dxi-column> <dxi-column dataField="Skype"></dxi-column> </dx-tree-list>
Vue
<template> <div id="app-container"> <DxTreeList ... :allow-column-reordering="true"> <DxColumn data-field="FullName"" /> <DxColumn data-field="Position" /> <DxColumn data-field="BirthDate" data-type="date"> </DxColumn> <DxColumn data-field="HireDate" data-type="date"> </DxColumn> <DxColumn data-field="City" /> <DxColumn data-field="State" /> <DxColumn data-field="Email" /> <DxColumn data-field="MobilePhone" /> <DxColumn data-field="Skype" /> </DxTreeList> </div> </template> <script> // ... import { DxTreeList, DxColumn } from 'devextreme-vue/tree-list'; export default { components: { DxTreeList, DxColumn }, // ... } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TreeList, Column } from 'devextreme-react/tree-list'; function App() { return ( <div className="App"> <TreeList ... allowColumnReordering={true}> <Column dataField="FullName" /> <Column dataField="Position" /> <Column dataField="BirthDate" dataType="date"> </Column> <Column dataField="HireDate" dataType="date"> </Column> <Column dataField="City" /> <Column dataField="State" /> <Column dataField="Email" /> <Column dataField="MobilePhone" /> <Column dataField="Skype" /> </TreeList> </div> ); } export default App;
In the code above, we also specify the "date" dataType for the BirthDate
and HireDate
columns because BirthDate
and HireDate
are stored as strings, but you want the TreeList to treat them as date-time values.
Resize Columns
TreeList columns have equal widths (the default setting). You can set each column's width or indicate that all columns should adjust their widths to their content (columnAutoWidth). Users can resize columns if you enable the allowColumnResizing property.
jQuery
$(function() { $("#treeList").dxTreeList({ // ... columns: [ // ... { dataField: "BirthDate", dataType: "date", width: 100, }, { dataField: "HireDate", dataType: "date", width: 100, }, // ... ], allowColumnResizing: true, columnAutoWidth: true, }); });
Angular
<dx-tree-list ... [allowColumnResizing]="true" [columnAutoWidth]="true"> <!-- ... --> <dxi-column dataField="BirthDate" dataType="date" [width]="100"> </dxi-column> <dxi-column dataField="HireDate" dataType="date" [width]="100"> </dxi-column> <!-- ... --> </dx-tree-list>
Vue
<template> <div id="app-container"> <DxTreeList ... :allow-column-resizing="true" :column-auto-width="true"> <!-- ... --> <DxColumn data-field="BirthDate" data-type="date" :width="100"> </DxColumn> <DxColumn data-field="HireDate" data-type="date" :width="100"> </DxColumn> <!-- ... --> </DxTreeList> </div> </template> <script> import { DxTreeList, DxColumn } from 'devextreme-vue/tree-list'; export default { components: { DxTreeList, DxColumn }, // ... } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TreeList, Column } from 'devextreme-react/tree-list'; function App() { return ( <div className="App"> <TreeList ... columnAutoWidth={true} allowColumnResizing={true}> {/* ... */} <Column dataField="BirthDate" dataType="date" width={100}> </Column> <Column dataField="HireDate" dataType="date" width={100}> </Column> {/* ... */} </TreeList> </div> ); } export default App;
Fix Columns
When the width of all columns exceeds the UI component's width, users can scroll the TreeList horizontally. If you set the columnFixing.enabled property to true, users can use a column header's context menu to show certain columns in the view regardless of how far they scroll the TreeList.
You can also enable a column's fixed property in code. This fixes the column to the UI component's left edge. To change the position, set the fixedPosition property.
The following code fixes the FullName
column to the default position and allows users to fix and unfix columns at runtime:
jQuery
$(function() { $("#treeList").dxTreeList({ // ... columnFixing: { enabled: true }, columns: [{ dataField: "FullName", fixed: true }, // ... ], // ... }); });
Angular
<dx-tree-list ... > <dxi-column dataField="FullName" [fixed]="true"> </dxi-column> <!-- ... --> <dxo-column-fixing [enabled]="true"></dxo-column-fixing> </dx-tree-list>
Vue
<template> <div id="app-container"> <DxTreeList ... > <DxColumn data-field="FullName" :fixed="true"> </DxColumn> <!-- ... --> <DxColumnFixing :enabled="true" /> </DxTreeList> </div> </template> <script> import { DxTreeList, DxColumn, DxColumnFixing } from 'devextreme-vue/tree-list'; export default { components: { DxTreeList, DxColumn, DxColumnFixing }, // ... } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TreeList, Column, ColumnFixing } from 'devextreme-react/tree-list'; function App() { return ( <div className="App"> <TreeList ... > {/* ... */} <Column dataField="FullName" fixed={true}> </Column> {/* ... */} <ColumnFixing enabled={true} /> </TreeList> </div> ); } export default App;
Hide Columns
The TreeList displays all columns from the columns array. To hide a column, set its visible property to false. Hidden columns appear in the columnChooser. Users can restore hidden columns from it. To enable the column chooser, set the columnChooser.enabled property to true. If a column should not be visible in the column chooser, do not declare it in the columns array.
jQuery
$(function() { $("#treeList").dxTreeList({ // ... columns: [ // ... { dataField: "Email", visible: false }], columnChooser: { enabled: true }, }); });
Angular
<dx-tree-list ... > <!-- ... --> <dxi-column dataField="Email" [visible]="false"></dxi-column> <dxo-column-chooser [enabled]="true"></dxo-column-chooser> </dx-tree-list>
Vue
<template> <div id="app-container"> <DxTreeList ... > <!-- ... --> <DxColumn data-field="Email" :visible="false" /> <DxColumnChooser :enabled="true" /> </DxTreeList> </div> </template> <script> import { DxTreeList, DxColumn, DxColumnChooser } from 'devextreme-vue/tree-list'; export default { components: { DxTreeList, DxColumn, DxColumnChooser }, // ... } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TreeList, Column, ColumnChooser } from 'devextreme-react/tree-list'; function App() { return ( <div className="App"> <TreeList ... > {/* ... */} <Column dataField="Email" visible={false} /> <ColumnChooser enabled={true} /> </TreeList> </div> ); } export default App;
Sort Data
The sorting.mode property specifies whether users can sort records by single or multiple columns. This tutorial uses the default sorting mode - single.
You can also set a column's sortOrder and sortIndex properties to specify the initial sort settings. sortIndex applies only in multiple sorting mode.
jQuery
$(function() { $("#treeList").dxTreeList({ // ... columns: [{ dataField: "State", sortOrder: "asc", }, // ... ], // sorting: { mode: "single" }, }); });
Angular
<dx-tree-list ... > <!-- ... --> <dxi-column dataField="State" sortOrder="asc"> </dxi-column> <!-- <dxo-sorting [mode]="single"></dxo-sorting> --> </dx-tree-list>
Vue
<template> <div id="app-container"> <DxTreeList ... > <!-- ... --> <DxColumn data-field="State" sort-order="asc"> </DxColumn> <!-- <DxSorting mode="single" /> --> </DxTreeList> </div> </template> <script> import { DxTreeList, DxColumn, // ... // DxSorting } from 'devextreme-vue/tree-list'; export default { components: { DxTreeList, DxColumn, // ... // DxSorting }, // ... } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TreeList, Column, // ... // Sorting } from 'devextreme-react/tree-list'; function App() { return ( <div className="App"> <TreeList ... > {/* ... */} <Column dataField="State" sortOrder="asc"> </Column> {/* <Sorting mode="single" /> */} </TreeList> </div> ); } export default App;
Filter and Search Data
The TreeList includes the following UI elements used to filter and search data:
In this tutorial, the filterRow and searchPanel are displayed:
jQuery
$(function() { $("#treeList").dxTreeList({ // ... filterRow: { visible: true }, searchPanel: { visible: true }, }); });
Angular
<dx-tree-list ... > <!-- ... --> <dxo-filter-row [visible]="true"></dxo-filter-row> <dxo-search-panel [visible]="true"></dxo-search-panel> </dx-tree-list>
Vue
<template> <div id="app-container"> <DxTreeList ... > <!-- ... --> <DxFilterRow :visible="true" /> <DxSearchPanel :visible="true" /> </DxTreeList> </div> </template> <script> import { DxTreeList, // ... DxFilterRow, DxSearchPanel } from 'devextreme-vue/tree-list'; export default { components: { DxTreeList, // ... DxFilterRow, DxSearchPanel }, // ... } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TreeList, // ... FilterRow, SearchPanel } from 'devextreme-react/tree-list'; function App() { return ( <div className="App"> <TreeList ... > {/* ... */} <FilterRow visible={true} /> <SearchPanel visible={true} /> </TreeList> </div> ); } export default App;
Run the code and enter a value in a filter row cell or the search panel. Data is filtered according to this value.
Edit and Validate Data
Users can add, update, and delete records. To allow these operations, enable the allowAdding, allowUpdating, and allowDeleting properties in the editing object. Multiple edit modes are available. This tutorial uses the pop-up edit mode.
DevExtreme includes a validation engine that checks edited values before they are saved. This engine supports different validation rule types, such as Email, Compare, Range, and more. Validation rules are specified per column; one column can use multiple rules. The code below assigns the Required rule to several columns.
jQuery
$(function() { $("#treeList").dxTreeList({ editing: { mode: "popup", allowUpdating: true, allowDeleting: true, allowAdding: true }, columns: [{ dataField: "FullName", validationRules: [{ type: "required" }] }, { dataField: "Position", validationRules: [{ type: "required" }] }, { dataField: "BirthDate", // ... validationRules: [{ type: "required" }] }, { dataField: "HireDate", // ... validationRules: [{ type: "required" }] }, // ... { dataField: "State", // ... validationRules: [{ type: "required" }], } // ... ); });
Angular
<dx-tree-list ... > <!-- ... --> <dxi-column dataField="FullName"> <dxi-validation-rule type="required"></dxi-validation-rule> </dxi-column> <dxi-column dataField="Position"> <dxi-validation-rule type="required"></dxi-validation-rule> </dxi-column> <dxi-column ... dataField="BirthDate"> <dxi-validation-rule type="required"></dxi-validation-rule> </dxi-column> <dxi-column ... dataField="HireDate"> <dxi-validation-rule type="required"></dxi-validation-rule> </dxi-column> <dxi-column ... dataField="State"> <dxi-validation-rule type="required"></dxi-validation-rule> </dxi-column> <dxo-editing mode="popup" [allowUpdating]="true" [allowDeleting]="true" [allowAdding]="true"> </dxo-editing> </dx-tree-list>
Vue
<template> <div id="app-container"> <DxTreeList ... > <!-- ... --> <DxColumn data-field="FullName"> <DxRequiredRule /> </DxColumn> <DxColumn data-field="Position"> <DxRequiredRule /> </DxColumn> <DxColumn ... data-field="BirthDate"> <DxRequiredRule /> </DxColumn> <DxColumn ... data-field="HireDate"> <DxRequiredRule /> </DxColumn> <!-- ... --> <DxColumn ... data-field="State"> <DxRequiredRule /> </DxColumn> <DxEditing mode="popup" :allow-updating="true" :allow-adding="true" :allow-deleting="true" /> </DxTreeList> </div> </template> <script> import { DxTreeList, DxColumn, // ... DxRequiredRule, DxEditing } from 'devextreme-vue/tree-list'; export default { components: { DxTreeList, DxColumn, // ... DxRequiredRule, DxEditing }, // ... } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { TreeList, Column, // ... RequiredRule, Editing } from 'devextreme-react/tree-list'; function App() { return ( <div className="App"> <TreeList ... > {/* ... */} <Column dataField="FullName"> <RequiredRule /> </Column> <Column dataField="Position"> <RequiredRule /> </Column> {/* ... */} <Column ... dataField="HireDate"> <RequiredRule /> </Column> {/* ... */} <Column ... dataField="State"> <RequiredRule /> </Column> <Editing mode="popup" allowUpdating={true} allowDeleting={true} allowAdding={true} /> </TreeList> </div> ); } export default App;
Run the code and click the Edit button in any row. This invokes a pop-up window that contains an edit form. When you clear the Full Name text box on this form, the following validation error is shown: "Full Name is required".
Select Records
The TreeList supports single and multiple record selection modes. Use the selection.mode property to specify the mode.
You can obtain the selected record's data in the onSelectionChanged function. In the code below, this function displays the selected employee under the TreeList:
jQuery
$(function() { $("#treeList").dxTreeList({ // ... selection: { mode: "single" }, onSelectionChanged: function(e) { e.component.byKey(e.currentSelectedRowKeys[0]).done(employee => { if(employee) { $("#selected-employee").text(`Selected employee: ${employee.FullName}`); } }); }, }); });
<html> <!-- ... --> <body class="dx-viewport"> <div id="app-container"> <div id="treeList"></div> <p id="selected-employee"></p> </div> </body> </html>
/* ... */ #app-container { width: 900px; position: relative; } #selected-employee { position: absolute; left: 50%; transform: translate(-50%, 0); }
Angular
<div id="app-container"> <dx-tree-list ... (onSelectionChanged)="selectEmployee($event)"> <!-- ... --> <dxo-selection mode="single"></dxo-selection> </dx-tree-list> <p id="selected-employee" *ngIf="selectedEmployee"> Selected employee: {{ selectedEmployee.FullName }} </p> </div>
import { Component } from '@angular/core'; import { Employee, EmployeesService } from './employees.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { // ... selectedEmployee: Employee; constructor(service: EmployeesService) { // ... this.selectEmployee = this.selectEmployee.bind(this); } selectEmployee(e) { e.component.byKey(e.currentSelectedRowKeys[0]).done(employee => { if(employee) { this.selectedEmployee = employee; } }); } }
/* ... */ #app-container { width: 900px; position: relative; } #selected-employee { position: absolute; left: 50%; transform: translate(-50%, 0); }
Vue
<template> <div id="app-container"> <DxTreeList ... @selection-changed="selectEmployee"> <!-- ... --> <DxSelection mode="single" /> </DxTreeList> <p id="selected-employee" v-if="selectedEmployee"> Selected employee: {{ selectedEmployee.FullName }} </p> </div> </template> <script> import { DxTreeList, // ... DxSelection } from 'devextreme-vue/tree-list'; export default { components: { DxTreeList, // ... DxSelection }, data() { return { // ... selectedEmployee: undefined, } }, methods: { selectEmployee(e) { e.component.byKey(e.currentSelectedRowKeys[0]).done(employee => { if(employee) { this.selectedEmployee = employee; } }); } } } </script> <style> /* ... */ #app-container { width: 900px; position: relative; } #selected-employee { position: absolute; left: 50%; transform: translate(-50%, 0); } </style>
React
import React, { useCallback, useState } from 'react'; import 'devextreme/dist/css/dx.light.css'; import './App.css'; import { TreeList, Column, // ... Selection } from 'devextreme-react/tree-list'; function SelectedEmployee(props) { if(props.employee) { return ( <p id="selected-employee"> Selected employee: {props.employee.FullName} </p> ); } return null; } function App() { const [selectedEmployee, setSelectedEmployee] = useState(); const selectEmployee = useCallback((e) => { e.component.byKey(e.currentSelectedRowKeys[0]).done(employee => { setSelectedEmployee(employee); }); }, []); return ( <div className="App"> <TreeList ... onSelectionChanged={selectEmployee}> {/* ... */} <Selection mode="single" /> </TreeList> <SelectedEmployee employee={selectedEmployee} /> </div> ); } export default App;
/* ... */ .App { width: 900px; position: relative; } #selected-employee { position: absolute; left: 50%; transform: translate(-50%, 0); }
Customize the Toolbar
The TreeList includes an integrated toolbar that displays predefined and custom controls. To add or remove toolbar items, declare the toolbar.items[] array. Toolbar items within the UI preserve the order in which they are declared.
This tutorial illustrates how to add the following items to the toolbar:
Predefined controls
Declare a toolbar item element and specify the name and properties that you want to customize (see the "addRowButton" configuration in the code below). If a control does not need customization, include its name only. Ensure that items[] contain controls for all features that you enabled in your TreeList.DevExtreme components
Configure a DevExtreme component within a toolbar item element. In this tutorial, we extended the toolbar's item collection with a custom Button that expands or collapses all grid records.
jQuery
$(function() { const treeList = $("#treeList").dxTreeList({ // ... toolbar: { items: [ { location: "after", widget: "dxButton", options: { text: "Collapse All", width: 136, onClick(e) { const expanding = e.component.option("text") === "Expand All"; treeList.option({ autoExpandAll: expanding, expandedRowKeys: [] }); e.component.option("text", expanding ? "Collapse All" : "Expand All"); }, }, }, { name: "addRowButton", showText: "always" }, "exportButton", "columnChooserButton", "searchPanel" ] }, }).dxTreeList("instance"); });
Angular
<div id="app-container"> <dx-tree-list ... [autoExpandAll]="expanded" [(expandedRowKeys)]="expandedRowKeys"> <!-- ... --> <dxo-toolbar> <dxi-item location="after"> <dx-button [text]="expanded ? 'Collapse All' : 'Expand All'" [width]="136" (onClick)="expanded = !expanded; expandedRowKeys = []"> </dx-button> </dxi-item> <dxi-item name="addRowButton" showText="always"></dxi-item> <dxi-item name="exportButton"></dxi-item> <dxi-item name="columnChooserButton"></dxi-item> <dxi-item name="searchPanel"></dxi-item> </dxo-toolbar> </dx-tree-list> </div>
// ... @Component({ // ... }) export class AppComponent { // ... expanded: Boolean = true; expandedRowKeys: Number[] = []; }
Vue
<template> <div id="app-container"> <DxTreeList ... :auto-expand-all="expanded" :expanded-row-keys="expandedRowKeys"> <!-- ... --> <DxToolbar> <DxItem location="after" template="button-template" /> <DxItem name="addRowButton" show-text="always" /> <DxItem name="exportButton" /> <DxItem name="columnChooserButton" /> <DxItem name="searchPanel" /> </DxToolbar> <template #button-template> <DxButton :text="expanded ? 'Collapse All' : 'Expand All'" :width="136" @click="expanded = !expanded; expandedRowKeys = []" /> </template> </DxTreeList> </div> </template> <script> import { DxTreeList, // ... DxToolbar, DxItem, } from 'devextreme-vue/tree-list'; import { DxButton } from 'devextreme-vue/button'; export default { components: { DxTreeList, // ... DxToolbar, DxItem, DxButton }, data() { return { // ... expanded: true, expandedRowKeys: [] } }, // ... } </script> <style> /* ... */ </style>
React
import React, { useCallback, useState } from 'react'; import 'devextreme/dist/css/dx.light.css'; import './App.css'; import { TreeList, // ... Toolbar, Item, } from 'devextreme-react/tree-list'; import { Button } from 'devextreme-react/button'; // ... function App() { // ... const [expanded, setExpanded] = useState(true); const [expandedRowKeys, setExpandedRowKeys] = useState([]); const onOptionChanged = useCallback((e) => { if(e.name === 'expandedRowKeys') { setExpandedRowKeys(e.value); } }, []); return ( <div className="App"> <TreeList ... autoExpandAll={expanded} expandedRowKeys={expandedRowKeys} onOptionChanged={onOptionChanged}> {/* ... */} <Toolbar> <Item location="after"> <Button text={expanded ? 'Collapse All' : 'Expand All'} width={136} onClick={() => { setExpanded(prevExpanded => !prevExpanded) setExpandedRowKeys([]); }} /> </Item> <Item name="addRowButton" showText="always" /> <Item name="exportButton" /> <Item name="columnChooserButton" /> <Item name="searchPanel" /> </Toolbar> </TreeList> </div> ); } export default App;
Enable Row Drag & Drop
Users can drag and drop nodes to reorder them or change their hierarchy. To configure these features, enable the allowReordering and allowDropInsideItem properties of the rowDragging object and implement the onDragChange and onReorder functions as shown below. For detailed instructions, refer to the Node Drag & Drop demo.
jQuery
$(function() { const treeList = $("#treeList").dxTreeList({ // ... rowDragging: { allowDropInsideItem: true, allowReordering: true, onDragChange: function(e) { var visibleRows = treeList.getVisibleRows(), sourceNode = treeList.getNodeByKey(e.itemData.ID), targetNode = visibleRows[e.toIndex].node; while (targetNode && targetNode.data) { if (targetNode.data.ID === sourceNode.data.ID) { e.cancel = true; break; } targetNode = targetNode.parent; } }, onReorder: function(e) { var visibleRows = e.component.getVisibleRows(), sourceData = e.itemData, targetData = visibleRows[e.toIndex].data; if (e.dropInsideItem) { e.itemData.HeadID = targetData.ID; } else { var sourceIndex = employees.indexOf(sourceData), targetIndex = employees.indexOf(targetData); if (sourceData.HeadID !== targetData.HeadID) { sourceData.HeadID = targetData.HeadID; if (e.toIndex > e.fromIndex) { targetIndex++; } } employees.splice(sourceIndex, 1); employees.splice(targetIndex, 0, sourceData); } e.component.refresh(); } }, }).dxTreeList("instance"); });
Angular
<div id="app-container"> <dx-tree-list ... <!-- ... --> <dxo-row-dragging [onDragChange]="onDragChange" [onReorder]="onReorder" [allowDropInsideItem]="true" [allowReordering]="true" ></dxo-row-dragging> </dx-tree-list> </div>
// ... @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { // ... selectedEmployee: Employee; constructor(service: EmployeesService) { this.employees = service.getEmployees(); // ... this.onReorder = this.onReorder.bind(this); } onDragChange(e) { let visibleRows = e.component.getVisibleRows(), sourceNode = e.component.getNodeByKey(e.itemData.ID), targetNode = visibleRows[e.toIndex].node; while(targetNode && targetNode.data) { if (targetNode.data.ID === sourceNode.data.ID) { e.cancel = true; break; } targetNode = targetNode.parent; } } onReorder(e) { let visibleRows = e.component.getVisibleRows(), sourceData = e.itemData, targetData = visibleRows[e.toIndex].data; if (e.dropInsideItem) { e.itemData.HeadID = targetData.ID; e.component.refresh(); } else { let sourceIndex = this.employees.indexOf(sourceData), targetIndex = this.employees.indexOf(targetData); if (sourceData.HeadID !== targetData.HeadID) { sourceData.HeadID = targetData.HeadID; if (e.toIndex > e.fromIndex) { targetIndex++; } } this.employees.splice(sourceIndex, 1); this.employees.splice(targetIndex, 0, sourceData); } } }
Vue
<template> <div id="app-container"> <DxTreeList ... > <!-- ... --> <DxRowDragging :on-drag-change="onDragChange" :on-reorder="onReorder" :allow-drop-inside-item="true" :allow-reordering="true" /> </DxTreeList> </div> </template> <script> import { DxTreeList, // ... DxRowDragging } from 'devextreme-vue/tree-list'; export default { components: { // ... DxRowDragging }, data() { return { employees: service.getEmployees(), // ... } }, methods: { // ... onDragChange(e) { let visibleRows = e.component.getVisibleRows(), sourceNode = e.component.getNodeByKey(e.itemData.ID), targetNode = visibleRows[e.toIndex].node; while (targetNode && targetNode.data) { if (targetNode.data.ID === sourceNode.data.ID) { e.cancel = true; break; } targetNode = targetNode.parent; } }, onReorder(e) { let visibleRows = e.component.getVisibleRows(), sourceData = e.itemData, targetData = visibleRows[e.toIndex].data; if (e.dropInsideItem) { e.itemData.HeadID = targetData.ID; e.component.refresh(); } else { let sourceIndex = this.employees.indexOf(sourceData), targetIndex = this.employees.indexOf(targetData); if (sourceData.HeadID !== targetData.HeadID) { sourceData.HeadID = targetData.HeadID; if (e.toIndex > e.fromIndex) { targetIndex++; } } this.employees.splice(sourceIndex, 1); this.employees.splice(targetIndex, 0, sourceData); this.employees = this.employees.slice(); } } } } </script> // ...
React
import React, { useCallback, useState } from 'react'; import 'devextreme/dist/css/dx.light.css'; import './App.css'; import { // ... RowDragging } from 'devextreme-react/tree-list'; // ... function App() { // ... const [currentEmployees, setCurrentEmployees] = useState(employees); // ... const onDragChange = useCallback((e) => { let visibleRows = e.component.getVisibleRows(), sourceNode = e.component.getNodeByKey(e.itemData.ID), targetNode = visibleRows[e.toIndex].node; while (targetNode && targetNode.data) { if (targetNode.data.ID === sourceNode.data.ID) { e.cancel = true; break; } targetNode = targetNode.parent; } }, []); const onReorder = useCallback((e) => { let visibleRows = e.component.getVisibleRows(), sourceData = e.itemData, targetData = visibleRows[e.toIndex].data, employeesReordered = currentEmployees, sourceIndex = employeesReordered.indexOf(sourceData), targetIndex = employeesReordered.indexOf(targetData); if (e.dropInsideItem) { sourceData = { ...sourceData, HeadID: targetData.ID }; employeesReordered = [...employeesReordered.slice(0, sourceIndex), sourceData, ...employeesReordered.slice(sourceIndex + 1)]; } else { if (sourceData.HeadID !== targetData.HeadID) { sourceData = { ...sourceData, HeadID: targetData.HeadID }; if (e.toIndex > e.fromIndex) { targetIndex++; } } employeesReordered = [...employeesReordered.slice(0, sourceIndex), ...employeesReordered.slice(sourceIndex + 1)]; employeesReordered = [...employeesReordered.slice(0, targetIndex), sourceData, ...employeesReordered.slice(targetIndex)]; } setCurrentEmployees(employeesReordered); }, []); return ( <div className="App"> <TreeList ... > {/* ... */} <RowDragging onDragChange={onDragChange} onReorder={onReorder} allowDropInsideItem={true} allowReordering={true} /> </TreeList> <SelectedEmployee employee={selectedEmployee} /> </div> ); } export default App;
Enable Pagination
When pagination is enabled, TreeList loads records page by page instead of loading them all at once. To configure pagination, set the paging.enabled property to true and use the paging.pageSize property to specify the optimal number of records per page. Use this feature if your tests show noticeable lags without it.
jQuery
$(function() { $("#treeList").dxTreeList({ // ... paging: { enabled: true, pageSize: 10 } }); });
Angular
<dx-tree-list ... > <!-- ... --> <dxo-paging [enabled]="true" [pageSize]="10"> </dxo-paging> </dx-tree-list>
Vue
<template> <div id="app-container"> <DxTreeList ... > <!-- ... --> <DxPaging :enabled="true" :page-size="10" /> </DxTreeList> </div> </template> <script> import { // ... DxPaging } from 'devextreme-vue/tree-list'; export default { components: { // ... DxPaging }, // ... } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.light.css'; import { // ... Paging } from 'devextreme-react/tree-list'; function App() { return ( <div className="App"> <TreeList ... > {/* ... */} <Paging enabled={true} defaultPageSize={10} /> </TreeList> </div> ); } export default App;
For further information on the TreeList component, refer to the following resources: