JavaScript/jQuery TreeList - columns

Configures columns.

Default Value: undefined
Raised Events: onOptionChanged

This option accepts an array of objects, where each object configures a single column. If a column does not need to be customized, this array may include the name of the field that provides data for this column.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            dataField: "Title",
            caption: "Position"
        }, {
            dataField: "FullName",
            width: 300
        }, 
            "CompanyName",
            "City"
        ]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxi-column dataField="Title" caption="Position"></dxi-column>
    <dxi-column dataField="FullName" [width]="300"></dxi-column>
    <dxi-column dataField="CompanyName"></dxi-column>
    <dxi-column dataField="City"></dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
See Also

alignment

Aligns the content of the column.

Type:

String

Default Value: undefined
Accepted Values: undefined | 'center' | 'left' | 'right'

The default alignment of the content depends on the type of data.

dataType alignment
'number' 'right'
'boolean' 'center'
'string' 'left'
'date' 'left'
'datetime' 'left'

Use the HorizontalAlignment enum to specify this option when the widget is used as an ASP.NET MVC 5 Control or a DevExtreme-Based ASP.NET Core Control. This enum accepts the following values: Left, Center, and Right.

allowEditing

Specifies whether a user can edit values in the column at runtime. By default, inherits the value of the editing.allowUpdating option.

Type:

Boolean

Default Value: true

NOTE
If values in the column are calculated customarily using the calculateCellValue option, they cannot be edited at runtime.
See Also

allowFiltering

Specifies whether data can be filtered by this column. Applies only if filterRow.visible is true.

Type:

Boolean

Default Value: true

See Also

allowFixing

Specifies whether a user can fix the column at runtime. Applies only if columnFixing.enabled is true.

Type:

Boolean

Default Value: true

See Also

allowHeaderFiltering

Specifies whether the header filter can be used to filter data by this column. Applies only if headerFilter.visible is true. By default, inherits the value of the allowFiltering option.

Type:

Boolean

Default Value: true

allowHiding

Specifies whether a user can hide the column using the column chooser at runtime. Applies only if columnChooser.enabled is true.

Type:

Boolean

Default Value: true

NOTE
Fixed columns ignore the hidingPriority and allowHiding options.
See Also

allowReordering

Specifies whether this column can be used in column reordering at runtime. Applies only if allowColumnReordering is true.

Type:

Boolean

Default Value: true

allowResizing

Specifies whether a user can resize the column at runtime. Applies only if allowColumnResizing is true.

Type:

Boolean

Default Value: true

See Also

allowSearch

Specifies whether this column can be searched. Applies only if searchPanel.visible is true. Inherits the value of the allowFiltering option by default.

Type:

Boolean

Default Value: true

allowSorting

Specifies whether a user can sort rows by this column at runtime. Applies only if sorting.mode differs from "none".

Type:

Boolean

Default Value: true

NOTE
In a column with calculated values, this option is set to false by default.
See Also

buttons[]

Allows you to customize buttons in the edit column or create a custom command column. Applies only if the column's type is "buttons".

Accepted Values: 'add' | 'cancel' | 'delete' | 'edit' | 'save' | 'undelete'

calculateCellValue

Calculates custom cell values. Use this function to create an unbound data column.

Type:

Function

Function parameters:
rowData:

Object

The data of the row to which the cell belongs.

Return Value: any

A cell's custom value.

Unlike data columns bound to a data field, unbound columns display custom values returned from the calculateCellValue function. It is called each time a new row is rendered.

In the following code, the calculateCellValue function is used to create an unbound column that displays a calculated sales amount. Data objects contain the Price and UnitsSold fields used in the calculation:

jQuery
index.js
var products = [{
    ProductID: 1,
    ProductName: "Fabrikam SLR Camera 35\" X358 Blue",
    Price: 168,
    UnitsSold: 4
},
// ...
];

$(function() {
    $("#treeListContainer").dxTreeList({
        dataSource: products,
        columns: [{
            caption: "Sales Amount",
            calculateCellValue: function(rowData) {
                return rowData.Price * rowData.UnitsSold;
            }
        },
        // ...
        ]
    });
});
Angular
app.component.html
app.component.ts
app.service.ts
app.module.ts
<dx-tree-list
    [dataSource]="products">
    <dxi-column
        caption="Sales Amount"
        [calculateCellValue]="calculateSalesAmount">
    </dxi-column>
</dx-tree-list>
import { Component } from '@angular/core';
import { Product, Service } from './app.service';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    products: Product[];
    constructor(service: Service) {
        this.products = service.getProducts();
    }

    calculateSalesAmount(rowData) {
        return rowData.Price * rowData.UnitsSold;
    }
}
import { Injectable } from '@angular/core';

export class Product {
    ProductID: number,
    ProductName: string,
    Price: number,
    UnitsSold: number
}

let products: Product[] = [{
    ProductID: 1,
    ProductName: "Fabrikam SLR Camera 35\" X358 Blue",
    Price: 168,
    UnitsSold: 4
},
// ...
];

@Injectable()
export class Service {
    getProducts(): Product[] {
        return products;
    }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { DxTreeListModule } from 'devextreme-angular';
import { Service } from './app.service';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        DxTreeListModule
    ],
    providers: [
        Service
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }
Vue
App.vue
data.js
<template>
    <DxTreeList
        :data-source="products">
        <DxColumn
            caption="Sales Amount"
            :calculate-cell-value="calculateSalesAmount">
        </DxColumn>
    </DxTreeList>
</template>

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

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

import service from './data.js';

export default {
    components: {
        DxTreeList,
        DxColumn
    },
    data() {
        const products = service.getProducts();
        return {
            products
        }
    },
    methods: {
        calculateSalesAmount(rowData) {
            return rowData.Price * rowData.UnitsSold;
        }
    }
}
</script>
const products = [{
    ProductID: 1,
    ProductName: "Fabrikam SLR Camera 35\" X358 Blue",
    Price: 168,
    UnitsSold: 4
},
// ...
];

export default {
    getProducts() {
        return products;
    }
};
React
App.js
data.js
import React from 'react';

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

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

import service from './data.js';

class App extends React.Component {
    constructor(props) {
        super(props);
        this.products = service.getProducts();
    }

    calculateSalesAmount(rowData) {
        return rowData.Price * rowData.UnitsSold;
    }

    render() {
        return (
            <TreeList
                dataSource={this.products}>
                <Column
                    caption="Sales Amount"
                    calculateCellValue={this.calculateSalesAmount}
                />
            </TreeList>
        );
    }
}
export default App;
const products = [{
    ProductID: 1,
    ProductName: "Fabrikam SLR Camera 35\" X358 Blue",
    Price: 168,
    UnitsSold: 4
},
// ...
];

export default {
    getProducts() {
        return products;
    }
};

The following features are disabled in an unbound column, but you can enable them as described in this table:

Feature Action that enables it
Editing Implement the setCellValue function.
Sorting Set the allowSorting option to true.
Filtering Set the allowFiltering option to true.
Searching Set the allowSearch option to true.
Grouping (DataGrid only) Set the allowGrouping option to true.

To invoke the default behavior, call the defaultCalculateCellValue function and return its result.

jQuery
index.js
$(function() {
    $("#treeListContainer").dxTreeList({
        columns: [{
            calculateCellValue: function(rowData) {
                // ...
                return this.defaultCalculateCellValue(rowData);
            }
        }]
    });
});
Angular
app.component.ts
app.component.html
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    calculateCellValue(rowData) {
        // ...
        const column = this as any;
        return column.defaultCalculateCellValue(rowData);
    }
}
<dx-tree-list ... >
    <dxi-column ...
        [calculateCellValue]="calculateCellValue">
    </dxi-column>
