Vue TreeList - Adaptability

The TreeList can hide columns and adapt its layout to screens of different sizes. Data from hidden columns is available in adaptive detail rows. A user can click the ellipsis buttons in the adaptive column to expand or collapse these rows:

DevExtreme HTML5 JavaScript jQuery Knockout Angular TreeList Adaptability

Hide Columns

When the total width of columns exceeds component width, the TreeList either truncates column cell text or adds horizontal scrolling. As an alternative, the component can hide one or several columns to prevent horizontal scrolling and display cell text in full. To enable this feature, set the columnHidingEnabled property to true.

Each column has a unique default hiding priority. The rightmost column has the priority of 0. This value is incremented by 1 for columns from right to left; the column with the lowest priority is hidden first.

You can use the columns[].hidingPriority property to specify custom hiding priorities for those columns that you want to hide. Other columns will never be hidden. This will override the default behavior described above. In this case, the columnHidingEnabled property can be omitted.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        columnHidingEnabled: true,
        // These columns will be hidden in the following order:
        columns: [{
            // ...
            hidingPriority: 0 // first
        }, {
            // ...
            hidingPriority: 1 // second 
        }, {
            // ...
            hidingPriority: 2 // third
        }]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... 
    [columnHidingEnabled]="true">
    <!-- These columns will be hidden in the following order: -->
    <dxi-column [hidingPriority]="0" ... ></dxi-column> <!-- first -->
    <dxi-column [hidingPriority]="1" ... ></dxi-column> <!-- second -->
    <dxi-column [hidingPriority]="2" ... ></dxi-column> <!-- third -->
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxTreeList ...
        :column-hiding-enabled="true">
        <!-- These columns will be hidden in the following order: -->
        <DxColumn :hiding-priority="0" ... /> <!-- first -->
        <DxColumn :hiding-priority="1" ... /> <!-- second -->
        <DxColumn :hiding-priority="2" ... /> <!-- third -->
    </DxTreeList>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxTreeList, {
    DxColumn
} from 'devextreme-vue/tree-list';

export default {
    components: {
        DxTreeList,
        DxColumn
    },
    // ...
}
</script>
React
App.js
import React from 'react';

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

import TreeList, {
    Column
} from 'devextreme-react/tree-list';

export default function App() {
    return (
        <TreeList ...
            columnHidingEnabled={true}>
            {/* These columns will be hidden in the following order: */}
            <Column defaultHidingPriority={0} ... /> {/* first */}
            <Column defaultHidingPriority={1} ... /> {/* second */}
            <Column defaultHidingPriority={2} ... /> {/* third */}
        </TreeList>
    );
}

View Demo

NOTE

If your TreeList is inside a resizable container, you must call the updateDimensions() method on each container resize to rerender the component:

jQuery
JavaScript
$("#treeListContainer").dxTreeList("updateDimensions");
Angular
TypeScript
import { ..., ViewChild } from "@angular/core";
import { DxTreeListModule, DxTreeListComponent } from "devextreme-angular";
// ...
export class AppComponent {
    @ViewChild(DxTreeListComponent, { static: false }) treeList: DxTreeListComponent;
    // Prior to Angular 8
    // @ViewChild(DxTreeListComponent) treeList: DxTreeListComponent;
    renderTreeList () {
        this.treeList.instance.updateDimensions();
    };
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxTreeList ...
        :ref="treeListRefKey">
    </DxTreeList>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxTreeList from 'devextreme-vue/tree-list';

const treeListRefKey = "my-tree-list";

export default {
    components: {
        DxTreeList
    },
    data() {
        return() {
            treeListRefKey
        }
    },
    methods: {
        renderTreeList() {
            this.treeList.updateDimensions();
        }
    },
    computed: {
        treeList: function() {
            return this.$refs[treeListRefKey].instance;
        }
    }
}
</script>
React
App.js
import React, { useRef } from 'react';
import 'devextreme/dist/css/dx.light.css';
import TreeList from 'devextreme-react/tree-list';

export default function App() {
    const treeList = useRef(null);
    const renderTreeList = () => {
        treeList.current.instance.updateDimensions();
    };

    return (
        <TreeList ref={treeList}>
            {/* ... */ }
        </TreeList>
    );
}

Customize Adaptive Detail Row

Adaptive detail rows contain the Form UI component. You can implement the onAdaptiveDetailRowPreparing handler to customize the Form: change its properties in the formOptions attribute of the function's argument. For example, the following code marks the form's "OrderID" data field as required:

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        onAdaptiveDetailRowPreparing: function (e) {
            for (let formItem of e.formOptions.items) {
                if (formItem.dataField == "OrderID") {
                    formItem.isRequired = true;
                }
            }
        }
    });
});
Angular
TypeScript
HTML
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    onAdaptiveDetailRowPreparing (e) {
        for (let formItem of e.formOptions.items) {
            if (formItem.dataField == "OrderID") {
                formItem.isRequired = true;
            }
        }
    }
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
<dx-tree-list ...
    (onAdaptiveDetailRowPreparing)="onAdaptiveDetailRowPreparing($event)">
