JavaScript/jQuery TreeView - Expand and Collapse Nodes

Initially

If a node is supposed to be expanded initially, set its expanded field to true. If another field specifies whether a node is expanded or collapsed, assign its name to the expandedExpr property as shown in the following code.

jQuery
JavaScript
var hierarchicalData = [{
    name: 'Fruits',
    isExpanded: true,
    items: [
        { name: 'Apples' },
        { name: 'Oranges' }
    ]
}, {
    name: 'Vegetables',
    isExpanded: true,
    items: [
        { name: 'Cucumbers' },
        { name: 'Tomatoes' }
    ]
}];

$(function() {
    $("#treeViewContainer").dxTreeView({
        dataSource: hierarchicalData,
        keyExpr: 'name',
        displayExpr: 'name',
        expandedExpr: 'isExpanded'
    });
});
Angular
HTML
TypeScript
<dx-tree-view
    [dataSource]="hierarchicalData"
    keyExpr="name"
    displayExpr="name"
    expandedExpr="isExpanded">
</dx-tree-view>
import { DxTreeViewModule } from "devextreme-angular";
// ...
export class AppComponent {
    hierarchicalData = [{
        name: 'Fruits',
        isExpanded: true,
        items: [
            { name: 'Apples' },
            { name: 'Oranges' }
        ]
    }, {
        name: 'Vegetables',
        isExpanded: true,
        items: [
            { name: 'Cucumbers' },
            { name: 'Tomatoes' }
        ]
    }];
}
@NgModule({
    imports: [
        // ...
        DxTreeViewModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxTreeView
        key-expr="key"
        display-expr="name"
        expanded-expr="isExpanded"
        :items="hierarchicalData" 
    />
</template>
<script>
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.css';

import { DxTreeView } from 'devextreme-vue/tree-view';

const hierarchicalData = [{
    key: '1',
    name: 'Fruits',
    isExpanded: true,
    items: [
        { key: '1_1', name: 'Apples' },
        { key: '1_2', name: 'Oranges' }
    ]
}, {
    key: '2',
    name: 'Vegetables',
    isExpanded: true,
    items: [
        { key: '2_1', name: 'Cucumbers' },
        { key: '2_2', name: 'Tomatoes' }
    ]
}];

export default {
    components: {
        DxTreeView
    },
    data() {
        return {
            hierarchicalData
        };
    },
};
</script>
React
App.js
import React from 'react';

import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.css';

import TreeView from 'devextreme-react/tree-view';

const hierarchicalData = [{
    key: '1',
    name: 'Fruits',
    isExpanded: true,
    items: [
        { key: '1_1', name: 'Apples' },
        { key: '1_2', name: 'Oranges' }
    ]
}, {
    key: '2',
    name: 'Vegetables',
    isExpanded: true,
    items: [
        { key: '2_1', name: 'Cucumbers' },
        { key: '2_2', name: 'Tomatoes' }
    ]
}];

class App extends React.Component {
    render() {
        return (
            <TreeView
                keyExpr="key"
                displayExpr="name"
                expandedExpr="isExpanded"
                items={hierarchicalData} />
        );
    }
}

export default App;

Using the API

The TreeView provides the following API to expand and collapse nodes:

  • All nodes
    You can use the expandAll() and collapseAll() methods to expand and collapse nodes at once. Note that the expandAll() method expands only the loaded nodes if data is loaded on demand.

    jQuery
    JavaScript
    $("#treeViewContainer").dxTreeView("expandAll");
    // $("#treeViewContainer").dxTreeView("collapseAll");
    Angular
    TypeScript
    import { ..., ViewChild } from "@angular/core";
    import { DxTreeViewModule, DxTreeViewComponent } from "devextreme-angular";
    // ...
    export class AppComponent {
        @ViewChild(DxTreeViewComponent, { static: false }) treeView: DxTreeViewComponent;
        // Prior to Angular 8
        // @ViewChild(DxTreeViewComponent) treeView: DxTreeViewComponent;
        expandAllNodes () {
            this.treeView.instance.expandAll();
        }
        collapseAllNodes () {
            this.treeView.instance.collapseAll();
        }
    }
    @NgModule({
        imports: [
            // ...
            DxTreeViewModule
        ],
        // ...
    })
    Vue
    App.vue
    <template>
        <DxTreeView
            :ref="treeViewRef"
            :items="data" 
        />
    </template>
    <script>
    import 'devextreme/dist/css/dx.common.css';
    import 'devextreme/dist/css/dx.light.css';
    
    import { DxTreeView } from 'devextreme-vue/tree-view';
    
    const treeViewRef = 'treeView';
    const data = [ ... ];
    
    export default {
        components: {
            DxTreeView
        },
        data() {
            return {
                data,
                treeViewRef
            };
        },
        computed: {
            treeView: function() {
                return this.$refs[treeViewRef].instance;
            }
        },   
        methods: {
            expandAllNodes() {
                this.treeView.expandAll();
            },
            collapseAllNodes() {
                this.treeView.collapseAll();
            } 
        }
    };
    </script>
    React
    App.js
    import React from 'react';
    
    import 'devextreme/dist/css/dx.common.css';
    import 'devextreme/dist/css/dx.light.css';
    
    import TreeView from 'devextreme-react/tree-view';
    
    const data = [ ... ];
    
    class App extends React.Component {
        constructor() {
            super();
            this.treeViewRef = React.createRef();
            this.expandAllNodes = this.expandAllNodes.bind(this);
            this.collapseAllNodes = this.collapseAllNodes.bind(this);                
        }
        render() {
            return (
                <TreeView
                    items={data}
                    ref={this.treeViewRef} />
            );
        }
        expandAllNodes() {
            this.treeView.expandAll();
        }
        collapseAllNodes() {
            this.treeView.collapseAll();
        }
        get treeView() {
            return this.treeViewRef.current.instance;
        }    
    }
    
    export default App;
  • Individual nodes
    Call the expandItem(key) or collapseItem(key) method and pass a node key as an argument:

    jQuery
    JavaScript
    $("#treeViewContainer").dxTreeView("expandItem", nodeKey);
    // $("#treeViewContainer").dxTreeView("collapseItem", nodeKey);
    Angular
    TypeScript
    import { ..., ViewChild } from "@angular/core";
    import { DxTreeViewModule, DxTreeViewComponent } from "devextreme-angular";
    // ...
    export class AppComponent {
        @ViewChild(DxTreeViewComponent, { static: false }) treeView: DxTreeViewComponent;
        // Prior to Angular 8
        // @ViewChild(DxTreeViewComponent) treeView: DxTreeViewComponent;
        expandNode (key) {
            this.treeView.instance.expandItem(key);
        }
        collapseNode (key) {
            this.treeView.instance.collapseItem(key);
        }
    }
    @NgModule({
        imports: [
            // ...
            DxTreeViewModule
        ],
        // ...
    })
    Vue
    App.vue
    <template>
        <DxTreeView
            :ref="treeViewRef"
            :items="data" 
        />
    </template>
    <script>
    import 'devextreme/dist/css/dx.common.css';
    import 'devextreme/dist/css/dx.light.css';
    
    import { DxTreeView } from 'devextreme-vue/tree-view';
    
    const treeViewRef = 'treeView';
    const data = [ ... ];
    
    export default {
        components: {
            DxTreeView
        },
        data() {
            return {
                data,
                treeViewRef
            };
        },
        computed: {
            treeView: function() {
                return this.$refs[treeViewRef].instance;
            }
        },   
        methods: {
            expandNode(key) {
                this.treeView.expandItem(key);
            },
            collapseNode(key) {
                this.treeView.collapseItem(key);
            } 
        }
    };
    </script>
    React
    App.js
    import React from 'react';
    
    import 'devextreme/dist/css/dx.common.css';
    import 'devextreme/dist/css/dx.light.css';
    
    import TreeView from 'devextreme-react/tree-view';
    const data = [ ... ];
    
    class App extends React.Component {
        constructor() {
            super();
            this.treeViewRef = React.createRef();
            this.expandNode = this.expandNode.bind(this);
            this.collapseNode = this.collapseNode.bind(this);
        }
        render() {
            return (
                <TreeView
                    items={data}
                    ref={this.treeViewRef} />
            );
        }
        expandNode(key) {
            this.treeView.expandItem(key);
        }
        collapseNode(key) {
            this.treeView.collapseItem(key);
        }
        get treeView() {
            return this.treeViewRef.current.instance;
        }    
    }
    
    export default App;

Events

To execute certain commands when a node is expanded or collapsed, handle the itemExpanded or itemCollapsed event. Assign event handling functions to the onItemExpanded or onItemCollapsed property when you configure the UI component if these functions are going to remain unchanged.

jQuery
JavaScript
$(function() {
    $("#treeViewContainer").dxTreeView({
        onItemExpanded: function (e) {
            // Handler of the "itemExpanded" event
        },
        onItemCollapsed: function (e) {
            // Handler of the "itemCollapsed" event
        }
    });
});
Angular
HTML
TypeScript
<dx-tree-view ...
    (onItemExpanded)="onItemExpanded($event)"
    (onItemCollapsed)="onItemCollapsed($event)">
</dx-tree-view>
import { DxTreeViewModule } from "devextreme-angular";
// ...
export class AppComponent {
    onItemExpanded (e) {
        // Handler of the "itemExpanded" event
    }
    onItemCollapsed (e) {
        // Handler of the "itemCollapsed" event
    }
}
@NgModule({
    imports: [
        // ...
        DxTreeViewModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxTreeView
        :data-source="data"
        @item-expanded="onItemExpanded"
        @item-collapsed="onItemCollapsed" 
    />
</template>
<script>
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.css';

import { DxTreeView } from 'devextreme-vue/tree-view';

const data = [ ... ];

export default {
    components: {
        DxTreeView
    },
    data() {
        return {
            data
        };
    },
    methods: {
        onItemExpanded(e) {
            // Handler of the 'itemExpanded' event
        }
        onItemCollapsed(e) {
            // Handler of the 'itemCollapsed' event
        }
    }
};
</script>
React
App.js
import React from 'react';

import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.css';

import TreeView from 'devextreme-react/tree-view';

const data = [ ... ];

class App extends React.Component {
    render() {
        return (
            <TreeView
                onItemExpanded={this.onItemExpanded}
                onItemCollapsed={this.onItemCollapsed}
                dataSource={data} />
        );
    }

    onItemExpanded(e) {
        // Handler of the 'itemExpanded' event
    }

    onItemCollapsed(e) {
        // Handler of the 'itemCollapsed' event
    }
}

export default App;

If you are going to change event handlers at runtime, or if you need to attach several handlers to a single event, subscribe to the events using the on(eventName, eventHandler) method. This approach is more typical of jQuery.

JavaScript
var itemCollapsedEventHandler1 = function (e) {
    // First handler of the "itemCollapsed" event
};

var itemCollapsedEventHandler2 = function (e) {
    // Second handler of the "itemCollapsed" event
};

$("#treeViewContainer").dxTreeView("instance")
    .on("itemCollapsed", itemCollapsedEventHandler1)
    .on("itemCollapsed", itemCollapsedEventHandler2);
See Also