</dx-tree-list>
Vue
App.vue
<template>
    <DxTreeList ... >
        <DxColumn ...
            :calculate-cell-value="calculateCellValue">
        </DxColumn>
    </DxTreeList>
</template>

<script>
// ...
export default {
    // ...
    methods: {
        calculateCellValue(rowData) {
            // ...
            const column = this as any;
            return column.defaultCalculateCellValue(rowData);
        }
    }
}
</script>
React
App.js
// ...
class App extends React.Component {
    calculateCellValue(rowData) {
        // ...
        const column = this as any;
        return column.defaultCalculateCellValue(rowData);
    }

    render() {
        return (
            <TreeList ... >
                <Column ...
                    calculateCellValue={this.calculateCellValue}
                />
            </TreeList>
        );
    }
}
export default App;
NOTE
The this keyword refers to the column's configuration.
NOTE
This function is called multiple times for every record: when the record is rendered, when sorting or filtering is applied, and when summaries are computed. It is recommend that you keep calculations inside this function as simple as possible to avoid hindering widget performance.
See Also

calculateDisplayValue

Calculates custom display values for column cells. Requires specifying the dataField or calculateCellValue option. Used in lookup optimization.

Type:

String

|

Function

Function parameters:
rowData:

Object

The data of the row to which the cell belongs.

Return Value: any

The value for the cell to display.

This option accepts the name of the data source field that provides display values...

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        columns: [{
            dataField: "countryID", // provides values for editing
            calculateDisplayValue: "country" // provides display values
        }]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxi-column
        dataField="countryID" <!-- provides values for editing -->
        calculateDisplayValue="country"> <!-- provides display values -->
    </dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxTreeList>
        <DxColumn          
            data-field="countryID" <!-- provides values for editing -->
            calculate-display-value="country"> <!-- provides display values -->  
        />
    </DxTreeList>
</template>

<script>
import 'devextreme/dist/css/dx.common.css';
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.common.css';
import 'devextreme/dist/css/dx.light.css';

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

class App extends React.Component {
    // ...

    render() {
        return (
            <TreeList>
                <Column 
                    dataField="countryID"  <!-- provides values for editing -->
                    calculateDisplayValue="country"  <!-- provides display values -->  
                />
            </TreeList>
        );
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
Razor VB
@(Html.DevExtreme().TreeList()
    .Columns(columns => columns.Add()
        .DataField("CountryID")
        .CalculateDisplayValue("Country")
    )
)
@(Html.DevExtreme().TreeList() _
    .Columns(Sub(columns)
        columns.Add() _
            .DataField("CountryID") _
            .CalculateDisplayValue("Country")
    End Sub)        
)

... or a function that combines display values. Specify this function only if all data processing operations are executed on the client.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        columns: [{
            dataField: "countryID", // provides values for editing
            calculateDisplayValue: function (rowData) { // combines display values
                return rowData.capital + " (" + rowData.country + ")";
            }
        }]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxi-column
        dataField="countryID" <!-- provides values for editing -->
        [calculateDisplayValue]="getCountryWithCapital"> <!-- combines display values -->
    </dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    getCountryWithCapital(rowData) {
        return rowData.capital + " (" + rowData.country + ")";
    }
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxTreeList>
        <DxColumn       
            data-field="countryID" <!-- provides values for editing -->
            :calculate-display-value="getCountryWithCapital" <!-- combines display values -->
        />
    </DxTreeList>
</template>

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

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

export default {
    components: {
        DxTreeList,
        DxColumn 
    },
    methods: {
        getCountryWithCapital(rowData) {
            return rowData.capital + " (" + rowData.country + ")";
        }
    }
}
</script>  
React
App.js
import React from 'react';

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

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

class App extends React.Component {
    // ...

    render() {
        return (
            <TreeList>
                <Column
                    dataField="countryID" <!-- provides values for editing -->                 
                    calculateDisplayValue={this.getCountryWithCapital} <!-- combines display values -->
                />
            </TreeList>
        );
    }

    getCountryWithCapital(rowData) {
        return rowData.capital + " (" + rowData.country + ")";
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
Razor VB
@(Html.DevExtreme().TreeList()
    .Columns(columns => columns.Add()
        .DataField("CountryID")
        .CalculateDisplayValue(new JS("getCountryWithCapital"))
    )
)

<script>
    function getCountryWithCapital(rowData) {
        return rowData.capital + " (" + rowData.country + ")";
    }        
</script>
@(Html.DevExtreme().TreeList() _
    .Columns(Sub(columns)
        columns.Add() _
            .DataField("CountryID") _
            .CalculateDisplayValue(New JS("getCountryWithCapital"))
    End Sub)        
)

<script>
    function getCountryWithCapital(rowData) {
        return rowData.capital + " (" + rowData.country + ")";
    }        
</script>    

The widget uses the specified display values in sorting, searching, and grouping (in case of DataGrid).

NOTE
The this keyword refers to the column's configuration.

Do not use this option to format text in cells. Instead, use the format, customizeText, or cellTemplate option.

calculateFilterExpression

Specifies the column's custom filtering rules.

Type:

Function

Function parameters:
filterValue: any

A user input value.

selectedFilterOperation:

String

The selected filter operation.

target:

String

The UI element where the filter expression was set.
Possible values: "filterRow", "headerFilter", "filterBuilder", and *"search".

Return Value:

Filter Expression

A filter expression. If you are using remoteOperations, it should not contain functions.

This function must return a filter expression. The simplest filter expression has the following format:

[selector, selectedFilterOperation, filterValue]
  • selector
    A data source field or a function providing actual column values. Pass this.calculateCellValue if your column contains calculated values.
  • selectedFilterOperation
    A comparison operator. One of the following: "=", "<>", ">", ">=", "<", "<=", "between", "startswith", "endswith", "contains", "notcontains".

    NOTE
    For the "between" operator, the returned filter expression has a slightly different format: [[selector, ">=", startValue], "and", [selector, "<=", endValue]].
  • filterValue
    A user input value. Values the selector provides are compared to this value.

In the following code, the calculateFilterExpression function implements an exclusive between operation. This is done by overriding the default inclusive implementation.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            calculateFilterExpression: function (filterValue, selectedFilterOperation) {
                // Implementation for the "between" comparison operator
                if (selectedFilterOperation === "between" && $.isArray(filterValue)) {
                    var filterExpression = [
                        [this.dataField, ">", filterValue[0]], 
                        "and", 
                        [this.dataField, "<", filterValue[1]]
                    ];
                    return filterExpression;
                }
                // Invokes the default filtering behavior
                return this.defaultCalculateFilterExpression.apply(this, arguments);
            },
            // ...
        }]
    });
});
Angular
TypeScript
HTML
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    calculateFilterExpression (filterValue, selectedFilterOperation) {
        let column = this as any;
        // Implementation for the "between" comparison operator
        if (selectedFilterOperation === "between" && Array.isArray(filterValue)) {
            var filterExpression = [
                [column.dataField, ">", filterValue[0]], 
                "and", 
                [column.dataField, "<", filterValue[1]]
            ];
            return filterExpression;
        }
        // Invokes the default filtering behavior
        return column.defaultCalculateFilterExpression.apply(column, arguments);
    }
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
<dx-tree-list ... >
    <dxi-column [calculateFilterExpression]="calculateFilterExpression" ... ></dxi-column>
</dx-tree-list>

In the previous code, the defaultCalculateFilterExpression function invokes default behavior. You can omit this function call if you so choose.

NOTE
The this keyword refers to the column's configuration.

calculateSortValue

Calculates custom values to be used in sorting.