</dx-tree-list>
Vue
App.vue
<template>
    <DxTreeList ...
        :@adaptive-detail-row-preparing="onAdaptiveDetailRowPreparing">
    </DxTreeList>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxTreeList from 'devextreme-vue/tree-list';

export default {
    components: {
        DxTreeList
    },
    methods: {
        onAdaptiveDetailRowPreparing(e) {
            for (let formItem of e.formOptions.items) {
                if (formItem.dataField == 'OrderID') {
                    formItem.isRequired = true;
                }
            }
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import TreeList from 'devextreme-react/tree-list';

const onAdaptiveDetailRowPreparing = (e) => {
    for (let formItem of e.formOptions.items) {
        if (formItem.dataField == 'OrderID') {
            formItem.isRequired = true;
        }
    }
};

export default function App() {
    return (
        <TreeList ... 
            onAdaptiveDetailRowPreparing={onAdaptiveDetailRowPreparing}>
        </TreeList>
    );
}

Expand and Collapse Adaptive Detail Rows

You can call the expandAdaptiveDetailRow(key) or collapseAdaptiveDetailRow() method to expand or collapse an adaptive detail row. To check whether a specific row is expanded, use the isAdaptiveDetailRowExpanded(key) method. Note that only one detail row can be expanded at a time.

jQuery
JavaScript
var expandAdaptiveDetailRow = function (key, treeListInstance) {
    if (!treeListInstance.isAdaptiveDetailRowExpanded(key)) {
        treeListInstance.expandAdaptiveDetailRow(key);
    }
}
Angular
TypeScript
import { ..., ViewChild } from "@angular/core";
import { DxTreeListModule, DxTreeListComponent } from "devextreme-angular";
// ...
export class AppComponent {
    @ViewChild(DxTreeListComponent, { static: false }) treeList: DxTreeListComponent;
    // Prior to Angular 8
    // @ViewChild(DxTreeListComponent) treeList: DxTreeListComponent;
    expandAdaptiveDetailRow (key) {
        if (!this.treeList.instance.isAdaptiveDetailRowExpanded(key)) {
            this.treeList.instance.expandAdaptiveDetailRow(key);
        }
    }
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxTreeList ...
        :ref="treeListRefKey">
    </DxTreeList>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';

import DxTreeList from 'devextreme-vue/tree-list';

const treeListRefKey = "my-tree-list";

export default {
    components: {
        DxTreeList
    },
    data() {
        return() {
            treeListRefKey
        }
    },
    methods: {
        expandAdaptiveDetailRow(key) {
            if (!this.treeList.isAdaptiveDetailRowExpanded(key)) {
                this.treeList.expandAdaptiveDetailRow(key);
            }
        }
    },
    computed: {
        treeList: function() {
            return this.$refs[treeListRefKey].instance;
        }
    }
}
</script>
React
App.js
import React, { useRef } from 'react';
import 'devextreme/dist/css/dx.light.css';
import TreeList from 'devextreme-react/tree-list';

export default function App() {
    const treeList = useRef(null);
    const expandAdaptiveDetailRow = (key) => {
        if (!treeList.current.instance.isAdaptiveDetailRowExpanded(key)) {
            treeList.current.instance.expandAdaptiveDetailRow(key);
        }
    };

    return (
        <TreeList ref={treeList}>
            {/* ... */ }
        </TreeList>
    );
}
See Also