Type:

String

|

Function

Function parameters:
rowData:

Object

The data of the row to which the cell belongs.

Return Value: any

The value to be used in sorting.

This option accepts the name of the data source field that provides values to be used in sorting...

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        columns: [{
            dataField: "Position", // provides values for the column
            calculateSortValue: "isOnVacation" // provides values to be used in sorting 
        }]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxi-column
        dataField="Position" <!--provides values for the column -->
        calculateSortValue="isOnVacation"> <!-- provides values to be used in sorting -->
    </dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})

... or a function that returns such a value.

jQuery
JavaScript
$(function() {
    var treeList = $("#treeListContainer").dxTreeList({
        columns: [{
            dataField: "Position",
            sortOrder: "asc",
            calculateSortValue: function (rowData) {
                if (rowData.Position == "CEO")
                    return treeList.columnOption("Position", "sortOrder") == "asc" ? "aaa" : "zzz"; // CEOs are always displayed at the top
                else
                    return rowData.Position; // Others are sorted as usual
            }
        }]
    }).dxTreeList("instance");
});
Angular
TypeScript
HTML
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    customSortingFunction (rowData) {
        let column = this as any;
        if (rowData.Position == "CEO")
            return column.sortOrder == "asc" ? "aaa" : "zzz"; // CEOs are always displayed at the top
        else
            return rowData.Position; // Others are sorted as usual
    }
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
<dx-tree-list ... >
    <dxi-column
        dataField="Position"
        sortOrder="asc"
        [calculateSortValue]="customSortingFunction">
    </dxi-column>
</dx-tree-list>
NOTE

Please review the following notes about the calculateSortValue option.

  • The this keyword refers to the column's configuration.

  • When the DataGrid is grouped by the column, this option is ignored. Use the calculateGroupValue option instead or additionally.

See Also

caption

Specifies a caption for the column.

Type:

String

Default Value: undefined

Use this option to display a descriptive or friendly name for the column. If this option is not set, the caption will be generated from the name of the dataField.

cellComponent

An alias for the cellTemplate property specified in React. Accepts a custom component. Refer to Using a Custom Component for more information.

cellRender

An alias for the cellTemplate property specified in React. Accepts a rendering function. Refer to Using a Rendering Function for more information.

cellTemplate

Specifies a custom template for data cells.

Type:

template

Template Data:
Name Type Description
column

TreeList Column

The column's properties.

columnIndex

Number

The index of the cell's column.

component

TreeList

The widget's instance.

data

Object

The data of the row to which the cell belongs.

displayValue any

The cell's display value. Differs from the value field only when the column uses lookup or calculateDisplayValue.

oldValue any

The cell's previous raw value. Defined only if repaintChangesOnly is true.

row

TreeList Row

The cell's row.

rowIndex

Number

The index of the cell's row. Begins with 0 on each page.
Refer to Column and Row Indexes for more information.

rowType

String

The row's type.

text

String

displayValue after applying format and customizeText.

value any

The cell's raw value.

watch

Function

Allows tracking a variable and performing actions when it changes. Applies when repaintChangesOnly is true.
This function has the following parameters:

  • getter(data): Function
    A function that returns the variable that should be tracked.

  • handler(newValue): Function
    A function called when this variable changes.

NOTE
If you implement two-way data binding in your template, make sure that you have switched off the built-in implementation of this feature by setting the twoWayBindingEnabled option to false.

View Demo

See Also

columns

Configures columns.

Default Value: undefined

Unlike normal columns, band columns do not hold data. Instead, they collect two or more columns under one column header. To set up this layout, declare the band column using a hierarchical structure. For this, assign the nested columns to the columns field of the band column. For example, the following code declares the "Address" band column and nests three columns within it.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            caption: "Address",
            columns: ["City", "Street", "Apartment"]
        }, {
            // ...
        }]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxi-column caption="Address">
        <dxi-column dataField="City"></dxi-column>
        <dxi-column dataField="Street"></dxi-column>
        <dxi-column dataField="Apartment"></dxi-column>
    </dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})

A nested column has almost every option a regular column has. These options are described in the columns section of the Reference.

NOTE
There is an exception though: nested columns cannot be fixed alone, therefore specifying the fixed and fixedPosition options for them is useless. However, the whole band column can be fixed as usual.

For example, the following code specifies the width and sortOrder options of the "Street" column nested within the fixed "Address" band column.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            caption: "Address",
            fixed: true,
            fixedPosition: "right",
            columns: [
                "City", {
                    dataField: "Street",
                    width: 100,
                    sortOrder: "asc"
                },
                "Apartment"
            ]
        }, {
            // ...
        }]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxi-column
        caption="Address"
        [fixed]="true"
        fixedPosition="right">
        <dxi-column dataField="City"></dxi-column>
        <dxi-column dataField="Street" [width]="100" sortOrder="asc"></dxi-column>
        <dxi-column dataField="Apartment"></dxi-column>
    </dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})

Band columns support hierarchies of any nesting level. It means that the following structure is acceptable.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            caption: "A",
            columns: [ "A1", "A2", {
                caption: "A3",
                columns: ["A31", "A32", {
                    caption: "A33",
                    columns: ["A331", "A332", "A333"]
                }]
            }]
        }, {
            caption: "B",
            columns: // ...
        }]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxi-column caption="A">
        <dxi-column dataField="A1"></dxi-column>
        <dxi-column dataField="A2"></dxi-column>
        <dxi-column caption="A3">
            <dxi-column dataField="A31"></dxi-column>
            <dxi-column dataField="A32"></dxi-column>
            <dxi-column caption="A33">
                <dxi-column dataField="A331"></dxi-column>
                <dxi-column dataField="A332"></dxi-column>
                <dxi-column dataField="A333"></dxi-column>
            </dxi-column>
        </dxi-column>
    </dxi-column>
    <dxi-column caption="B">
        ...
    </dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})

Band columns have the isBand flag. Banded columns have the ownerBand option set. Use these options to distinguish band and banded columns from regular ones in code.

See Also

cssClass

Specifies a CSS class to be applied to the column.

Type:

String

Default Value: undefined

In the following code, this option is assigned a cell-highlighted CSS class that customizes the position column's cell and header styles:

jQuery
index.js
styles.css
$(function() {
    $("#treeListContainer").dxTreeList({
        dataSource: [{
            ID: 1,
            position: "CTO"
        }, // ...
        ],
        columns: [ "ID", {
            dataField: "position",
            cssClass: "cell-highlighted"
        } ],
    });
})
.dx-data-row .cell-highlighted {
    background-color: #e6e6e6;
}

.dx-header-row .cell-highlighted {
    color: gray;
    font-style: italic;
}
Angular
app.component.html
app.component.ts
app.module.ts
app.component.css
<dx-tree-list ...
    [dataSource]="employees">
    <dxi-column dataField="ID"></dxi-column>
    <dxi-column dataField="position" cssClass="cell-highlighted"></dxi-column>
</dx-tree-list>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    employees = [{
        ID: 1,
        position: "CTO"
    }, // ...
    ];
}
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 { }
::ng-deep .dx-data-row .cell-highlighted {
    background-color: #e6e6e6;
}

::ng-deep .dx-header-row .cell-highlighted {
    color: gray;
    font-style: italic;
}
Vue
App.vue
<template>
    <DxTreeList ...
        :data-source="employees">
        <DxColumn data-field="ID" />
        <DxColumn data-field="position" css-class="cell-highlighted" />
    </DxTreeList>
</template>
<script>
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.css';

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

const employees = [{
    ID: 1,
    position: "CTO"
}, // ...
];

export default {
    components: {
        DxTreeList,
        DxColumn
    },
    data() {
        employees
    }
};
</script>
<style>
.dx-data-row .cell-highlighted {
    background-color: #e6e6e6;
}

.dx-header-row .cell-highlighted {
    color: gray;
    font-style: italic;
}
</style>
React
App.js
styles.css
import React from 'react';

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

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

const employees = [{
    ID: 1,
    position: "CTO"
}, // ...
];

class App extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <TreeList ...
                dataSource={employees}>
                <Column dataField="ID" />
                <Column dataField="position" cssClass="cell-highlighted" />
            </TreeList>
        );
    }
}
export default App;
.dx-data-row .cell-highlighted {
    background-color: #e6e6e6;
}

.dx-header-row .cell-highlighted {
    color: gray;
    font-style: italic;
}
ASP.NET MVC Controls
Razor C#
styles.css
@(Html.DevExtreme().TreeList()
    .DataSource(new JS("employees"))
    .Columns(c => {
        c.Add().DataField("ID");
        c.Add().DataField("position").CssClass("cell-highlighted");
    })
)
<script type="text/javascript">
    var employees = [{
        ID: 1,
        position: "CTO"
    }, // ...
    ];
</script>
.dx-data-row .cell-highlighted {
    background-color: #e6e6e6;
}

.dx-header-row .cell-highlighted {
    color: gray;
    font-style: italic;
}

customizeText

Customizes the text displayed in column cells.

Type:

Function

Function parameters:
cellInfo:

Object

Information on the current cell.

Object structure:
Name Type Description
groupInterval

String

|

Number

Indicates how header filter values were combined into groups. Available if target is "headerFilter".
See the headerFilter.groupInterval option's description for possible values.

target

String

The UI element where the customizeText function was called: "row", "filterRow", "headerFilter", "search", "filterPanel", or "filterBuilder".

value

String

|

Number

|

Date

The cell's raw value.

valueText

String

The fomatted value converted to a string.

Return Value:

String

The text the cell should display.

jQuery
index.js
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            dataField: "Temperature",
            customizeText: function(cellInfo) {
                return cellInfo.value + " &deg;C";
            }
        }]
    });
});
Angular
app.component.html
app.component.ts
app.module.ts
<dx-tree-list ... >
   <dxi-column
       dataField="Temperature"
       [customizeText]="customizeText"
   ></dxi-column>
</dx-tree-list>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    customizeText(cellInfo) {
        return cellInfo.value + " &deg;C";
    }
}
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 { }
Vue
App.vue
<template>
    <DxTreeList ... >
        <DxColumn
            data-field="Temperature" 
            :customize-text="customizeText"
        />
    </DxTreeList>
</template>

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

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

export default {
    components: {
        DxTreeList,
        DxColumn
    },
    methods: {
        customizeText(cellInfo) {
            return cellInfo.value + " &deg;C";
        }
    }
}
</script>
React
App.js
import React from 'react';

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

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

class App extends React.Component {
    customizeText = (cellInfo) => {
        return cellInfo.value + " &deg;C";
    }
    render() {
        return (
            <TreeList ... >
                <Column dataField="Temperature" customizeText={this.customizeText} />
            </TreeList>
        );
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().TreeList()
    //...
    .Columns(columns => {
        columns.Add().DataField("Temperature")
            .CustomizeText("customizeText");
    })
)

<script type="text/javascript">
    function customizeText(cellInfo) {
        return cellInfo.value + " &deg;C";
    }
</script>
NOTE
The specified text is not used to sort, filter, and group data or calculate summaries. If it should be, specify the calculateCellValue function instead.

The customizeText function can be called to highlight the matching text correctly when the data displayed in the column matches the search condition.

NOTE
The this keyword refers to the column's configuration.
See Also

dataField

Binds the column to a field of the dataSource.

Type:

String

Default Value: undefined

The columns array can contain only the names of data source fields, which is sufficient if you do not need to specify any other column options. But if you do, then this array should contain objects that configure columns. To bind the columns to data source fields, use the dataField option. Note that you can combine both declarations in a single array as shown in the following code.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [
            "CustomerID",
            { dataField: "EmployeeID", width: 200 },
            "OrderDate",
            { dataField: "Freight", format: "fixedPoint" },
            "ShipName",
            "ShipCity"
        ]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxi-column dataField="CustomerID"></dxi-column>
    <dxi-column dataField="EmployeeID" [width]="200"></dxi-column>
    <dxi-column dataField="OrderDate"></dxi-column>
    <dxi-column dataField="Freight" format="fixedPoint"></dxi-column>
    <dxi-column dataField="ShipName"></dxi-column>
    <dxi-column dataField="ShipCity"></dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
See Also

dataType

Casts column values to a specific data type.

Type:

String

Default Value: undefined
Accepted Values: 'string' | 'number' | 'date' | 'boolean' | 'object' | 'datetime'

If a data field provides values of one data type, but the widget should cast them to another, specify the proper type in this option. In the following code, values of the ID and hireDate fields are cast to numeric and date data types, respectively.

jQuery
JavaScript
$(function() {
    $("#treeList").dxTreeList({
        // ...
        dataSource: [{
            ID: "1",
            hireDate: 1491821760000
        }, // ...
        ],
        columns: [{
            dataField: "ID",
            dataType: "number"
        }, {
            dataField: "hireDate",
            dataType: "date"
        }]
    });
})
Angular
HTML
TypeScript
<dx-tree-list ...
    [dataSource]="employees">
    <dxi-column
        dataField="ID"
        dataType="number">
    </dxi-column>
    <dxi-column 
        dataField="hireDate"
        dataType="date">
    </dxi-column>
</dx-tree-list>
import { DxTreeListModule } from 'devextreme-angular';
// ...
export class AppComponent {
    employees = [{
        ID: "1",
        hireDate: 1491821760000
    }, // ...
    ];
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule 
    ],
    // ...
})
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().TreeList()
    .DataSource(new JS("employees"))
    .Columns(c => {
        c.Add()
            .DataField("ID")
            .DataType(GridColumnDataType.Number);
        c.Add()
            .DataField("hireDate")
            .DataType(GridColumnDataType.Date);
    })
)
<script>
    var employees = [{
        ID: "1",
        hireDate: 1491821760000
    }, // ...
    ];
</script>
Vue
<template>
    <DxTreeList ...
        :data-source="employees">
        <DxColumn
            data-field="ID"
            data-type="number"
        />
        <DxColumn
            data-field="hireDate"
            data-type="date"
        />
    </DxTreeList>
</template>
<script>
import { DxTreeList, DxColumn } from 'devextreme-vue/tree-list';

const employees = [{
    ID: '1',
    hireDate: 1491821760000
}, // ...
];

export default {
    components: {
        DxTreeList,
        DxColumn
    },
    data() {
        employees
    }
};
</script>
React
import React from 'react';
import { TreeList, Column } from 'devextreme-react/tree-list';

const employees = [{
    ID: '1',
    hireDate: 1491821760000
}, // ...
];

class App extends React.Component {
    render() {
        return (
            <TreeList ...
                dataSource={employees}>
                <Column dataField="ID" dataType="number" />
                <Column dataField="hireDate" dataType="date" />
            </TreeList>
        );
    }
}
export default App;
NOTE
Date-time values stored as strings should have one of the following formats: "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy-MM-ddTHH:mm:ssx" or "yyyy-MM-ddTHH:mm:ss".

Use the GridColumnDataType enum to specify this option when the widget is used as an ASP.NET MVC 5 Control or a DevExtreme-Based ASP.NET Core Control. This enum accepts the following values: String, Number, Date, DateTime, Boolean, and Object.

See Also

editCellComponent

An alias for the editCellTemplate property specified in React. Accepts a custom component. Refer to Using a Custom Component for more information.

editCellRender

An alias for the editCellTemplate property specified in React. Accepts a rendering function. Refer to Using a Rendering Function for more information.

editCellTemplate

Specifies a custom template for data cells in editing state.

Type:

template

Template Data:
Name Type Description
column

TreeList Column

The settings of the column the cell belong to.

columnIndex

Number

The index of the column the cell belongs to.
Refer to the Column and Row Indexes topic for more information on how this index is calculated.

component

TreeList

The widget's instance.

data

Object

The data of the cell's row.

displayValue any

The displayed cell value. Differs from the value field only when the column uses lookup or calculateDisplayValue.

row

TreeList Row

The cell's row.

rowIndex

Number

The index of the row the cell belongs to. Begins with 0 on each page. Group rows are included.
Refer to the Column and Row Indexes topic for more information on row indexes.

rowType

String

The row's type.

setValue(newValue, newText) any

A method you should call to change the cell value and, optionally, the displayed value after the editor's value is changed.
See an example in the Custom Editors demo.

NOTE
In batch editing mode, check that the value is actually changed before calling this method to ensure correct cell highlighting.
text

String

displayValue after applying format and customizeText.

value any

The cell value as it is specified in the data source.

watch

Function

Allows tracking a variable and performing actions when it changes. Applies when repaintChangesOnly is true.
This function has the following parameters:

  • getter(data): Function
    A function that returns the variable that should be tracked.

  • handler(newValue): Function
    A function called when this variable changes.

Use the editCellTemplate to replace the default editor. In the template, specify the replacement editor's appearance and behavior.

View Demo

Other options that allow editor customization include:

NOTE
If you implement two-way data binding in your template, set twoWayBindingEnabled to false to disable this feature's default implementation.
See Also

editorOptions

Configures the default widget used for editing and filtering in the filter row.

Type:

Object

In this object, you can specify the default widget's options (except onValueChanged, which you can specify in onEditorPreparing).

The default editor widget depends on the column configuration. The following table illustrates the dependency:

Column Configuration Default Editor
dataType: "date"
"datetime"
DateBox
"number" NumberBox
"boolean" CheckBox
"string"
"object"
TextBox
lookup is defined SelectBox

Because of this dependency, editorOptions cannot be typed and are not implemented as nested configuration components in Angular, Vue, and React. In these frameworks, specify editorOptions with an object. We recommend that you declare the object outside the configuration component in Vue and React to prevent possible issues caused by unnecessary re-rendering.

Angular
app.component.html
app.module.ts
<dx-tree-list ... >
    <dxi-column ...
        [editorOptions]="{ format: 'currency', showClearButton: true }">
    </dxi-column>
</dx-tree-list>
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 { }
Vue
App.vue
<template>
    <DxTreeList ... >
        <DxColumn ...
            :editor-options="columnEditorOptions"
        />
    </DxTreeList>
</template>

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

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

export default {
    components: {
        DxTreeList,
        DxColumn
    },
    data() {
        return {
            columnEditorOptions: { format: 'currency', showClearButton: true }
        }
    }
}
</script>
React
App.js
import React from 'react';

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

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

class App extends React.Component {
    columnEditorOptions = { format: 'currency', showClearButton: true };

    render() {
        return (
            <TreeList ... >
                <Column ...
                    editorOptions={this.columnEditorOptions}
                />
            </TreeList>
        );
    }
}
export default App;

View Demo

Other options that allow editor customization include:

See Also

encodeHtml

Specifies whether HTML tags are displayed as plain text or applied to the values of the column.

Type:

Boolean

Default Value: true

When true, HTML tags are displayed as plain text; when false, they are applied to the values of the column.

falseText

In a boolean column, replaces all false items with a specified text. Applies only if showEditorAlways option is false.

Type:

String

Default Value: 'false'

See Also

filterOperations

Specifies the available filter operations. Applies if allowFiltering is true and the filterRow and/or filterPanel are visible.

Type:

Array<String>

Default Value: undefined
Accepted Values: '=' | '<>' | '<' | '<=' | '>' | '>=' | 'contains' | 'endswith' | 'isblank' | 'isnotblank' | 'notcontains' | 'startswith' | 'between' | 'anyof' | 'noneof'

The following table lists the available filter operations by data types. Users can apply these filter operations in the filter row and nested filterBuilder component. The same operations are assigned to columns of a specific data type.

dataType filterOperations
"string" [ "contains", "notcontains", "startswith", "endswith", "=", "<>" ]
"numeric" [ "=", "<>", "<", ">", "<=", ">=", "between" ]
"date" [ "=", "<>", "<", ">", "<=", ">=", "between" ]

The nested filter builder also allows users to select from an extended set of operations that include "anyof", "noneof", "isblank", "isnotblank", and names of custom operations (if there are any).

The filterOperations option can also accept an empty array. In this case, the selected filter operation is "=" for all data types, and a user cannot change it.

Use the FilterOperations enum to specify this option when the widget is used as an ASP.NET MVC 5 Control or a DevExtreme-Based ASP.NET Core Control. This enum accepts the following values: Equal, NotEqual, LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual, NotContains, Contains, StartsWith, EndsWith, and Between.

See Also

filterType

Specifies whether a user changes the current filter by including (selecting) or excluding (clearing the selection of) values. Applies only if headerFilter.visible and allowHeaderFiltering are true.

Type:

String

Default Value: 'include'
Accepted Values: 'exclude' | 'include'

This option accepts the following values.

  • include
    Values in the header filter are unselected initially, and a user can select values to apply a filter.
  • exclude
    All values in the header filter are selected initially. A user can deselect values to change the filter.

This option changes when the user clicks the Select All checkbox in the header filter:

Select All filterType / filterValues
filterType: "include"
filterValues: null
filterType: "exclude"
filterValues: null

Use the FilterType enum to specify this option when the widget is used as an ASP.NET MVC 5 Control or a DevExtreme-Based ASP.NET Core Control. This enum accepts the following values: Include and Exclude.

See Also

filterValue

Specifies the column's filter value displayed in the filter row.

Type: any
Default Value: undefined
Raised Events: onOptionChanged

This value is applied using the selectedFilterOperation.

NOTE
The filter row and header filter can work simultaneously. If you specify the filterValue option to set up the filter row, it limits the filter values for the header filter and vice versa: if you specify the filterValues option to set up the header filter, it limits the filter row's filter values.

filterValues

Specifies values selected in the column's header filter.

Type:

Array<any>

Default Value: undefined
Raised Events: onOptionChanged

If the headerFilter.groupInterval option is set, each value in the filterValues array specifies the beginning of an interval instead of an exact value:

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            dataField: "ID",
            dataType: "number",
            headerFilter: { groupInterval: 100 },
            filterValues: [500, 700], // Filter intervals are 500-600 and 700-800
        },
        // ...
        ]
    })
});
Angular
TypeScript
HTML
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    columns = [{
        dataField: "ID",
        dataType: "number",
        headerFilter: { groupInterval: 100 },
        filterValues: [500, 700], // Filter intervals are 500-600 and 700-800
    },
    // ...
    ];
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
<dx-tree-list ...
    [columns]="columns">
</dx-tree-list>
NOTE
The filter row and header filter can work simultaneously. If you specify the filterValue option to set up the filter row, it limits the filter values for the header filter and vice versa: if you specify the filterValues option to set up the header filter, it limits the filter row's filter values.
See Also

fixed

Fixes the column.

Type:

Boolean

Default Value: false

See Also

fixedPosition

Specifies the widget's edge to which the column is fixed. Applies only if columns[].fixed is true.

Type:

String

Default Value: undefined
Accepted Values: 'left' | 'right'

Use the HorizontalEdge enum to specify this option when the widget is used as an ASP.NET MVC 5 Control or a DevExtreme-Based ASP.NET Core Control. This enum accepts the following values: Left and Right.

See Also

format

Formats a value before it is displayed in a column cell.

Type:

Format

Default Value: ''

See the format section for details on accepted values.

In the following code, the "fixedPoint" format type with a precision of 2 decimal places is applied to column values:

jQuery
index.js
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            // ...
            format: {
                type: "fixedPoint",
                precision: 2
            }
        }]
    });
});
Angular
app.component.html
app.module.ts
<dx-tree-list ... >
    <dxi-column ... >
        <dxo-format
            type="fixedPoint"
            [precision]="2">
        </dxo-format>
    </dxi-column>
</dx-tree-list>
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 { }
Vue
App.vue
<template>
    <DxTreeList ... >
        <DxColumn ... >
            <DxFormat
                type="fixedPoint"
                :precision="2"
            />
        </DxColumn>
    </DxTreeList>
</template>

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

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

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

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

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

class App extends React.Component {
    // ...
    render() {
        return (
            <TreeList>
                <Column ... >
                    <Format
                        type="fixedPoint"
                        precision={2}
                    />
                </Column>
            </TreeList>
        );
    }
}
export default App;

The format option also limits user input in cells that use the DateBox widget for editing. For cells that use the NumberBox widget, you can specify the editorOptions.format option, as shown in the following demo:

View Demo

formItem

Configures the form item that the column produces in the editing state. Applies only if editing.mode is "form" or "popup".

In the following code, the Full_Name grid column in the editing state produces a form item that spans two form columns. The item's label is on top of the editor:

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        editing: {
            allowUpdating: true,
            mode: "form"
        },
        columns: [{
            dataField: "Full_Name",
            formItem: {
                colSpan: 2,
                label: {
                    location: "top"
                }
            }
        },
        // ...
        ]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxo-editing
        [allowUpdating]="true"
        mode="form">
    </dxo-editing>
    <dxi-column dataField="Full_Name">
        <dxo-form-item [colSpan]="2">
            <dxo-label location="top"></dxo-label>
        </dxo-form-item>
    </dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().TreeList()
    // ...
    .Editing(e => e
        .AllowUpdating(true)
        .Mode(GridEditMode.Form)
    )
    .Columns(cols => {
        // ...
        cols.Add().DataField("Full_Name")
            .FormItem(item => item
                .ColSpan(2)
                .Label(l => l.Location(FormLabelLocation.Top)
            )
        );
    })
)
NOTE
The formItem object does not allow you to specify a template. Use the column's editCellTemplate instead.
See Also

headerCellComponent

An alias for the headerCellTemplate property specified in React. Accepts a custom component. Refer to Using a Custom Component for more information.

headerCellRender

An alias for the headerCellTemplate property specified in React. Accepts a rendering function. Refer to Using a Rendering Function for more information.

headerCellTemplate

Specifies a custom template for column headers.

Type:

template

Template Data:
Name Type Description
column

TreeList Column

The settings of the column to which the header belongs.

columnIndex

Number

The index of the column to which the header belongs.

component

TreeList

The widget's instance.

See Also

headerFilter

Specifies data settings for the header filter.

Type:

Object

Default Value: undefined

See Also

hidingPriority

Specifies the order in which columns are hidden when the widget adapts to the screen or container size. Ignored if allowColumnResizing is true and columnResizingMode is "widget".

Type:

Number

Default Value: undefined

The hidingPriority is a unique positive integer that ascends from right to left beginning with 0 by default. Columns with low hidingPriority are hidden first.

NOTE
Specifying hidingPriority for at least one column enables the column hiding feature and cancels the default hiding priorities.
NOTE
Fixed columns ignore the hidingPriority and allowHiding options.
See Also

isBand

Specifies whether the column bands other columns or not.

Type:

Boolean

Default Value: undefined

Unlike normal columns, band columns do not hold data. Instead, they collect two or more columns under one column header. In most cases, to set up this layout, you can declare the band column using a hierarchical structure. For example, the following code bands three columns under the "Address" header.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            caption: "Address",
            columns: ["City", "Street", "Apartment"]
        }, {
            // ...
        }]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxi-column caption="Address">
        <dxi-column dataField="City"></dxi-column>
        <dxi-column dataField="Street"></dxi-column>
        <dxi-column dataField="Apartment"></dxi-column>
    </dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})

If you use the customizeColumns option to configure columns, the hierarchical structure cannot be implemented. To band columns in this case, use the isBand and ownerBand options.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        customizeColumns: function(columns) {
            columns.push({ // Pushes the "Address" band column into the "columns" array
                caption: "Address",
                isBand: true
            });

            var addressFields = ["City", "Street", "Apartment"];
            for (var i = 0; i < columns.length-1; i++) {
                if (addressFields.indexOf(columns[i].dataField) > -1) // If the column belongs to "Address",
                    columns[i].ownerBand = columns.length-1; // assigns "Address" as the owner band column
            }
        }
    });
});
Angular
TypeScript
HTML
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    customizeColumns (columns) {
        columns.push({ // Pushes the "Address" band column into the "columns" array
            caption: "Address",
            isBand: true
        });

        let addressFields = ["City", "Street", "Apartment"];
        for (let i = 0; i < columns.length - 1; i++) {
            if (addressFields.indexOf(columns[i].dataField) > -1) // If the column belongs to "Address",
                columns[i].ownerBand = columns.length - 1; // assigns "Address" as the owner band column
        }
    }
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
<dx-tree-list ...
    [customizeColumns]="customizeColumns">
</dx-tree-list>

Band columns can have the following properties only:

NOTE
Band columns cannot nest command columns.
See Also

lookup

Specifies options of a lookup column.

Type:

Object

Default Value: undefined

A lookup column restricts the set of values that can be chosen when a user edits or filters the column. In a lookup column, each cell is a drop-down menu. You can use a lookup column when you need to substitute displayed values with required values. For example, consider that you have two arrays of objects: drivers and buses.

JavaScript
var drivers = [
    { driverID: 1, firstName: "John", lastName: "Smith", busID: 2 },
    { driverID: 2, firstName: "Lizzy", lastName: "Cook", busID: 1 },
    { driverID: 3, firstName: "Brian", lastName: "Hawkins", busID: 3 }
];

var buses = [
    { busID: 1, plates: "123456" },
    { busID: 2, plates: "AB-1234" },
    { busID: 3, plates: "CD-9876" }
];

All drivers have the busID field, which refers to a bus. If drivers is the main dataSource, the Bus ID column displays bus IDs, which provides little information to a user. It will be more useful to display bus license plates instead of IDs. For this, the buses array must be set as a lookup dataSource for the Bus ID column. Then, the names of data fields must be assigned to the valueExpr and displayExpr options. Values from the valueExpr data field will be replaced with values from the displayExpr data field.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        dataSource: drivers,
        // ...
        columns: [{
            dataField: "busID",
            lookup: {
                dataSource: buses,
                valueExpr: "busID",
                displayExpr: "plates"
            }
        }]
    });
});
Angular
HTML
TypeScript
<dx-tree-list [dataSource]="drivers">
    <dxi-column dataField="busID">
        <dxo-lookup
            [dataSource]="buses"
            valueExpr="busID"
            displayExpr="plates">
        </dxo-lookup>
    </dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    drivers = [
        { driverID: 1, firstName: "John", lastName: "Smith", busID: 2 },
        { driverID: 2, firstName: "Lizzy", lastName: "Cook", busID: 1 },
        { driverID: 3, firstName: "Brian", lastName: "Hawkins", busID: 3 }
    ];
    buses = [
        { busID: 1, plates: "123456" },
        { busID: 2, plates: "AB-1234" },
        { busID: 3, plates: "CD-9876" }
    ];
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})

With this code, the Bus ID column contains license plates instead of IDs. Moreover, the user can choose a plate number from the drop-down menu when editing cells or applying a filter to this column.

See Also

minWidth

Specifies the minimum width of the column.

Type:

Number

Default Value: undefined

name

Specifies the identifier of the column.

Type:

String

Default Value: undefined

Set this option if you need to refer to the column in your code afterwards, for example, when changing a column option.

ownerBand

Specifies the band column that owns the current column. Accepts the index of the band column in the columns array.

Type:

Number

Default Value: undefined

Main article: isBand

renderAsync

Specifies whether to render the column after other columns and elements. Use if column cells have a complex template. Requires the width option specified.

Type:

Boolean

Default Value: false

See Also

selectedFilterOperation

Specifies the column's filter operation displayed in the filter row.

Type:

String

Default Value: undefined
Accepted Values: '<' | '<=' | '<>' | '=' | '>' | '>=' | 'between' | 'contains' | 'endswith' | 'notcontains' | 'startswith'
Raised Events: onOptionChanged

The following table lists default filter operations by data type:

dataTypeDefault filter operation
"string""contains"
"number""="
"date""="

Use the FilterOperations enum to specify this option when the widget is used as an ASP.NET MVC 5 Control or a DevExtreme-Based ASP.NET Core Control. This enum accepts the following values: Equal, NotEqual, LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual, NotContains, Contains, StartsWith, EndsWith, and Between.

See Also

setCellValue

Specifies a function to be invoked after the user has edited a cell value, but before it will be saved in the data source.

Type:

Function

Function parameters:
newData:

Object

The data object where new data should be set.

value: any

The input value.

currentRowData:

Object

A read-only parameter providing access to the current row data.

Return Value: void |

Promise<void> (jQuery or native)

Return a promise for an asynchronous operation or return nothing.

This function allows you to process user input before it is saved to the data source. It accepts the newData, value, and currentRowData parameters. value is the user input that you should assign to one of the newData fields. Fill the empty newData object with fields whose values should be saved in the current row's data object. The read-only currentRowData parameter can be used to access the current row's data.

jQuery
index.js
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [
            "Price",
            {
                dataField: "Count",
                dataType: "number",
                setCellValue: function(newData, value, currentRowData) {
                    newData.Count = value;
                    newData.TotalPrice = currentRowData.Price * value;
                }
            },
            "TotalPrice",
            // ...
        ]
    });
});
Angular
app.component.html
app.component.ts
app.module.ts
<dx-tree-list ... >
    <dxi-column dataField="Price"></dxi-column>
    <dxi-column
        dataField="Count"
        dataType="number"
        [setCellValue]="setCellValue">
    </dxi-column>
    <dxi-column dataField="TotalPrice"></dxi-column>
</dx-tree-list>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    setCellValue (newData, value, currentRowData) {
        newData.Count = value;
        newData.TotalPrice = currentRowData.Price * value;
    }
}
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 { }
Vue
App.vue
<template>
    <DxTreeList ... >
        <DxColumn data-field="Price" />
        <DxColumn data-field="Count" data-type="number" />
        <DxColumn data-field="TotalPrice" :set-cell-value="setCellValue" />
    </DxTreeList>
</template>
<script>
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.css';

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

export default {
    components: {
        DxTreeList,
        DxColumn
    },
    // ...
    methods: {
        setCellValue(newData, value, currentRowData) {
            newData.Count = value;
            newData.TotalPrice = currentRowData.Price * value;
        }
    }
};
</script>
React
App.js
import React from 'react';

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

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

class App extends React.Component {
    setCellValue(newData, value, currentRowData) {
        newData.Count = value;
        newData.TotalPrice = currentRowData.Price * value;
    }

    render() {
        return (
            <TreeList ... >
                <Column dataField="Price" />
                <Column dataField="Count" dataType="numeric" setCellValue={this.setCellValue}/>
                <Column dataField="TotalPrice" />
            </TreeList>
        );
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().TreeList()
    // ...
    .Columns(c => {
        c.Add().DataField("Price");
        c.Add().DataField("Count")
            .DataType(GridColumnDataType.Number)
            .SetCellValue(@<text>
                function(newData, value, currentRowData) {
                    newData.Count = value;
                    newData.TotalPrice = currentRowData.Price * value;
                }
            </text>);
        c.Add().DataField("TotalPrice");
    })
)

If you need to perform asynchronous operations in the setCellValue function, return a promise from it. In the following code, this technique is used to get the Tax value from the server when the State value is changed:

jQuery
index.js
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            dataField: "State",
            setCellValue: function(newData, value, currentRowData) {
                return getTaxRates(value)
                    .done(function(data) {
                        newData.State = value;
                        newData.Tax = data.Tax;
                    });
            }
        },
        "Tax",
        // ...
        ]
    });
    function getTaxRates(state) {
        var promise = $.ajax({
            // The URL returns { State: 1, Tax: 10 }
            url: "https://www.mywebsite.com/api/getTaxRates",
            dataType: "json",
            data: { State: state }
        });
        return promise;
    }
});
Angular
app.component.html
app.component.ts
app.module.ts
<dx-tree-list ... >
    <dxi-column
        dataField="State"
        [setCellValue]="setCellValue">
    </dxi-column>
    <dxi-column dataField="Tax"></dxi-column>
    <!-- ... -->
</dx-tree-list>
import { Component } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import 'rxjs/add/operator/toPromise';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    constructor(private httpClient: HttpClient) {
        this.setCellValue = this.setCellValue.bind(this);
    }

    setCellValue(newData, value, currentRowData) {
        return this.getTaxRates(value).then((data: any) => {
            newData.State = value;
            newData.Tax = data.Tax;
        });
    }
    getTaxRates(state) {
        const params = new HttpParams().set('State', state);
        return this.httpClient.get("https://www.mywebsite.com/api/getTaxRates", { params })
            .toPromise()
            .then(data => {
                // "data" is { State: 1, Tax: 10 }
                return data;
            })
            .catch(error => { throw "Data Loading Error" });
    }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';

import { DxTreeListModule } from 'devextreme-angular';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        HttpClientModule,
        DxTreeListModule
    ],
    providers: [ ],
    bootstrap: [AppComponent]
})
export class AppModule { }
Vue
App.vue
<template>
    <DxTreeList ... >
        <DxColumn data-field="State" :set-cell-value="setCellValue" />
        <DxColumn data-field="Tax" />
        <!-- ... -->
    </DxTreeList>
</template>
<script>
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.css';

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

export default {
    components: {
        DxTreeList,
        DxColumn
    },
    // ...
    methods: {
        setCellValue(newData, value, currentRowData) {
            return this.getTaxRates(value).then(data => {
                newData.State = value;
                newData.Tax = data.Tax;
            });
        },
        getTaxRates(state) {
            let params = '?' + 'State=' + state;
            return fetch("https://www.mywebsite.com/api/getTaxRates${params}")
                .toPromise()
                .then(data => {
                    // "data" is { State: 1, Tax: 10 }
                    return data;
                })
                .catch(error => { throw "Data Loading Error" });
        }
    }
};
</script>
React
App.js
import React from 'react';

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

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

class App extends React.Component {
    constructor(props) {
        super(props);
        this.setCellValue = this.setCellValue.bind(this);
    }

    setCellValue(newData, value, currentRowData) {
        return this.getTaxRates(value).then(data => {
            newData.State = value;
            newData.Tax = data.Tax;
        });
    }
    getTaxRates(state) {
        let params = '?' + 'State=' + state;
        return fetch("https://www.mywebsite.com/api/getTaxRates${params}")
            .toPromise()
            .then(data => {
                // "data" is { State: 1, Tax: 10 }
                return data;
            })
            .catch(error => { throw "Data Loading Error" });
    }

    render() {
        return (
            <TreeList ... >
                <Column dataField="State" setCellValue={this.setCellValue}/>
                <Column dataField="Tax" />
                {/* ... */}
            </TreeList>
        );
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().TreeList()
    // ...
    .Columns(c => {
        c.Add().DataField("State")
            .SetCellValue("setCellValue");
        c.Add().DataField("Tax");
        // ...
    })
)
<script type="text/javascript">
    function setCellValue(newData, value, currentRowData) {
        return getTaxRates(value).done(function(data) {
            newData.State = value;
            newData.Tax = data.Tax;
        });
    }
    function getTaxRates(state) {
        var promise = $.ajax({
            // The URL returns { State: 1, Tax: 10 }
            url: "https://www.mywebsite.com/api/getTaxRates",
            dataType: "json",
            data: { State: state }
        });
        return promise;
    }
</script>

To invoke the default behavior, call the this.defaultSetCellValue(newData, value) function.

NOTE
The this keyword refers to the column's configuration.

showEditorAlways

Specifies whether the column displays its values using editors.

Type:

Boolean

Default Value: false

A column cell has normal and editing states. In a normal state, the cell value is text. In the editing state, the cell contains an editor that indicates the cell value and allows a user to edit it. In certain cases, a viewer reads the cell value easier if it is indicated by an editor even in the normal state. For example, boolean values are more comprehensible when they are indicated by check boxes. To display editors in cells permanently, set the showEditorAlways option to true.

NOTE

This option has the following peculiarities.

  • The default value of this option depends on the column's dataType. For boolean columns, it is true; for columns of other types - false.
  • If you use templates, setting this option to true means that the column will always use editCellTemplate instead of cellTemplate.
See Also

showInColumnChooser

Specifies whether the column chooser can contain the column header.

Type:

Boolean

Default Value: true

See Also

sortIndex

Specifies the index according to which columns participate in sorting.

Type:

Number

Default Value: undefined
Raised Events: onOptionChanged

This option accepts an integer specifying the index of the column in a collection of columns with applied sorting. For example, consider the following data source that can provide data for three columns.

JavaScript
var dataSource = [
    { firstName: "John", lastName: "Doe", title: "Sales Manager" },
    { firstName: "Michael", lastName: "King", title: "Sales Representative" },
    // ...
];

To sort data first by the "Last Name" and then by the "First Name" column, use the following code. Note that the sortOrder option should also be specified.

jQuery
JavaScript
$(function() {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [
            { dataField: "firstName", sortIndex: 1, sortOrder: "asc" },
            { dataField: "lastName", sortIndex: 0, sortOrder: "asc" },
            // ...
        ]
    });
});
Angular
HTML
TypeScript
<dx-tree-list ... >
    <dxi-column dataField="firstName" [sortIndex]="1" sortOrder="asc"></dxi-column>
    <dxi-column dataField="lastName" [sortIndex]="0" sortOrder="asc"></dxi-column>
</dx-tree-list>
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})

You can set the sortIndex option at design time to specify initial sorting, or change this option using the columnOption method to sort at runtime.

sortingMethod

Specifies a custom comparison function for sorting. Applies only when sorting is performed on the client.

Type:

Function

Function parameters:
value1: any

A value to be compared.

value2: any

A value to be compared.

Return Value:

Number

Specifies whether value1 goes before value2.

Default Value: undefined

This function accepts two cell values and should return a number indicating their sort order:

  • Less than zero
    value1 goes before value2.
  • Zero
    value1 and value2 remain unchanged relative to each other.
  • Greater than zero
    value1 goes after value2.

The string comparison is culture-insensitive by default. Use the following code to make it culture-sensitive:

jQuery
JavaScript
$(function () {
    $("#treeListContainer").dxTreeList({
        // ...
        columns: [{
            dataField: "fieldName",
            sortingMethod: function (value1, value2) {
                // Handling null values
                if(!value1 && value2) return -1;
                if(!value1 && !value2) return 0;
                if(value1 && !value2) return 1;
                // Determines whether two strings are equivalent in the current locale
                return value1.localeCompare(value2);
            }
        }]
    });
});
Angular
TypeScript
HTML
import { DxTreeListModule } from "devextreme-angular";
// ...
export class AppComponent {
    sortStringsConsideringCulture (value1, value2) {
        // Handling null values
        if(!value1 && value2) return -1;
        if(!value1 && !value2) return 0;
        if(value1 && !value2) return 1;
        // Determines whether two strings are equivalent in the current locale
        return value1.localeCompare(value2);
    }
}
@NgModule({
    imports: [
        // ...
        DxTreeListModule
    ],
    // ...
})
<dx-tree-list ... >
    <dxi-column
        dataField="fieldName"
        [sortingMethod]="sortStringsConsideringCulture">
    </dxi-column>
</dx-tree-list>
NOTE
The sortingMethod's value1 and value2 are the values returned from the calculateSortValue function if the latter is specified.
NOTE
The this keyword refers to the column's configuration.

sortOrder

Specifies the sort order of column values.

Type:

String

Default Value: undefined
Accepted Values: undefined | 'asc' | 'desc'
Raised Events: onOptionChanged

By default, rows are sorted according to the data source. Set the sortOrder option to sort rows in a required order. If you need to sort by multiple columns, specify the sortIndex option as well, or otherwise, each sorted column will get a sort index according to the position in the columns array.

Use the SortOrder enum to specify this option when the widget is used as an ASP.NET MVC 5 Control or a DevExtreme-Based ASP.NET Core Control. This enum accepts the following values: Asc and Desc.

See Also

trueText

In a boolean column, replaces all true items with a specified text. Applies only if showEditorAlways option is false.

Type:

String

Default Value: 'true'

See Also

type

Specifies the command column that this object customizes.

Type:

String

Accepted Values: 'adaptive' | 'buttons' | 'drag'

validationRules

Specifies validation rules to be checked when cell values are updated.

NOTE
You can use the AsyncRule only in the Form and Popup editing modes. Other modes do not support async validation.

View Demo

See Also

visible

Specifies whether the column is visible, that is, occupies space in the table.

Type:

Boolean

Default Value: true
Raised Events: onOptionChanged

visibleIndex

Specifies the position of the column regarding other columns in the resulting widget.

Type:

Number

Default Value: undefined
Raised Events: onOptionChanged

Visible indexes are normalized after the widget's creation: the leftmost column is assigned an index of 0; the rightmost column's index becomes equal to the number of visible columns minus 1; other columns get the indexes in between.

IMPORTANT
This index is used in column reordering only. Do not confuse it with the visible column index, which is used to manipulate cells by calling methods, such as getCellElement(rowIndex, visibleColumnIndex), editCell(rowIndex, visibleColumnIndex), etc.
See Also

width

Specifies the column's width in pixels or as a percentage. Ignored if it is less than minWidth.

Type:

Number

|

String

Default Value: undefined

The option supports the following types of values:

  • Number
    The column's width in pixels.
  • String
    A CSS-accepted column width measurement (for example, "55px", "80%" and "auto") except relative units such as em, ch, vh, etc.

    NOTE
    Fixed columns ignore widths specified as a percentage.
See Also