All docs
V19.2
24.1
The page you are viewing does not exist in version 24.1.
23.2
The page you are viewing does not exist in version 23.2.
23.1
The page you are viewing does not exist in version 23.1.
22.2
The page you are viewing does not exist in version 22.2.
22.1
The page you are viewing does not exist in version 22.1.
21.2
The page you are viewing does not exist in version 21.2.
21.1
The page you are viewing does not exist in version 21.1.
20.2
The page you are viewing does not exist in version 20.2.
20.1
The page you are viewing does not exist in version 20.1.
19.2
19.1
18.2
18.1
17.2
Box
Row
Map
Vue
A newer version of this page is available. Switch to the current version.

jQuery DataGrid Options

This section describes the configuration options of the DataGrid widget.

See Also

accessKey

Specifies the shortcut key that sets focus on the widget.

Type:

String

Default Value: null

The value of this option will be passed to the accesskey attribute of the HTML element that underlies the widget.

activeStateEnabled

Specifies whether or not the widget changes its state when interacting with a user.

Type:

Boolean

Default Value: false

This option is used when the widget is displayed on a platform whose guidelines include the active state change for widgets.

allowColumnReordering

Specifies whether a user can reorder columns.

Type:

Boolean

Default Value: false

Initially, columns appear in the order specified by the columns array. If you skip specifying this array, columns will mirror the order of fields in the first object from the dataSource. You can allow a user to reorder columns at runtime by setting the allowColumnReordering option to true.

See Also

allowColumnResizing

Specifies whether a user can resize columns.

Type:

Boolean

Default Value: false

By default, the width of each column depends on the width of the widget and the total number of columns. You can allow a user to resize the columns at runtime by setting the allowColumnResizing option to true.

See Also

autoNavigateToFocusedRow

Automatically scrolls to the focused row when the focusedRowKey is changed.

Type:

Boolean

Default Value: true

cacheEnabled

Specifies whether data should be cached.

Type:

Boolean

Default Value: true

When this option is set to true, data loaded once is saved in cache. Then, the widget takes data from this cache when performing such operations as sorting, grouping, paging, etc. Caching is helpful when the data source takes significant time to load. But, consider disabling it for frequently changing data sources.

To update data in cache, call the refresh() method of the widget or the load() method of the DataSource.

NOTE
If you fetch data from the server, some operations with data can be executed remotely, while others - locally. If you perform basic operations (sorting, filtering, and paging) remotely and advanced operations (grouping and summary calculation) locally, certain user actions will force DataGrid to query the server for data repeatedly despite caching being enabled. Particularly, the advanced operations demand data to be reloaded completely from the server to provide correct results.
See Also

cellHintEnabled

Enables a hint that appears when a user hovers the mouse pointer over a cell with truncated content.

Type:

Boolean

Default Value: true

The cell's content may be truncated if the width of the cell's column becomes very small. In this case, when a user hovers the mouse pointer over such a cell, a hint containing the cell's value appears. To disable cell hints, assign false to the cellHintEnabled option.

columnAutoWidth

Specifies whether columns should adjust their widths to the content.

Type:

Boolean

Default Value: false

When this option is set to true, all columns adjust their width to the content.

If the widget's overall content is narrower than the widget's width, the columns are stretched to fit the widget. To avoid this, set the columns.width option to "auto".

If the content is wider, the columnAutoWidth option set to true causes horizontal scrolling. You can set the allowHiding option to false for columns you want to be displayed continuously.

When the columnAutoWidth option is set to false, all columns have identical width, which in turn depends on the width of the widget.

See Also

columnChooser

Configures the column chooser.

Type:

Object

The column chooser allows a user to hide columns at runtime. To enable it, assign true to the columnChooser.enabled option.

DevExtreme HTML5 JavaScript jQuery Angular Knockout DataGrid Column Chooser

See Also

columnFixing

Configures column fixing.

Type:

Object

When the width of all columns exceeds the widget width, horizontal scrolling appears. If specific columns should be on screen constantly regardless of how far the widget is scrolled, allow a user to fix them at runtime using the context menu. For this, set the columnFixing.enabled option to true.

DevExtreme HTML5 JavaScript jQuery Angular Knockout DataGrid Column Fixing

When you enable column fixing, command columns become fixed automatically.

DataGrid Demo TreeList Demo

See Also

columnHidingEnabled

Specifies whether the widget should hide columns to adapt to the screen or container size. Ignored if allowColumnResizing is true and columnResizingMode is "widget".

Type:

Boolean

Default Value: false

This option set to true makes the widget hide certain columns automatically if all the columns do not fit the widget's width. Columns with low hidingPriority are hidden first. These are the rightmost (leftmost if rtlEnabled is true) columns by default. Information from hidden columns is available in an adaptive detail row.

See Also

columnMinWidth

Specifies the minimum width of columns.

Type:

Number

Default Value: undefined

columnResizingMode

Specifies how the widget resizes columns. Applies only if allowColumnResizing is true.

Type:

String

Default Value: 'nextColumn'
Accepted Values: 'nextColumn' | 'widget'

The columnResizingMode option accepts one of the following values:

  • nextColumn
    When a user resizes a column, the width of the next column changes.
  • widget
    When a user resizes a column, the width of the widget changes.
    This mode is ignored if you specify the width of any column in percent.

columns[]

An array of grid columns.

Default Value: undefined
Raised Events: onOptionChanged

By default, a column is created for each field of a data source object, but in most cases, it is redundant. To specify a set of columns to be created in a grid, assign an array specifying these columns to the columns option. Each grid column is represented in this array by an object containing column settings or by a data source field that this column is bound to. Detailed information on specifying grid columns is given in the Columns Overview article.

Column options define the behavior and appearance of a grid column. One of the other capabilities allows you to control the sorting of column values using the allowSorting and sortOrder options, apply a filter to grid records using the allowFiltering and filterOperations options, and group grid records using the allowGrouping and groupIndex options. In addition, you can change the visibility and width of a column using corresponding options.

To get or set an option or several options for a column at runtime, use the columnOption method with the required arguments.

View Demo

See Also

columnWidth

Specifies the width for all data columns. Has a lower priority than the column.width option.

Type:

Number

Default Value: undefined

See Also

customizeColumns

Customizes columns after they are created.

Type:

Function

Function parameters:

All column configurations.

Use this function to make minor adjustments to automatically generated columns. You can access and modify column configurations using the function's parameter.

jQuery
JavaScript
$(function(){
    $("#dataGrid").dxDataGrid({
        // ...
        customizeColumns: function (columns) {
            columns[0].width = 100;
            columns[1].width = 210;
        }
    })
});
Angular
TypeScript
HTML
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    customizeColumns (columns) {
        columns[0].width = 100;
        columns[1].width = 210;
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
<dx-data-grid ...
    [customizeColumns]="customizeColumns">
</dx-data-grid>
Vue
App.vue
<template>
    <dx-data-grid ...
        :customize-columns="customizeColumns"> 
    />
</template>

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

import DxDataGrid, {
    // ... 
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    },
    methods: {
        customizeColumns(columns) {
            columns[0].width = 100;
            columns[1].width = 210;
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid, {
    // ...
} from 'devextreme-react/data-grid';

class App extends React.Component {
    customizeColumns = (columns) => {
        columns[0].width = 100;
        columns[1].width = 210;
    }

    render() {
        return (
            <DataGrid ...
                customizeColumns={this.customizeColumns}
            />
        );
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    // ...
    .CustomizeColumns("customizeColumns")
)
<script>
    function customizeColumns(columns) {
        columns[0].width = 100;
        columns[1].width = 210;
    }
</script>
NOTE
Data operations (sorting, filtering, summary) are unavailable for the columns created via customizeColumns. To create a fully functioning column, add it to the columns array.

customizeExportData

Customizes data before export. You can use the export.customizeExcelCell function instead.

Type:

Function

Function parameters:

All column configurations.

The Row objects. This array contains only exported rows.

This function is called between the onExporting and onExported functions. This function customizes data; the other functions can be used to customize grid columns.

In the following code, the customizeExportData function replaces empty values with the "Is Blank" value:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        customizeExportData: function (columns, rows) {
            rows.forEach(function (row) {
                var rowValues = row.values;
                for (var i = 0; i < rowValues.length; i++) {
                    if (rowValues[i] == "")
                        rowValues[i] = "Is Blank";
                }
            })
        }
    });
});
Angular
TypeScript
HTML
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    customizeExportData (columns, rows) {
        rows.forEach(function (row) {
            let rowValues =  row.values;
            for(let i = 0; i < rowValues.length; i++) {
                if (rowValues[i] == "")
                    rowValues[i] = "Is Blank";
            }
        })
    };
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
<dx-data-grid ...
    [customizeExportData]="customizeExportData">
</dx-data-grid>
Vue
App.vue
<template>
    <DxDataGrid ...
        :customize-export-data="customizeExportData"
    >
    </DxDataGrid>
</template>

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

import { DxDataGrid } from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    },
    methods: {
        customizeExportData(columns, rows) {
            rows.forEach(function (row) {
                var rowValues = row.values;
                for (var i = 0; i < rowValues.length; i++) {
                    if (rowValues[i] == "")
                        rowValues[i] = "Is Blank";
                }
            })
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ...
                customizeExportData={customizeExportData}
            >
            </{DataGrid}>
        );
    }
}

function customizeExportData(columns, rows) {
    rows.forEach(function (row) {
        var rowValues = row.values;
        for (var i = 0; i < rowValues.length; i++) {
            if (rowValues[i] == "")
                rowValues[i] = "Is Blank";
        }
    })
}

export default App;
See Also

dataSource

Binds the widget to data.

Default Value: null

If you use DevExtreme ASP.NET MVC Controls, refer to the Bind Controls to Data article.

The DataGrid works with collections of objects.

Depending on your data source, bind the DataGrid to data as follows.

  • Data Array
    Assign the array to the dataSource option and specify the keyExpr. View Demo

  • Read-Only Data in JSON Format
    Set the dataSource option to the URL of a JSON file or service that returns JSON data. View Demo

  • OData
    Implement an ODataStore. Make sure to specify the key. View Demo

  • Web API, PHP, MongoDB
    Use one of the following extensions to enable the server to process data according to the protocol DevExtreme widgets use:

    Then, use the createStore method to configure access to the server on the client as shown below. This method is part of DevExtreme.AspNet.Data.

    jQuery
    JavaScript
    $(function() {
        let serviceUrl = "https://url/to/my/service";
        $("#dataGridContainer").dxDataGrid({
            // ...
            dataSource: DevExpress.data.AspNet.createStore({
                key: "ID",
                loadUrl: serviceUrl + "/GetAction",
                insertUrl: serviceUrl + "/InsertAction",
                updateUrl: serviceUrl + "/UpdateAction",
                deleteUrl: serviceUrl + "/DeleteAction"
            })
        })
    });
    Angular
    app.component.ts
    app.component.html
    app.module.ts
    import { Component } from '@angular/core';
    import CustomStore from 'devextreme/data/custom_store';
    import { createStore } from 'devextreme-aspnet-data-nojquery';
    
    @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
    })
    export class AppComponent {
        store: CustomStore;
        constructor() {
            let serviceUrl = "https://url/to/my/service";
            this.store = createStore({
                key: "ID",
                loadUrl: serviceUrl + "/GetAction",
                insertUrl: serviceUrl + "/InsertAction",
                updateUrl: serviceUrl + "/UpdateAction",
                deleteUrl: serviceUrl + "/DeleteAction"
            })
        }
    }
    <dx-data-grid ...
        [dataSource]="store">
    </dx-data-grid>
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { AppComponent } from './app.component';
    
    import { DxDataGridModule } from 'devextreme-angular';
    
    @NgModule({
        declarations: [
            AppComponent
        ],
        imports: [
            BrowserModule,
            DxDataGridModule
        ],
        providers: [],
        bootstrap: [AppComponent]
    })
    export class AppModule { }
    Vue
    App.vue
    <template> 
        <DxDataGrid ...
            :data-source="store" />
    </template>
    
    <script>
    import 'devextreme/dist/css/dx.common.css';
    import 'devextreme/dist/css/dx.light.css';
    
    import CustomStore from 'devextreme/data/custom_store';
    import { createStore } from 'devextreme-aspnet-data-nojquery';
    import { DxDataGrid } from 'devextreme-vue/data-grid';
    
    export default {
        components: {
            DxDataGrid
        },
        data() {
            const serviceUrl = "https://url/to/my/service";
            const store = createStore({
                key: "ID",
                loadUrl: serviceUrl + "/GetAction",
                insertUrl: serviceUrl + "/InsertAction",
                updateUrl: serviceUrl + "/UpdateAction",
                deleteUrl: serviceUrl + "/DeleteAction"
            });
            return {
                store
            }
        }
    }
    </script>
    React
    App.js
    import React from 'react';
    import 'devextreme/dist/css/dx.common.css';
    import 'devextreme/dist/css/dx.light.css';
    
    import CustomStore from 'devextreme/data/custom_store';
    import { createStore } from 'devextreme-aspnet-data-nojquery';
    import DataGrid from 'devextreme-react/data-grid';
    
    const serviceUrl = "https://url/to/my/service";
    const store = createStore({
        key: "ID",
        loadUrl: serviceUrl + "/GetAction",
        insertUrl: serviceUrl + "/InsertAction",
        updateUrl: serviceUrl + "/UpdateAction",
        deleteUrl: serviceUrl + "/DeleteAction"
    });
    
    class App extends React.Component {
        render() {
            return (
                <DataGrid ...
                    dataSource={store} />
            );
        }
    }
    export default App;

    View Demo

  • Any other data source
    Implement a CustomStore. View Demo

Regardless of the data source on the input, the DataGrid always wraps it in the DataSource object. This object allows you to sort, filter, group, and perform other data shaping operations. To get its instance, call the getDataSource() method.

NOTE

Please review the following notes about data binding:

  • Data field names should not contain the following characters: ., ,, :, [, and ].

  • If the DataGrid widget gets data from a server, configure remoteOperations to notify the widget about data operations the server performs.

  • Features like export and selection work incorrectly with mapped data objects. Use calculated columns instead of mapping.

  • DataSource and stores provide methods to process and update data. However, the methods do not allow you to perform particular tasks (for example, replace the entire dataset, reconfigure data access at runtime). For such tasks, create a new array, store, or DataSource and assign it to the dataSource option as shown in the articles about changing options in jQuery, Angular, React, and Vue.

dateSerializationFormat

Specifies the format in which date-time values should be sent to the server. Use it only if you do not specify the dataSource at design time.

Type:

String

Without a data source, the widget cannot detect the date-time values' format. In this case, specify the dateSerializationFormat option that supports the following formats:

  • "yyyy-MM-dd" - a local date

  • "yyyy-MM-ddTHH:mm:ss" - local date and time

  • "yyyy-MM-ddTHH:mm:ssZ" - the UTC date and time

  • "yyyy-MM-ddTHH:mm:ssx" - date and time with a timezone

This option applies only if the forceIsoDateParsing field is set to true in the global configuration object.

See Also

disabled

Specifies whether the widget responds to user interaction.

Type:

Boolean

Default Value: false

editing

Configures editing.

Type:

Object

The widget can allow a user to add, update and delete data. To control which of these operations are allowed, use the allowAdding, allowUpdating and allowDeleting options. Editing can be carried out in different modes, which are detailed in the mode option's description.

NOTE
Before allowing a user to add, update, and delete, make sure that your data source supports these actions.

View Demo

See Also

elementAttr

Specifies the attributes to be attached to the widget's root element.

Type:

Object

Default Value: {}

jQuery
$(function(){
    $("#dataGridContainer").dxDataGrid({
        // ...
        elementAttr: {
            id: "elementId",
            class: "class-name"
        }
    });
});
Angular
HTML
TypeScript
<dx-data-grid ...
    [elementAttr]="{ id: 'elementId', class: 'class-name' }">
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ...
        :element-attr="dataGridAttributes">
    </DxDataGrid>
</template>

<script>
import DxDataGrid from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    },
    data() {
        return {
            dataGridAttributes: {
                id: 'elementId',
                class: 'class-name'
            }
        }
    }
}
</script>
React
App.js
import React from 'react';

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    dataGridAttributes = {
        id: 'elementId',
        class: 'class-name'
    }

    render() {
        return (
            <DataGrid ...
                elementAttr={this.dataGridAttributes}>
            </DataGrid>
        );
    }
}
export default App;

errorRowEnabled

Indicates whether to show the error row.

Type:

Boolean

Default Value: true

The error row displays data-related errors that may occur on the server during the widget's runtime. Setting this option to false hides the error row, but the errors can still be viewed in the browser's console.

See Also

export

Configures client-side exporting.

Type:

Object

When client-side exporting is enabled, the grid toolbar contains the Export button ( DevExtreme DataGrid HTML5 Toolbar Exporting ) that exports grid data to Excel. For details on exporting, refer to the Client-Side Exporting article.

NOTE
Client-side exporting requires the JSZip library. Learn where you can get it from topics in the Installation section.

View Demo

filterBuilder

Configures the integrated filter builder.

Default Value: {}

See the FilterBuilder configuration for options that you can specify in this object.

NOTE
In Angular and Vue, the nested component that configures the filterBuilder option does not support event bindings and two-way property bindings.
See Also

filterBuilderPopup

Configures the popup in which the integrated filter builder is shown.

Default Value: {}

See the Popup configuration for options that you can specify in this object.

NOTE
In Angular and Vue, the nested component that configures the filterBuilderPopup option does not support event bindings and two-way property bindings.
See Also

filterPanel

Configures the filter panel.

Type:

Object

Default Value: {}

The filter panel displays the applied filter expression.

DevExtreme HTML5 JavaScript jQuery Angular Knockout DataGrid Filter Panel

Clicking on the filter expression opens the filter builder.

DevExtreme HTML5 JavaScript jQuery Angular Knockout DataGrid Filter Panel

If you change the filter expression in the filter panel or filter builder, the changes are reflected in the filter row and header filter, and vice versa. You can disable this synchronization by setting the filterSyncEnabled option to false. In this case, the filter panel remains synchronized with the filter builder.

See Also

filterRow

Configures the filter row.

Type:

Object

The filter row allows a user to filter data by values of individual columns.

DevExtreme HTML5 JavaScript jQuery Angular Knockout DataGrid FilterRow

Each cell in the filter row contains a magnifying glass icon, pausing on which opens a drop-down list with filters available for the column.

DevExtreme HTML5 JavaScript jQuery Angular Knockout DataGrid FilterRow

To make the filter row visible, assign true to the filterRow.visible option.

View Demo

See Also

filterSyncEnabled

Specifies whether to synchronize the filter row, header filter, and filter builder. The synchronized filter expression is stored in the filterValue option.

Type:

Boolean

|

String

Default Value: 'auto'
Accepted Values: 'auto'

Synchronization is enabled if the filter panel is visible. When it is enabled, check that each column that allows filtering has the dataField or name option specified.

filterValue

Specifies a filter expression.

Default Value: null
Raised Events: onOptionChanged

If filterSyncEnabled is true, the filter expression includes a combination of the filter row, header filter, and filter builder filters. Otherwise, it contains only the filter builder filter.

The filter expression can contain the following operations: "=", "<>", "<", ">", "<=", ">=", "between", "contains", "notcontains", "startswith", "endswith", "anyof", "noneof", and the filter builder's custom operations. Use "anyof" and "noneof" to select and clear the selection of items in the header filter's popup menu. In the following code, "anyof" is used to select items with IDs 500 and 700:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        filterSyncEnabled: true,
        headerFilter: { visible: true },
        filterValue: ["ID", "anyof", [500, 700]], 
    })
});
Angular
HTML
TypeScript
<dx-data-grid ...
    [filterSyncEnabled]="true"
    [filterValue]="['ID', 'anyof', [500, 700]]"> 
    <dxo-header-filter 
        [visible]="true">
    </dxo-header-filter>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ...
        :filter-sync-enabled="true"
        :filter-value="filterValue"> 
        <DxHeaderFilter :visible="true" />
    </DxDataGrid>
</template>

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

import DxDataGrid, {
    DxHeaderFilter,
    // ...
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxHeaderFilter,
        // ...
    },
    data() {
        return {
            filterValue: ['ID', 'anyof', [500, 700]]
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid, {
    HeaderFilter,
    // ...
} from 'devextreme-react/data-grid';

const filterValue = ['ID', 'anyof', [500, 700]];

class App extends React.Component {
    render() {
        return (
            <DataGrid ...
                filterSyncEnabled={true}
                defaultFilterValue={filterValue}>
                <HeaderFilter visible={true} />
            </DataGrid>
        );
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    // ...
    .FilterSyncEnabled(true)
    .HeaderFilter(hf => hf.Visible(true))
    .FilterValue("['ID', 'anyof', [500, 700]]")
)

If a column's groupInterval option is set, the "anyof" and "noneof" operations for this column accept the beginning of intervals instead of exact values:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        headerFilter: { visible: true },
        filterValue: ["ID", "anyof", [500, 700]], // Filter intervals are 500-600 and 700-800
        columns: [{
            dataField: "ID",
            dataType: "number",
            headerFilter: { groupInterval: 100 }
        },
        // ...
        ]
    })
});
Angular
HTML
TypeScript
<dx-data-grid ...
    <!-- Filter intervals are 500-600 and 700-800 -->
    [(filterValue)]="['ID', 'anyof', [500, 700]]">
        <dxo-header-filter 
            [visible]="true">
        </dxo-header-filter>
        <dxi-column
            dataField="ID"
            dataType="number">
                <dxo-header-filter 
                    [groupInterval]="100">
                </dxo-header-filter>
        </dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ...
        <!-- Filter intervals are 500-600 and 700-800 -->
        :filter-value="filterValue">
        <DxHeaderFilter :visible="true" />
        <DxColumn
            data-field="ID"
            data-type="number">
            <DxColumnHeaderFilter :group-interval="100" />
        </DxColumn>
    </DxDataGrid>
</template>

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

import DxDataGrid, {
    DxColumn,
    DxHeaderFilter,
    DxColumnHeaderFilter,
    // ...
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxColumn,
        DxHeaderFilter,
        DxColumnHeaderFilter,
        // ...
    },
    data() {
        return {
            filterValue: ['ID', 'anyof', [500, 700]]
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid, {
    Column,
    HeaderFilter,
    ColumnHeaderFilter,
    // ...
} from 'devextreme-react/data-grid';

const filterValue = ['ID', 'anyof', [500, 700]];

class App extends React.Component {
    render() {
        return (
            <DataGrid ...
                {/* Filter intervals are 500-600 and 700-800 */}
                defaultFilterValue={filterValue}>
                <HeaderFilter visible={true} />
                <Column
                    dataField="ID"
                    dataType="number">
                    <ColumnHeaderFilter groupInterval={100} />
                </Column>
            </DataGrid>
        );
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    // ...
    // Filter intervals are 500-600 and 700-800
    .HeaderFilter(headerFilter => headerFilter.Visible(true))
    .FilterValue("['ID', 'anyof', [500, 700]]")
    .Columns(columns => {
        columns.AddFor(m => m.ID)
            .DataType(GridColumnDataType.Number)
            .HeaderFilter(hf => hf.GroupInterval(100));
        // ...
    })
)
NOTE
The DataSource does not support the "anyof", "noneof", and custom operations. Use the getCombinedFilter(returnDataField) method to get the DataSource-compatible filter expression.
See Also

focusedColumnIndex

The index of the column that contains the focused data cell.

Type:

Number

Default Value: -1
Raised Events: onFocusedCellChanged

This index changes when users do the following:

  • Navigate through cells
  • Reorder the columns
  • Hide the columns

The following image illustrates the indexing system:

DevExtreme HTML5 JavaScript DataGrid Column Index

Band columns do not have indexes and cannot be focused. However, users can focus banded columns.

The default index, -1, means that no column is focused.

See Also

focusedRowEnabled

Specifies whether the focused row feature is enabled.

Type:

Boolean

Default Value: false

When this option is set to true, the following applies:

NOTE
Specify the widget's keyExpr or the Store's key option to ensure that the focused row feature works properly.

View Demo

See Also

focusedRowIndex

Specifies the initially or currently focused grid row's index. Use it when focusedRowEnabled is true.

Type:

Number

Default Value: -1
Raised Events: onFocusedRowChanged

The focused row has a key and index on a page. When the pager is used for navigation, the focused row's index persists from page to page but corresponds to a different row with a different key on each page.

The default index, -1, means that no row is focused.

The focusedRowKey takes precedence over the focusedRowIndex when both are specified.

See Also

focusedRowKey

Specifies initially or currently focused grid row's key. Use it when focusedRowEnabled is true.

Type: any
Default Value: undefined
Raised Events: onFocusedRowChanged

The focused row has a key and index on a page. When the pager is used for navigation, the focused row's index persists from page to page but corresponds to a different row with a different key on each page.

In the DataGrid, group rows can also be focused. See the Group Index and Key topic for more information on how group keys are formed.

View Demo

See Also

focusStateEnabled

Specifies whether the widget can be focused using keyboard navigation.

Type:

Boolean

Default Value: false

grouping

Configures grouping.

Type:

Object

View Demo

See Also

groupPanel

Configures the group panel.

Type:

Object

Data in DataGrid can be grouped by one column or by several. Once a column is used for grouping, it is added to the group panel.

By default, the group panel is hidden. To make it visible, set the groupPanel.visible option to true. Alternatively, the visibility of the group panel can depend on the device's screen size. To accomplish this behavior, set the visible option to "auto".

In case you need to show the group panel, but make it irresponsive, assign false to the groupPanel.allowColumnDragging option. This is useful, for instance, when grid records are grouped initially and when the user needs to know about that grouping, but must not be able to change it.

See Also

View Demo

headerFilter

Configures the header filter feature.

Type:

Object

A header filter allows a user to filter values in an individual column by including/excluding them in/from the applied filter. A click on a header filter icon invokes a popup menu with all unique values in the column. By selecting or clearing the selection of values in this menu, the user includes/excludes them in/from the filter.

DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid HeaderFilter

To make header filter icons visible, assign true to the headerFilter.visible option.

A header filter's popup menu lists all column values. If they are numbers or dates, you can group them using the groupInterval option in the column's headerFilter. You can also provide a custom data source for a header filter using the dataSource option.

View Demo

The user's filtering preferences are saved in the filterValues option. The header filter's Select All checkbox changes the filterType option.

See Also

height

Specifies the widget's height.

Type:

Number

|

String

|

Function

Return Value:

Number

|

String

The widget's height.

Default Value: undefined

This option accepts a value of one of the following types:

  • Number
    The height in pixels.

  • String
    A CSS-accepted measurement of height. For example, "55px", "80%", "inherit".

  • Function
    A function returning either of the above. For example:

    JavaScript
    height: function() {
        return window.innerHeight / 1.5;
    }

highlightChanges

Specifies whether to highlight rows and cells with edited data. repaintChangesOnly should be true.

Type:

Boolean

Default Value: false

You can change the following CSS rules and classes that control highlighting:

CSS
@keyframes dx-datagrid-highlight-change {
    from {
        background-color: #efefef;
    }
    50% {
        background-color: #efefef;
    }
}
.dx-datagrid-cell-updated-animation {
    animation: dx-datagrid-highlight-change 1s;
}
.dx-datagrid-row-inserted-animation {
    animation: dx-datagrid-highlight-change 1s;
}

hint

Specifies text for a hint that appears when a user pauses on the widget.

Type:

String

Default Value: undefined

hoverStateEnabled

Specifies whether to highlight rows when a user moves the mouse pointer over them.

Type:

Boolean

Default Value: false

keyboardNavigation

Configures keyboard navigation.

Type:

Object

keyExpr

Specifies the key property (or properties) that provide(s) key values to access data items. Each key value must be unique. This option applies only if data is a simple array.

Type:

String

|

Array<String>

Default Value: undefined

loadPanel

Configures the load panel.

Type:

Object

The load panel is displayed while the widget loads data. It consists of a loading indicator and text, both placed on a pane.

DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid TreeList LoadPanel

Since the load panel is, in fact, the DevExtreme LoadPanel widget, the loadPanel object can contain any options of this widget along with options described here.

See Also

masterDetail

Allows you to build a master-detail interface in the grid.

Type:

Object

In DataGrid, a master-detail interface supplies a usual data row with an expandable section that contains the details on this data row. In that case, the data row is called "master row", while the section is called "detail section".

To enable the master-detail interface, assign true to the masterDetail.enabled option. After that, specify the template for detail sections using the masterDetail.template option. Templates allow you to place virtually anything into the detail sections. For example, you can display another DataGrid or any other UI widget there. For more information on specifying the template for the detail sections, see the template option description.

View Demo

See Also

noDataText

Specifies text shown when the widget does not display any data.

Type:

String

Default Value: 'No data'

onAdaptiveDetailRowPreparing

A function that is executed before an adaptive detail row is rendered.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

formOptions

Object

The options of the Form widget.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

Adaptive detail rows display information from columns that were hidden when the widget adapted to the screen or container size. Each adaptive detail row contains the Form widget that you can customize within the onAdaptiveDetailRowPreparing function using the formOptions object. Refer to the Form Configuration section for details on options of the Form widget.

NOTE

The following Form options cannot be specified using formOptions:

See Also

onCellClick

A function that is executed when a cell is clicked or tapped. Executed before onRowClick.

Type:

Function

|

String

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cellElement

HTMLElement | jQuery

The cell's container. It is an HTML Element or a jQuery Element when you use jQuery.

column

Object

This column's configuration.

columnIndex

Number

The index of the column to which the cell belongs. For details on indexes, see the Column and Row Indexes topic.

component

DataGrid

The widget's instance.

data

Object

The data of the row to which the cell belongs.

displayValue any

The cell's displayed value. Differs from the value field only when the column to which the clicked cell belongs uses lookup.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

event

Event (jQuery or EventObject)

The event that caused the function to execute. It is a dxEvent or a jQuery.Event when you use jQuery.

jQueryEvent

jQuery.Event

Use 'event' instead.

The jQuery event that caused the handler execution. Deprecated in favor of the event field.

key any

The row's key. If a field providing keys is not specified in the data source, the whole data object is considered the key.

model

Object

Model data. Available only if you use Knockout.

row

DataGrid Row

The row properties.

rowIndex

Number

The index of the row to which the cell belongs. Refer to Column and Row Indexes for more information.

rowType

String

The type of the row to which the clicked cell belongs.

text

String

The cell's formatted value converted to a string.

value any

The cell's raw value.

Default Value: null

onCellDblClick

A function that is executed when a cell is double-clicked or double-tapped. Executed before onRowDblClick.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cellElement

HTMLElement | jQuery

The cell's container. It is an HTML Element or a jQuery Element when you use jQuery.

column

DataGrid Column

The column's configuration.

columnIndex

Number

The index of the column the cell belongs to. For details on indexes, see the Column and Row Indexes topic.

component

DataGrid

The widget's instance.

data

Object

The data of the row the cell belongs to. Available if the rowType is "data", "detail", or "detailAdaptive".

displayValue any

The value displayed in the cell. Available if the rowType is "data" or "group".
Differs from the value field only when the cell belongs to a lookup column.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

event

Event (jQuery or EventObject)

The event that caused the function to execute. It is a dxEvent or a jQuery.Event when you use jQuery.

key any

The row's key or a group row's key. Available if the rowType is "data", "detail", "detailAdaptive", or "group".

model

Object

Model data. Available only if you use Knockout.

row

DataGrid Row

The row's properties. Available if the rowType is "data", "detail", "detailAdaptive", or "group".

rowIndex

Number

The index of the row the cell belongs to.

rowType

String

The row's type.

text

String

The cell's formatted value converted to a string. Available if the rowType is "data" or "group".

value any

The cell's raw value. Available if the rowType is "data" or "group".

Default Value: null

onCellHoverChanged

A function that is executed after the pointer enters or leaves a cell.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cellElement

HTMLElement | jQuery

The cell's container. It is an HTML Element or a jQuery Element when you use jQuery.

column

DataGrid Column

This column's configuration.

columnIndex

Number

The index of the column to which the cell belongs. For details on indexes, see the Column and Row Indexes topic.

component

DataGrid

The widget's instance.

data

Object

The data of the row to which the cell belongs.

displayValue any

The cell's displayed value. Differs from the value field only when the column to which the current cell belongs uses lookup.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

eventType

String

Indicates whether the pointer entered or left the cell. Can be either "mouseover" or "mouseout".

key any

The row's key. If a field providing keys is not specified in the data source, the whole data object is considered the key.

model

Object

Model data. Available only if you use Knockout.

row

DataGrid Row

The row properties.

rowIndex

Number

The row's index. Refer to Column and Row Indexes for more information.

rowType

String

The row's type.

text

String

The cell's formatted value converted to a string.

value any

The cell's raw value.

Default Value: null

To identify whether the pointer has entered or left the cell, check the eventType field's value.

onCellPrepared

A function that is executed after a cell is created.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cellElement

HTMLElement | jQuery

The cell's container. It is an HTML Element or a jQuery Element when you use jQuery.

column

DataGrid Column

This column's configuration.

columnIndex

Number

The index of the column to which the cell belongs. For details on indexes, see the Column and Row Indexes topic.

component

DataGrid

The widget's instance.

data

Object

The data of the row to which the cell belongs. Unavailable if rowType is "header", "filter", or "totalFooter".

displayValue any

The cell's displayed value. Differs from the value field only when the column to which the prepared cell belongs uses lookup.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

isExpanded

Boolean

Indicates whether the row is expanded or collapsed. Unavailable if rowType is "header", "filter", or "totalFooter".

isNewRow

Boolean

Indicates that the row is added, but not yet saved. Available if rowType is "data".

isSelected

Boolean

Indicates whether the row is selected.

key any

The row's key. Unavailable if rowType is "header", "filter", or "totalFooter".
If a field providing keys is not specified in the data source, the whole data object is considered the key.

model

Object

Model data. Available only if you use Knockout.

oldValue any

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

row

DataGrid Row

The row properties.

rowIndex

Number

The row's index. Refer to Column and Row Indexes for more information.

rowType

String

The row's type.

text

String

The cell's formatted value converted to a string.

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.

Default Value: null

View Demo

In the following code, the onCellPrepared function is used to change a ProductName's color depending on the Amount of sold products. You can paste this code in the Real-Time Updates demo and see how it works.

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        repaintChangesOnly: true,
        onCellPrepared: function(e) {
            if(e.rowType === "data" && e.column.dataField === "ProductName") {
                e.cellElement.css("color", e.data.Amount >= 10000 ? "green" : "red");
                // Tracks the `Amount` data field
                e.watch(function() {
                    return e.data.Amount;
                }, function() {
                    e.cellElement.css("color", e.data.Amount >= 10000 ? "green" : "red");
                })
            }
        }
    })
})
Angular
TypeScript
HTML
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    onCellPrepared(e) {
        if(e.rowType === "data" && e.column.dataField === "ProductName") {
            e.cellElement.style.color = e.data.Amount >= 10000 ? "green" : "red";
            // Tracks the `Amount` data field
            e.watch(function() {
                return e.data.Amount;
            }, function() {
                e.cellElement.style.color = e.data.Amount >= 10000 ? "green" : "red";
            })
        }
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
<dx-data-grid ...
    [repaintChangesOnly]="true"
    (onCellPrepared)="onCellPrepared($event)">
</dx-data-grid>
Vue
App.vue
<template>
    <DxDataGrid
        :repaint-changes-only="true"
        @cell-prepared="onCellPrepared"
    />
</template>

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

import DataGrid from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    },
    methods: {
       onCellPrepared(e) {
            if(e.rowType === "data" && e.column.dataField === "ProductName") {
                e.cellElement.style.color = e.data.Amount >= 10000 ? "green" : "red";
                // Tracks the `Amount` data field
                e.watch(function() {
                    return e.data.Amount;
                }, function() {
                    e.cellElement.style.color = e.data.Amount >= 10000 ? "green" : "red";
                })
            }
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    // ...
    render() {
        return (
            <DataGrid
                 repaintChangesOnly={true}
                 onCellPrepared={this.onCellPrepared}
            />
        );
    }
    onCellPrepared = (e) => {
        if(e.rowType === "data" && e.column.dataField === "ProductName") {
            e.cellElement.style.color = e.data.Amount >= 10000 ? "green" : "red";
            // Tracks the `Amount` data field
            e.watch(function() {
                return e.data.Amount;
            }, function() {
                e.cellElement.style.color = e.data.Amount >= 10000 ? "green" : "red";
            })
        }
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    .ID("dataGridContainer")
    // ...
    .RepaintChangesOnly(true)
    .OnCellPrepared("dataGrid_cellPrepared_handler")
)
<script>
    function dataGrid_cellPrepared_handler(e) {
        if (e.rowType === "data" && e.column.dataField === "ProductName") {
            e.cellElement.css("color", e.data.Amount >= 10000 ? "green" : "red");
            // Tracks the `Amount` data field
            e.watch(function() {
                return e.data.Amount;
            }, function() {
                e.cellElement.css("color", e.data.Amount >= 10000 ? "green" : "red");
            })
        }
    }
</script>
See Also

onContentReady

A function that is executed when the widget's content is ready and each time the content is changed.

Type:

Function

Function parameters:
e:

Object

Information about the event.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Available only when using Knockout.

Default Value: null

onContextMenuPreparing

A function that is executed before the context menu is rendered.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
column

DataGrid Column

This column's configuration.

columnIndex

Number

The index of the column on which the context menu is invoked. For details on indexes, see the following help topic: Column and Row Indexes.

component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

items

Array<Object>

Items to be displayed in the context menu. Their structure is described in the items option description. Each item also contains the onItemClick event handler, which allows you to access the clicked or tapped item's data.

model

Object

Model data. Available only if you use Knockout.

row

DataGrid Row

The row properties.

rowIndex

Number

The index of the row on which the context menu is invoked. Refer to the following help topic for more information: Column and Row Indexes.

target

String

The name of the element on which the context menu is invoked: "headerPanel", "header", "content", or "footer". This field is read-only.

targetElement

HTMLElement | jQuery

The grid element's container. It is an HTML Element or a jQuery Element when you use jQuery.

Default Value: null

In the following code, the onContextMenuPreparing function adds a custom item to the context menu invoked when a user right-clicks any column header:

jQuery
index.js
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        onContextMenuPreparing: function(e) { 
            if (e.target == "header") {
                // e.items can be undefined
                if (!e.items) e.items = [];

                // Add a custom menu item
                e.items.push({
                    text: "Log Column Caption",
                    onItemClick: function() {
                        console.log(e.column.caption);
                    }
                });
            } 
        }
    });
});
Angular
app.component.html
app.component.ts
app.module.ts
<dx-data-grid ...
    (onContextMenuPreparing)="addMenuItems($event)">
</dx-data-grid>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    addMenuItems(e) { 
        if (e.target == 'header') {
            // e.items can be undefined
            if (!e.items) e.items = [];

            // Add a custom menu item
            e.items.push({
                text: 'Log Column Caption',
                onItemClick: () => {
                    console.log(e.column.caption);
                }
            });
        } 
    }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { DxDataGridModule } from 'devextreme-angular';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        DxDataGridModule
    ],
    providers: [ ],
    bootstrap: [AppComponent]
})
export class AppModule { }
Vue
App.vue
<template>
    <DxDataGrid ...
        @context-menu-preparing="addMenuItems">
    </DxDataGrid>
</template>

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

import DxDataGrid from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    },
    data() {
        return {
            // ...
        }
    },
    methods: {
        addMenuItems(e) {
            if (e.target == 'header') {
                // e.items can be undefined
                if (!e.items) e.items = [];

                // Add a custom menu item
                e.items.push({
                    text: 'Log Column Caption',
                    onItemClick: () => {
                        console.log(e.column.caption);
                    }
                });
            } 
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    addMenuItems(e) {
        if (e.target == 'header') {
            // e.items can be undefined
            if (!e.items) e.items = [];

            // Add a custom menu item
            e.items.push({
                text: 'Log Column Caption',
                onItemClick: () => {
                    console.log(e.column.caption);
                }
            });
        }
    }

    render() {
        return (
            <DataGrid ...
                onContextMenuPreparing={this.addMenuItems}>
            </DataGrid>
        );
    }
}
export default App;

onDataErrorOccurred

A function that is executed when an error occurs in the data source.

Type:

Function

Function parameters:
e:

Object

Information on the occurred error.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

error

JavaScript Error Object

The standard Error object that defines the error.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

Handles errors that might occur in the data source. To obtain a human-readable description of the error in the function, use the error.message field.

onDisposing

A function that is executed before the widget is disposed of.

Type:

Function

Function parameters:
e:

Object

Information about the event.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

onEditingStart

A function that is executed before a cell or row switches to the editing state.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cancel

Boolean

Allows you to cancel row editing.

column

Object

The configuration of the column whose cell is switching to the editing state. Available in the "batch" editing mode.

component

DataGrid

The widget's instance.

data

Object

The data of a row to be edited.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

key any

The row's key. The key of an added but not yet saved row is undefined.
If a field providing keys is not specified in the data source, the whole data object is considered the key.

model

Object

Model data. Available only if Knockout is used.

Default Value: null

If the editing.mode is "batch" or "cell", this function is executed while the widget renders columns of boolean dataType and other columns whose showEditorAlways option is true.

View Demo

onEditorPrepared

A function that is executed after an editor is created. Not executed for cells with an editCellTemplate.

Type:

Function

Function parameters:
options:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

dataField

String

The name of the field that provides data for the column the editor belongs to.

disabled

Boolean

Indicates whether the editor is disabled.

editorElement

HTMLElement | jQuery

The editor's container. It is an HTML Element or a jQuery Element when you use jQuery.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Only available when using Knockout.

parentType

String

The editor's location. One of "dataRow", "filterRow", "headerRow" or "searchPanel".
Options passed to the function depend on this value.

readOnly

Boolean

Indicates whether the editor is read-only.

row

DataGrid Row

The properties of the row the editor belongs to.

rtlEnabled

Boolean

Indicates whether the editor uses right-to-left representation.

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.

updateValueTimeout

Number

Gets and sets the delay between when a user stops typing a filter value and the change is applied. Available if the parentType is "filterRow" or "searchPanel".

value any

The editor's value.

width

Number

The editor's width; equals null for all editors except for those whose parentType equals "searchPanel".

Default Value: null

onEditorPreparing

A function used to customize a cell's editor. Not executed for cells with an editCellTemplate.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cancel

Boolean

Allows you to cancel the editor's creation.
You can set this field's value to true and implement a custom editor.

component

DataGrid

The widget's instance.

dataField

String

The name of the field that provides data for the column's editor.

disabled

Boolean

Indicates whether the editor is disabled.

editorElement

HTMLElement | jQuery

The editor's container. It is an HTML Element or a jQuery Element when you use jQuery.

editorName

String

Allows you to change the editor. Accepts names of DevExtreme widgets only, for example, "dxTextBox".
Import a new editor's module when DevExtreme modules are used. The editorType option specified in the editing.form object has precedence over this parameter.

editorOptions

Object

Gets and sets the editor's configuration. editorOptions specified in the editing.form object have precedence over this parameter.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Available only if you use Knockout.

parentType

String

The editor's location. One of "dataRow", "filterRow", "headerRow" or "searchPanel".
Options passed to the function depend on this value.

readOnly

Boolean

Indicates whether the editor is read-only.

row

DataGrid Row

The properties of the row's editor.

rtlEnabled

Boolean

Indicates whether the editor uses right-to-left representation.

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.

updateValueTimeout

Number

Gets and sets the delay between when a user stops typing a filter value and the change is applied. Available if the parentType is "filterRow" or "searchPanel".

value any

The editor's value. This field is read-only. To change the editor's value, use the setValue(newValue, newText) function parameter.

width

Number

The editor's width; equals null for all editors except for those whose parentType equals "searchPanel".

Default Value: null

Use this function to:

  • Override the default editor's onValueChanged handler. For other default editor customizations, use editorOptions.

    jQuery
    index.js
    $(function() {
        $("#dataGridContainer").dxDataGrid({
            // ...
            onEditorPreparing: function(e) {
                if (e.dataField === "requiredDataField" && e.parentType === "dataRow") {
                    var standardHandler = e.editorOptions.onValueChanged;
                    e.editorOptions.onValueChanged = function(e) { // Overrides the standard handler
                        // ...
                        // Custom commands go here
                        // ...
                        standardHandler(e); // Calls the standard handler to save the edited value
                    }
                }
            }
        });
    });
    Angular
    app.component.html
    app.component.ts
    app.module.ts
    <dx-data-grid ...
        (onEditorPreparing)="overrideOnValueChanged($event)">
    </dx-data-grid>
    import { Component } from '@angular/core';
    
    @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
    })
    export class AppComponent {
        overrideOnValueChanged(e) {
            if (e.dataField === 'requiredDataField' && e.parentType === 'dataRow') {
                let standardHandler = e.editorOptions.onValueChanged;
                e.editorOptions.onValueChanged = function (e) { // Overrides the standard handler
                    // ...
                    // Custom commands go here
                    // ...
                    standardHandler(e); // Calls the standard handler to save the edited value
                }
            }
        }
    }
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { AppComponent } from './app.component';
    
    import { DxDataGridModule } from 'devextreme-angular';
    
    @NgModule({
        declarations: [
            AppComponent
        ],
        imports: [
            BrowserModule,
            DxDataGridModule
        ],
        providers: [],
        bootstrap: [AppComponent]
    })
    export class AppModule { }
    Vue
    App.vue
    <template>
        <DxDataGrid ...
            @editor-preparing="overrideOnValueChanged">
        </DxDataGrid>
    </template>
    
    <script>
    import 'devextreme/dist/css/dx.common.css';
    import 'devextreme/dist/css/dx.light.css';
    
    import DxDataGrid from 'devextreme-vue/data-grid';
    
    export default {
        components: {
            DxDataGrid
        },
        // ...
        methods: {
            overrideOnValueChanged(e) {
                if (e.dataField === 'requiredDataField' && e.parentType === 'dataRow') {
                    let standardHandler = e.editorOptions.onValueChanged;
                    e.editorOptions.onValueChanged = function (e) { // Overrides the standard handler
                        // ...
                        // Custom commands go here
                        // ...
                        standardHandler(e); // Calls the standard handler to save the edited value
                    }
                }
            }
        }
    }
    </script>
    React
    App.js
    import React from 'react';
    
    import 'devextreme/dist/css/dx.common.css';
    import 'devextreme/dist/css/dx.light.css';
    
    import DataGrid from 'devextreme-react/data-grid';
    
    class App extends React.Component {
        overrideOnValueChanged(e) {
            if (e.dataField === 'requiredDataField' && e.parentType === 'dataRow') {
                let standardHandler = e.editorOptions.onValueChanged;
                e.editorOptions.onValueChanged = function (e) { // Overrides the standard handler
                    // ...
                    // Custom commands go here
                    // ...
                    standardHandler(e); // Calls the standard handler to save the edited value
                }
            }
        }
        render() {
            return (
                <DataGrid ...
                    onEditorPreparing={this.overrideOnValueChanged}>
                </DataGrid>
            );
        }
    }
    export default App;
    ASP.NET MVC Controls
    Razor C#
    @(Html.DevExtreme().DataGrid()
        // ...
        .OnEditorPreparing("overrideOnValueChanged")
    )
    
    <script type="text/javascript">
        function overrideOnValueChanged(e) {
            if (e.dataField === "requiredDataField" && e.parentType === "dataRow") {
                var standardHandler = e.editorOptions.onValueChanged;
                e.editorOptions.onValueChanged = function(e) { // Overrides the standard handler
                    // ...
                    // Custom commands go here
                    // ...
                    standardHandler(e); // Calls the standard handler to save the edited value
                }
            }
        }
    </script>
  • Customize editors used in the search panel, filter row, and selection column.
    Use the parentType function parameter to check if the editor being customized belongs to one of these UI elements.

  • Dynamically change editor options in the editing state.

  • Implement other customization cases.

View Demo

NOTE
We do not recommend that you use the onEditorPreparing function to specify an editor's default value. Use the onInitNewRow function instead.
See Also

onExported

A function that is executed after data is exported.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Available only if Knockout is used.

Default Value: null

You can use this function with the onExporting function to adjust columns before exporting. See an example in the onExporting description.

See Also

onExporting

A function that is executed before data is exported.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function execution.

Object structure:
Name Type Description
cancel

Boolean

Allows you to cancel exporting data.

component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

fileName

String

The name of the file where grid data is about to be exported.

model

Object

Model data. Available only if Knockout is used.

Default Value: null

You can use this function with the onExported function to adjust columns before export. In the following code, these functions are used to export a hidden ID column:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        columns: [{
            dataField: "ID",
            visible: false
        }, // ...
        ]
        onExporting: function (e) {
            e.component.beginUpdate();
            e.component.columnOption("ID", "visible", true);
        },
        onExported: function (e) {
            e.component.columnOption("ID", "visible", false);
            e.component.endUpdate();
        }
    });
});
Angular
TypeScript
HTML
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    onExporting (e) {
        e.component.beginUpdate();
        e.component.columnOption("ID", "visible", true);
    };
    onExported (e) {
        e.component.columnOption("ID", "visible", false);
        e.component.endUpdate();
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
<dx-data-grid ...
    (onExporting)="onExporting($event)"
    (onExported)="onExported($event)">
    <!-- ... -->
    <dxi-column dataField="ID" [visible]="false"></dxi-column>
</dx-data-grid>
Vue
App.vue
<template>
    <DxDataGrid ...
        @exporting="onExporting"
        @exported="onExported"
    >
        <DxColumn
            data-field="ID"
            :visible="false"
        />
    </DxDataGrid>
</template>

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

import { DxDataGrid, DxColumn } from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid,
        DxColumn
    },
    methods: {
        onExporting(e) {
            e.component.beginUpdate();
            e.component.columnOption('ID', 'visible', true);
        },
        onExported(e) {
            e.component.columnOption('ID', 'visible', false);
            e.component.endUpdate();
        }
    }
</script>
React
App.js
import React from 'react';

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

import DataGrid, { Column } from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ... 
                onExporting={this.onExporting}
                onExported={this.onExported}>
                <Column dataField="ID" visible={false} />    
            </DataGrid>
        );
    }

    onExporting(e) {
        e.component.beginUpdate();
        e.component.columnOption('ID', 'visible', true);
    }

    onExported(e) {
        e.component.columnOption('ID', 'visible', false);
        e.component.endUpdate();
    }
}

export default App;
See Also

onFileSaving

A function that is executed before a file with exported data is saved to the user's local storage.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cancel

Boolean

Allows you to cancel file saving.

component

DataGrid

The widget's instance.

data

BLOB

Exported data as a BLOB.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

fileName

String

The name of the file to be saved.

format

String

The format of this file. Equals "EXCEL" for an Excel file.

Default Value: null

onFocusedCellChanged

A function that is executed after the focused cell changes. Applies only to cells in data or group rows.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cellElement

HTMLElement | jQuery

The focused cell's container. It is an HTML Element or a jQuery Element when you use jQuery.

column

DataGrid Column

The column's properties.

columnIndex

Number

The index of the cell's column.

component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Available only if you use Knockout.

row

DataGrid Row

The row's properties.

rowIndex

Number

The index of the cell's row.

Default Value: null

onFocusedCellChanging

A function that is executed before the focused cell changes. Applies only to cells in data or group rows.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cancel

Boolean

Allows you to cancel focusing a new cell.

cellElement

HTMLElement | jQuery

The to-be-focused cell's container. It is an HTML Element or a jQuery Element when you use jQuery.

columns

Array<DataGrid Column>

The visible columns' properties.

component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

event

Event (jQuery or EventObject)

The event that caused the function to execute. It is a dxEvent or a jQuery.Event when you use jQuery.

isHighlighted

Boolean

true if the cell is highlighted; otherwise false, even if the cell's row is highlighted.

model

Object

Model data. Available only if you use Knockout.

newColumnIndex

Number

The index of the column the cell that should be focused belongs to.

newRowIndex

Number

The index of the row the cell that should be focused belongs to.

prevColumnIndex

Number

The index of the previously focused cell's column.

prevRowIndex

Number

The index of the previously focused cell's row.

rows

Array<DataGrid Row>

The visible rows' properties.

Default Value: null

In the following code, the onFocusedCellChanging function is used to customize keyboard navigation within a row. The cell navigation is looped in a single row because focus moves to the row's first cell after reaching the last cell and vice versa:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        onFocusedCellChanging: function (e) {
            if (e.newColumnIndex == e.prevColumnIndex) {
                e.newColumnIndex = (e.newColumnIndex == 0 ? e.columns.length - 1 : 0)
            }
        }
    });
});
Angular
TypeScript
HTML
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    onFocusedCellChanging (e) { 
        if (e.newColumnIndex == e.prevColumnIndex) {
            e.newColumnIndex = (e.newColumnIndex == 0 ? e.columns.length - 1 : 0)
        }
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
<dx-data-grid ...
    (onFocusedCellChanging)="onFocusedCellChanging($event)">
</dx-data-grid>
Vue
App.vue
<template>
    <DxDataGrid ...
        @focused-cell-changing="onFocusedCellChanging"
    > 
    </DxDataGrid>
</template>

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

import { DxDataGrid } from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    },
    methods: {
        onFocusedCellChanging(e) {
            if (e.newColumnIndex == e.prevColumnIndex) {
                e.newColumnIndex = (e.newColumnIndex == 0 ? e.columns.length - 1 : 0);
            }
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ...
                onFocusedCellChanging={this.onFocusedCellChanging}
            >
            </DataGrid>
        );
    }

    onFocusedCellChanging(e) { 
        if (e.newColumnIndex == e.prevColumnIndex) {
            e.newColumnIndex = (e.newColumnIndex == 0 ? e.columns.length - 1 : 0);
        }
    }
}
export default App;
See Also

onFocusedRowChanged

A function that is executed after the focused row changes. Applies only to data or group rows. focusedRowEnabled should be true.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Available only if you use Knockout.

row

DataGrid Row

The row's properties.

rowElement

HTMLElement | jQuery

The focused row's container. It is an HTML Element or a jQuery Element when you use jQuery.

rowIndex

Number

The row's index.

Default Value: null

onFocusedRowChanging

A function that is executed before the focused row changes. Applies only to data or group rows. focusedRowEnabled should be true.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cancel

Boolean

Allows you to cancel focusing a new row.

component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

event

Event (jQuery or EventObject)

The event that caused the function to execute. It is a dxEvent or a jQuery.Event when you use jQuery.

model

Object

Model data. Available only if you use Knockout.

newRowIndex

Number

The index of the row to be focused.

prevRowIndex

Number

The index of the previously focused row.

rowElement

HTMLElement | jQuery

The to-be-focused row's container. It is an HTML Element or a jQuery Element when you use jQuery.

rows

Array<DataGrid Row>

The visible rows' properties.

Default Value: null

onInitialized

A function used in JavaScript frameworks to save the widget instance.

Type:

Function

Function parameters:
e:

Object

Information about the event.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

Default Value: null

See Also

onInitNewRow

A function that is executed before a new row is added to the widget.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

data

Object

The data of the inserted row; initially empty.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Available only if you use Knockout.

promise

Promise<void> (jQuery or native)

Assign a Promise to this field to perform an asynchronous operation, such as a request to a server.

Default Value: null

You can use this function to populate a new row with data. Add fields to the data object that correspond to the data source object's fields. Note that the data object can omit some fields from the data source object. Add only those fields that should initialize specific cells of a new row.

In the following code, the onInitNewRow function is used to provide default values for the new row's ID, hireDate, and position cells. The promise parameter is used to obtain values for the ID and position cell values asynchronously:

jQuery
index.js
$(function() {
    $("#dataGridContainer").dxDataGrid({
        dataSource: [{
            ID: 1,
            hireDate: 1491821760000,
            position: "CTO"
        }, // ...
        ],
        columns: [ "ID", {
            dataField: "hireDate",
            dataType: "date"
        }, "position" ],
        onInitNewRow: function(e) {
            e.data.hireDate = new Date();
            e.promise = getDefaultData().done(function(data) {
                e.data.ID = data.ID;
                e.data.position = data.Position;
            });
        }
    });
    function getDefaultData() {
        var promise = $.ajax({
            // The URL returns { ID: 100, Position: "Programmer" }
            url: "https://www.mywebsite.com/api/getDefaultData", 
            dataType: "json"
        });
        return promise;
    } 
})
Angular
app.component.html
app.component.ts
app.module.ts
<dx-data-grid ...
    [dataSource]="employees"
    (onInitNewRow)="onInitNewRow($event)">
    <dxi-column dataField="ID"></dxi-column>
    <dxi-column dataField="hireDate" dataType="date"></dxi-column>
    <dxi-column dataField="position"></dxi-column>
</dx-data-grid>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    employees = [{
        ID: 1,
        hireDate: 1491821760000,
        position: "CTO"
    }, // ...
    ];
    onInitNewRow(e) {
        e.data.hireDate = new Date();
        e.promise = this.getDefaultData().then((data: any) => {
            e.data.ID = data.ID;
            e.data.position = data.Position;
        });
    }
    getDefaultData() {
        return this.httpClient.get("https://www.mywebsite.com/api/getDefaultData")
            .toPromise()
            .then(data => {
                // "data" is { ID: 100, Position: "Programmer" }
                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 { DxDataGridModule } from 'devextreme-angular';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        DxDataGridModule
    ],
    providers: [ ],
    bootstrap: [AppComponent]
})
export class AppModule { }
Vue
App.vue
<template>
    <DxDataGrid ...
        :data-source="employees"
        @init-new-row="initNewRow">
        <DxColumn data-field="ID" />
        <DxColumn data-field="hireDate" data-type="date" />
        <DxColumn data-field="position" />
    </DxDataGrid>
</template>
<script>
import 'devextreme/dist/css/dx.common.css';
import 'devextreme/dist/css/dx.light.css';

import { DxDataGrid, DxColumn } from 'devextreme-vue/data-grid';
import 'whatwg-fetch';

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

export default {
    components: {
        DxDataGrid,
        DxColumn
    },
    data() {
        employees
    },
    methods: {
        initNewRow(e) {
            e.data.hireDate = new Date();
            e.promise = this.getDefaultData().then(data => {
                e.data.ID = data.ID;
                e.data.position = data.Position;
            });
        }
        getDefaultData() {
            return fetch("https://www.mywebsite.com/api/getDefaultData")
                .then(response => response.json())
                .then((data) => {
                    // "data" is { ID: 100, Position: "Programmer" }
                    return data;
                })
                .catch(() => { 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 { DataGrid, Column } from 'devextreme-react/data-grid';
import 'whatwg-fetch';

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

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

    onInitNewRow(e) {
        e.promise = this.getDefaultData().then(data => {
            e.data.ID = data.ID;
            e.data.position = data.Position;
        });
        e.data.hireDate = new Date();
    }

    getDefaultData() {
        return fetch("https://www.mywebsite.com/api/getDefaultData")
            .then(response => response.json())
            .then((data) => {
                // "data" is { ID: 100, Position: "Programmer" }
                return data;
            }) 
            .catch(() => { throw 'Data Loading Error' });
    }

    render() {
        return (
            <DataGrid ...
                dataSource={employees}
                onInitNewRow={this.onInitNewRow}>
                <Column dataField="ID" />
                <Column dataField="hireDate" dataType="date" />
                <Column dataField="position" />
            </DataGrid>
        );
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    .DataSource(new JS("employees"))
    .Columns(c => {
        c.Add().DataField("ID");
        c.Add().DataField("hireDate")
            .DataType(GridColumnDataType.Date);
        c.Add().DataField("position");
    })
    .OnInitNewRow("onInitNewRow")
)
<script type="text/javascript">
    var employees = [{
        ID: 1,
        hireDate: 1491821760000,
        position: "CTO"
    }, // ...
    ];
    function onInitNewRow(e) {
        e.data.hireDate = new Date();
        e.promise = getDefaultData().done(data => {
            e.data.ID = data.ID;
            e.data.position = data.Position;
        });
    }
    function getDefaultData() {
        let promise = $.ajax({
            // The URL returns { ID: 100, Position: "Programmer" }
            url: "https://www.mywebsite.com/api/getDefaultData",
            dataType: "json",
        });
        return promise;
    }
</script>

onKeyDown

A function that is executed when the widget is in focus and a key has been pressed down.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

event

Event (jQuery or EventObject)

The event that caused the function to execute. It is a dxEvent or a jQuery.Event when you use jQuery. This event is based on the keydown native event.

handled

Boolean

Indicates whether the widget has already handled this event.

jQueryEvent

jQuery.Event

Use 'event' instead.

The jQuery event that caused the function's execution. Deprecated in favor of the event field.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

jQuery
index.js
$(function() {
    $("#dataGrid").dxDataGrid({
        // ...
        onKeyDown(e) {
            if (e.event.ctrlKey && e.event.key === "Q") {
                console.log("Ctrl + Q was pressed"); 
            }
        }
    });
});
Angular
app.component.html
app.component.ts
app.module.ts
<dx-data-grid ...
    (onKeyDown)="onKeyDown($event)">
</dx-data-grid>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    onKeyDown(e) {
        if (e.event.ctrlKey && e.event.key === "Q") {
            console.log("Ctrl + Q was pressed"); 
        }
    }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { DxDataGridModule } from 'devextreme-angular';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        DxDataGridModule
    ],
    providers: [ ],
    bootstrap: [AppComponent]
})
export class AppModule { }
Vue
App.vue
<template>
    <DxDataGrid ...
        @key-down="onKeyDown">            
    </DxDataGrid>
</template>

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

import DxDataGrid from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    },
    methods: {
        onKeyDown(e) {
            if (e.event.ctrlKey && e.event.key === "Q") {
                console.log("Ctrl + Q was pressed"); 
            }
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ...
                onKeyDown={this.onKeyDown}>
            </DataGrid>
        );
    }

    onKeyDown(e) {
        if (e.event.ctrlKey && e.event.key === "Q") {
            console.log("Ctrl + Q was pressed"); 
        }
    }
}
export default App;

onOptionChanged

A function that is executed after a widget option is changed.

Type:

Function

Function parameters:
e:

Object

Information about the event.

Object structure:
Name Type Description
model

Object

Model data. Available only if you use Knockout.

fullName

String

The path to the modified option that includes all parent options.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

component

DataGrid

The widget's instance.

name

String

The modified option if it belongs to the first level. Otherwise, the first-level option it is nested into.

value any

The modified option's new value.

Default Value: null

onRowClick

A function that is executed when a row is clicked or tapped.

Type:

Function

|

String

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
columns

Array<Object>

All column configurations.

component

DataGrid

The widget's instance.

data

Object

The row's data.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

event

Event (jQuery or EventObject)

The event that caused the function to execute. It is a dxEvent or a jQuery.Event when you use jQuery.

groupIndex

Number

The row's group index. Available if rowType is "group".

handled

Boolean

Indicates whether internal widget functions have already handled the event.

isExpanded

Boolean

Indicates whether or not the group row is expanded. Available if rowType is "group".

isNewRow

Boolean

Indicates that the row is added, but not yet saved. Available if rowType is "data".

isSelected

Boolean

Indicates whether the row is selected.

jQueryEvent

jQuery.Event

Use 'event' instead.

The jQuery event that caused the function's execution. Deprecated in favor of the event field.

key any

The row's key.

model

Object

Model data. Available only if Knockout is used.

rowElement

HTMLElement | jQuery

The row's container. It is an HTML Element or a jQuery Element when you use jQuery.

rowIndex

Number

The row's index. Refer to Column and Row Indexes for more information.

rowType

String

The row's type.

values

Array<any>

Values displayed in the row cells.

Default Value: null

The widget executes the onCellClick function and can also execute internal functions before this function. Use the handled field to check whether internal functions were executed.

In the following code, the onRowClick function calls the editRow method to switch the clicked row to the editing state. This functionality is best applied in form or popup editing.mode:

jQuery
index.js
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        editing: { mode: "form "},
        onRowClick: function(e) {
            if(e.rowType === "data") {
                e.component.editRow(e.rowIndex);
            }
        }
    });
});
Angular
app.component.html
app.component.ts
app.module.ts
<dx-data-grid ...
    (onRowClick)="startEdit($event)">
    <dxo-editing mode="form"></dxo-editing>
</dx-data-grid>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    // ...
    startEdit(e) {
        if(e.rowType === "data") {
            e.component.editRow(e.rowIndex);
        }
    }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { DxDataGridModule } from 'devextreme-angular';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        DxDataGridModule
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }
Vue
App.vue
<template>
    <DxDataGrid ...
        @row-click="startEdit">
        <DxEditing mode="form" />
    </DxDataGrid>
</template>

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

import DxDataGrid, {
    DxEditing 
} from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    },
    methods: {
       startEdit(e) {
            if(e.rowType === "data") {
                e.component.editRow(e.rowIndex);
            }
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid, {
    Editing 
} from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ...
                onRowClick={this.startEdit}>
                <Editing mode="form">
            </DataGrid>
        );
    }

    startEdit = (e) => {
        if(e.rowType === "data") {
            e.component.editRow(e.rowIndex);
        }
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    // ...
    .Editing(e => e.Mode(GridEditMode.Form))
    .OnRowClick("startEdit")
)

<script type="text/javascript">
    function startEdit(e) {
        if(e.rowType === "data") {
            e.component.editRow(e.rowIndex);
        }
    }
</script>
NOTE
The onRowClick function is not executed when the clicked row enters or is in the editing state. Instead, specify the onCellClick function.

onRowCollapsed

A function that is executed after a row is collapsed.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

key any

The key of the row.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

onRowCollapsing

A function that is executed before a row is collapsed.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cancel

Boolean

Allows you to cancel row collapsing.

component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

key any

The key of the row.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

To cancel row collapsing, assign true to the cancel field of the function parameter.

onRowDblClick

A function that is executed when a row is double-clicked or double-tapped. Executed after onCellDblClick.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
columns

Array<DataGrid Column>

The configurations of visible columns.

component

DataGrid

The widget's instance.

data

Object

The row's data.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

event

Event (jQuery or EventObject)

The event that caused the function to execute. It is a dxEvent or a jQuery.Event when you use jQuery.

groupIndex

Number

The row's group index. Available if rowType is "group".

isExpanded

Boolean

Indicates whether the row is expanded or collapsed. Available if rowType is "data", "detail", or "group".

isNewRow

Boolean

Indicates that the row is added, but not yet saved. Available if rowType is "data".

isSelected

Boolean

Indicates whether the row is selected. Available if rowType is "data" or "detail".

key any

The row's key or a group row's key. Available if the rowType is "data", "detail", "detailAdaptive", or "group".

model

Object

Model data. Available only if you use Knockout.

rowElement

HTMLElement | jQuery

The row's container. It is an HTML Element or a jQuery Element when you use jQuery.

rowIndex

Number

The row's index. Refer to Column and Row Indexes for more information.

rowType

String

The row's type.

values

Array<any>

Raw values displayed in the row's cells.

Default Value: null

NOTE

onRowDblClick is not executed when the clicked row enters or is in the editing state. You can use onCellDblClick instead.

This event handler is also not executed on mobile devices, because double tap gesture is reserved for zooming. To force onRowDblClick execution, add the following CSS property to the widget's container:

HTML
<div style="touch-action:manipulation"></div>

onRowExpanded

A function that is executed after a row is expanded.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

key any

The key of the row.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

onRowExpanding

A function that is executed before a row is expanded.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cancel

Boolean

Allows you to cancel row expansion.

component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

key any

The key of the group or master row.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

To cancel row expansion, assign true to the cancel field of the function parameter.

onRowInserted

A function that is executed after a new row has been inserted into the data source.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

data

Object

The data of the row.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

error

JavaScript Error Object

The standard Error object defining an error that may occur during insertion.

key any

The key of the row. If a field providing keys is not specified in the data source, the whole data object is considered the key.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

NOTE
In batch editing mode, if several rows have been inserted, this function will be executed for each row individually.

onRowInserting

A function that is executed before a new row is inserted into the data source.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cancel

Boolean

|

Promise<void> (jQuery or native)

true, a Promise resolved with true, or a rejected Promise stops row insertion.
false or a Promise resolved with false or undefined continues row insertion.

component

DataGrid

The widget's instance.

data

Object

The data of the row that should be inserted.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

NOTE
In batch editing mode, this function is executed for each row individually if several rows should be inserted.

The following code shows how to use the function parameter's cancel field to prevent or continue row insertion. In this code, a Promise is assigned to this field. Row insertion continues if row data validation on the server succeeds (the Promise is resolved); otherwise, row insertion is prevented (the Promise is rejected).

jQuery
JavaScript
$(function(){
    $("#dataGridContainer").dxDataGrid({
        // ...
        onRowInserting: function(e) {
            var d = $.Deferred();
            $.getJSON("https://url/to/your/validation/service", JSON.stringify(e.data))
                .then(function(result) {
                    return !result.errorText ? d.resolve() : d.reject(result.errorText);
                })
                .fail(function() { 
                    return.reject(); 
                })
            e.cancel = d.promise();
        }
    })
})
Angular
TypeScript
HTML
import { DxDataGridModule } from "devextreme-angular";
import { HttpClient, HttpClientModule, HttpParams } from "@angular/common/http";
import "rxjs/add/operator/toPromise";
// ...
export class AppComponent {
    constructor(private httpClient: HttpClient) { /*...*/}
    onRowInserting(e) {
        let params = new HttpParams({ fromString: JSON.stringify(e.data) });
        let result = this.httpClient.get("https://url/to/your/validation/service", { params: params })
            .toPromise();
        e.cancel = new Promise((resolve, reject) => {
            result.then((validationResult) => {
                !validationResult.errorText ? resolve() : reject(validationResult.errorText)
            })
            .catch(() => reject());
        })    
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule,
        HttpClientModule
    ],
    // ...
})
<dx-data-grid ... 
    (onRowInserting)="onRowInserting($event)">
</dx-data-grid>

onRowPrepared

A function that is executed after a row is created.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
columns

Array<DataGrid Column>

All column configurations.

component

DataGrid

The widget's instance.

data

Object

The row's raw data. Unavailable if rowType is "header", "filter", or "totalFooter".

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

groupIndex

Number

The row's group index. Available if rowType is "group".

isExpanded

Boolean

Indicates whether the row is expanded or collapsed. Unavailable if rowType is "header", "filter", or "totalFooter".

isNewRow

Boolean

Indicates that the row is added, but not yet saved. Available if rowType is "data".

isSelected

Boolean

Indicates whether the prepared row is selected. Available only if rowType is "data".

key any

The row's key.
If a field providing keys is not specified in the data source, the whole data object is considered the key.

model

Object

Model data. Available only if Knockout is used.

rowElement

HTMLElement | jQuery

The row's container. It is an HTML Element or a jQuery Element when you use jQuery.

rowIndex

Number

The row's index. Refer to Column and Row Indexes for more information.

rowType

String

The row's type.

values

Array<any>

Values displayed in the row cells.

Default Value: null

onRowRemoved

A function that is executed after a row has been removed from the data source.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

data

Object

The data of the row.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

error

JavaScript Error Object

The standard Error object defining an error that may occur during removal.

key any

The key of the row. If a field providing keys is not specified in the data source, the whole data object is considered the key.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

NOTE
In batch editing mode, if several rows have been removed, this function will be executed for each row individually.

onRowRemoving

A function that is executed before a row is removed from the data source.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cancel

Boolean

|

Promise<void> (jQuery or native)

true, a Promise resolved with true, or a rejected Promise stops row removal.
false or a Promise resolved with false or undefined continues row removal.

component

DataGrid

The widget's instance.

data

Object

The data of the row that should be removed.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

key any

The row's key.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

NOTE
In batch editing mode, this function is executed for each row individually if several rows should be removed.

The following code shows how to use the function parameter's cancel field to prevent or continue row removal. In this code, a Promise is assigned to this field. Row removal continues if checks on the server succeed (the Promise is resolved); otherwise, row removal is prevented (the Promise is rejected).

jQuery
JavaScript
$(function(){
    $("#dataGridContainer").dxDataGrid({
        // ...
        onRowRemoving: function(e) {
            var d = $.Deferred();
            $.getJSON("https://url/to/your/validation/service", JSON.stringify(e.data))
                .then(function(result) {
                    return !result.errorText ? d.resolve() : d.reject(result.errorText)
                })
                .fail(function() { 
                    return d.reject(); 
                })
            e.cancel = d.promise();
        }
    })
})
Angular
TypeScript
HTML
import { DxDataGridModule } from "devextreme-angular";
import { HttpClient, HttpClientModule, HttpParams } from "@angular/common/http";
import "rxjs/add/operator/toPromise";
// ...
export class AppComponent {
    constructor(private httpClient: HttpClient) { /*...*/}
    onRowRemoving(e) {
        let params = new HttpParams({ fromString: JSON.stringify(e.data) });
        let result = this.httpClient.get("https://url/to/your/validation/service", { params: params })
            .toPromise();
        e.cancel = new Promise((resolve, reject) => {
            result.then((validationResult) => {
                !validationResult.errorText ? resolve() : reject(validationResult.errorText)
            })
            .catch(() => reject());
        })    
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule,
        HttpClientModule
    ],
    // ...
})
<dx-data-grid ... 
    (onRowRemoving)="onRowRemoving($event)">
</dx-data-grid>

onRowUpdated

A function that is executed after a row has been updated in the data source.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

data

Object

The updated data of the row.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

error

JavaScript Error Object

The standard Error object defining an error that may occur during updating.

key any

The key of the row. If a field providing keys is not specified in the data source, the whole data object is considered the key.

model

Object

Model data. Available only if you use Knockout.

Default Value: null

NOTE
In batch editing mode, if several rows have been updated, this function will be executed for each row individually.

onRowUpdating

A function that is executed before a row is updated in the data source.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
cancel

Boolean

|

Promise<void> (jQuery or native)

true, a Promise resolved with true, or a rejected Promise stops row updating.
false or a Promise resolved with false or undefined continues row updating.

component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

key any

The row's key.

model

Object

Model data. Available only if you use Knockout.

newData

Object

The row's updated data.

oldData

Object

The row's old data.

Default Value: null

NOTE
In batch editing mode, this function is executed for each row individually if several rows should be updated.

The following code shows how to use the function parameter's cancel field to prevent or continue row updating. In this code, a Promise is assigned to this field. Row updating continues if row data validation on the server succeeds (the Promise is resolved); otherwise, row updating is prevented (the Promise is rejected).

jQuery
JavaScript
$(function(){
    $("#dataGridContainer").dxDataGrid({
        // ...
        onRowUpdating: function(e) {
            var d = $.Deferred();
            $.getJSON("https://url/to/your/validation/service", JSON.stringify(e.data))
                .then(function(result) {
                    return !result.errorText ? d.resolve() : d.reject(result.errorText); 
                })
                .fail(function() { 
                    return d.reject(); 
                })
            e.cancel = d.promise();
        }
    })
})
Angular
TypeScript
HTML
import { DxDataGridModule } from "devextreme-angular";
import { HttpClient, HttpClientModule, HttpParams } from "@angular/common/http";
import "rxjs/add/operator/toPromise";
// ...
export class AppComponent {
    constructor(private httpClient: HttpClient) { /*...*/}
    onRowUpdating(e) {
        let params = new HttpParams({ fromString: JSON.stringify(e.data) });
        let result = this.httpClient.get("https://url/to/your/validation/service", { params: params })
            .toPromise();
        e.cancel = new Promise((resolve, reject) => {
            result.then((validationResult) => {
                !validationResult.errorText ? resolve() : reject(validationResult.errorText)
            })
            .catch(() => reject());
        })    
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule,
        HttpClientModule
    ],
    // ...
})
<dx-data-grid ... 
    (onRowUpdating)="onRowUpdating($event)">
</dx-data-grid>

onRowValidating

A function that is executed after cells in a row are validated against validation rules.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
brokenRules

Array<RequiredRule | NumericRule | RangeRule | StringLengthRule | CustomRule | CompareRule | PatternRule | EmailRule | AsyncRule>

An array of broken rules. The structure of rule objects is described in the Validation Rules section.

component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

errorText

String

An error message to be displayed.

isValid

Boolean

Indicates whether data in all row cells satisfies the validation rules.

key any

The key of the row. If a field providing keys is not specified in the data source, the whole data object is considered the key.

model

Object

Model data. Available only if you use Knockout.

newData

Object

The data of the validated row after changes.

oldData

Object

The data of the validated row before changes.

promise

Promise<void> (jQuery or native)

Assign a Promise to this field to perform an asynchronous operation, such as a request to a server.

Default Value: null

Use this function to perform operations before messages about failed validation are shown. For instance, you can run additional checks and change the isValid function parameter to change the validation result. You can also change the errorText parameter to correct the error message.

The following code illustrates how to validate an email address on the server and display an error row with a custom error text if the validation fails:

jQuery
index.js
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        onRowValidating: function(e) {
            if(e.newData.Email) {
                e.promise = checkEmail(e.newData.Email)
                    .done(function(result) {
                        e.errorText = result.errorText;
                        e.isValid = result.isValid;
                    });
            }
        }
    });
});
function checkEmail(email) {
    return $.ajax({
        // The url returns { errorText: "The Email address you entered already exists.", isValid: false }
        url: "https://www.mywebsite.com/api/checkEmail",
        dataType: "json",
        data: { email: email }
    });
}
Angular
app.component.html
app.component.ts
app.module.ts
<dx-data-grid ...
    (onRowValidating)="onRowValidating($event)">
</dx-data-grid>
import { Component } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    constructor(@Inject(HttpClient) http: HttpClient) {
        this.checkEmail = this.checkEmail.bind(this);
    }
    onRowValidating(e) {
        if(e.newData.Email) {
            e.promise = this.checkEmail(e.newData.Email)
                .then((result: any) => {
                    // "result" is { errorText: "The Email address you entered already exists.", isValid: false }
                    e.errorText = result.errorText;
                    e.isValid = result.isValid;
                });
        }
    }
    checkEmail(email) {
        const params = new HttpParams().set("email", email);
        return this.http.get("https://www.mywebsite.com/api/checkEmail", { params })
            .toPromise();
    }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Component } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';

import { DxDataGridModule } from 'devextreme-angular';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        HttpClientModule,
        DxDataGridModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }
Vue
App.vue
<template>
    <dx-data-grid ...
        @row-validating="onRowValidating">
    </dx-data-grid>
</template>

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

import DxDataGrid from 'devextreme-vue/data-grid';
import 'whatwg-fetch';

export default {
    components: {
        DxDataGrid
    },
    // ...
    methods: {
        onRowValidating(e) {
            if(e.newData.Email) {
                e.promise = this.checkEmail(e.newData.Email)
                    .then((result: any) => {
                        // "result" is { errorText: "The Email address you entered already exists.", isValid: false }
                        e.errorText = result.errorText;
                        e.isValid = result.isValid;
                    });
            }
        },
        checkEmail(email) {
            let params = '?' + 'email=' + email;
            return fetch("https://www.mywebsite.com/api/checkEmail${params}")
                .toPromise();
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid from 'devextreme-react/data-grid';
import 'whatwg-fetch';

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

    onRowValidating(e) {
        if(e.newData.Email) {
            e.promise = this.checkEmail(e.newData.Email)
                .then((result: any) => {
                    // "result" is { errorText: "The Email address you entered already exists.", isValid: false }
                    e.errorText = result.errorText;
                    e.isValid = result.isValid;
                });
        }
    }
    checkEmail(email) {
        let params = '?' + 'email=' + email;
        return fetch("https://www.mywebsite.com/api/checkEmail${params}")
            .toPromise();
    }

    render() {
        return (
            <DataGrid ...
                onRowValidating={this.onRowValidating}>
            </DataGrid>
        );
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    // ...
    .OnRowValidating("onRowValidating")
)

<script type="text/javascript">
    function onRowValidating(e) {
        if(e.newData.Email) {
            e.promise = checkEmail(e.newData.Email)
                .done(function(result) {
                    e.errorText = result.errorText;
                    e.isValid = result.isValid;
                });
        }
    }
    function checkEmail(email) {
        return $.ajax({
            // The url returns { errorText: "The Email address you entered already exists.", isValid: false }
            url: "https://www.mywebsite.com/api/checkEmail",
            dataType: "json",
            data: { email: email }
        });
    }
</script>
NOTE
In batch editing mode, if changes in several rows are committed simultaneously, this function is executed for each row.

onSelectionChanged

A function that is executed after selecting a row or clearing its selection.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

currentDeselectedRowKeys

Array<any>

The keys of the rows whose selection has been cleared.

currentSelectedRowKeys

Array<any>

The keys of the rows that have been selected.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Available only if you use Knockout.

selectedRowKeys

Array<any>

The keys of all selected rows.

selectedRowsData

Array<Object>

The data of all selected rows.
Does not include calculated values.

Default Value: null

This function has the following specifics:

  • If a field providing key values is not specified in the data source, the whole data object is considered the key. In this case, all arrays passed to the function contain data objects instead of keys.
  • When selection is deferred, this function does not provide access to keys and data. Use the getSelectedRowsData() or getSelectedRowKeys() method instead.

View Demo

onToolbarPreparing

A function that is executed before the toolbar is created.

Type:

Function

Function parameters:
e:

Object

Information about the event that caused the function's execution.

Object structure:
Name Type Description
component

DataGrid

The widget's instance.

element

HTMLElement | jQuery

The widget's container. It is an HTML Element or a jQuery Element when you use jQuery.

model

Object

Model data. Available only if you use Knockout.

toolbarOptions

Toolbar Configuration

The options of the toolbar.

Default Value: null

This function allows you to customize the toolbar. Depending on the configuration, the widget may add the following items to the toolbar:

  • DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Toolbar ColumnChooserButton - "columnChooserButton"
  • DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Toolbar AddButton - "addRowButton"
  • DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Toolbar SaveButton - "saveButton"
  • DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Toolbar RevertButton - "revertButton"
  • DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Toolbar Exporting - "exportButton"
  • DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Toolbar ApplyFilterButton - "applyFilterButton"
  • "groupPanel"
  • "searchPanel"

The following code shows how to use this function to customize the toolbar:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        onToolbarPreparing: function (e) {
            let toolbarItems = e.toolbarOptions.items;

            // Modifies an existing item
            toolbarItems.forEach(function(item) {                    
                if (item.name === "saveButton") {
                    item.options = {
                        icon: "custom-save-icon",
                        onClick: function(e) {
                            // Implement custom save logic here
                        }
                    }
                }
            });

            // Adds a new item
            toolbarItems.push({
                widget: "dxButton", 
                options: { icon: "user", onClick: function() { ... } },
                location: "after"
            });
        }
    });
});
Angular
TypeScript
HTML
import { DxDataGridModule, DxButtonModule } from "devextreme-angular";
// ...
export class AppComponent {
    onToolbarPreparing (e) { 
        let toolbarItems = e.toolbarOptions.items;
        // Modifies an existing item
        toolbarItems.forEach(function(item) {
            if (item.name === "saveButton") {
                item.options = {
                    icon: "custom-save-icon",
                    onClick: function(e) {
                        // Implement custom save logic here
                    }
                }
            }
        });

        // Adds a new item
        toolbarItems.push({
            widget: "dxButton", 
            options: { icon: "user", onClick: function () { ... } },
            location: "after"
        });
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule,
        DxButtonModule
    ],
    // ...
})
<dx-data-grid ...
    (onToolbarPreparing)="onToolbarPreparing($event)">
</dx-data-grid>
Vue
App.vue
<template>
    <DxDataGrid ...
        @toolbar-preparing="onToolbarPreparing"
    />
</template>

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

import { DxDataGrid } from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    },
    methods: {
        onToolbarPreparing(e) {
            let toolbarItems = e.toolbarOptions.items;
            // Modifies an existing item
            toolbarItems.forEach(function(item) {
                if (item.name === "saveButton") {
                    item.options = {
                        icon: "custom-save-icon",
                        onClick: function(e) {
                            // Implement custom save logic here
                        }
                    }
                }
            });

            // Adds a new item
            toolbarItems.push({
                widget: 'dxButton',
                options: {
                    icon: 'user',
                    onClick: function() {
                        // ...
                    }
                },
                location: 'after'
            });
        }
    }
}
</script>
React
App.js
import React from 'react';

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

import DataGrid from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid ...
                onToolbarPreparing={this.onToolbarPreparing}
            />
        );
    }

    onToolbarPreparing(e) {
        let toolbarItems = e.toolbarOptions.items;
        // Modifies an existing item
        toolbarItems.forEach(function(item) {
            if (item.name === "saveButton") {
                item.options = {
                    icon: "custom-save-icon",
                    onClick: function(e) {
                        // Implement custom save logic here
                    }
                }
            }
        });

        // Adds a new item
        toolbarItems.push({
            widget: 'dxButton',
            options: {
                icon: 'user',
                onClick: function() {
                    // ...
                }
            },
            location: 'after'
        });
    }
}
export default App;
NOTE
If you use modules and set a DevExtreme widget as a toolbar item, import this widget's module. You do not have to import the Button or TextBox widgets because DataGrid imports them automatically.

View Demo

pager

Configures the pager.

Type:

Object

The pager is an element that allows users to navigate through pages and change their size at runtime. The pager consists of the page navigator and several optional elements: the page size selector, navigation buttons, and page information.

DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Pager

View Demo

See Also

paging

Configures paging.

Type:

Object

Paging allows the widget to load data in portions instead of loading it simultaneously. To enable paging, set the paging.enabled option to true.

Users can switch between pages and change paging settings using the pager or they can scroll the pages. Paging settings apply with any scrolling mode.

View Demo

See Also

remoteOperations

Notifies the DataGrid of the server's data processing operations.

Type:

Boolean

|

Object

|

String

Default Value: 'auto'
Accepted Values: 'auto'

Server-side data processing improves the widget's performance on large datasets. When the server does not implement particular operations (and/or the corresponding remoteOperations fields are false) they are executed on the client. Note that the widget may send queries to the server while executing a client-side operation.

The following table lists the possible remoteOperations configurations and the operations the server should implement. The server should also implement additional operations depending on the used widget functionality.

Setting Required server-side operations Additional server-side operations
remoteOperations: true all operations except group paging -
remoteOperations: { groupPaging: true } all operations including group paging -
remoteOperations: { paging: true } paging filtering1, sorting1, summary calculation1
remoteOperations: { paging: true }
(with grouping used in the widget)
paging, filtering, sorting grouping3, summary calculation1
remoteOperations: { filtering: true } filtering -
remoteOperations: { sorting: true } sorting filtering1
remoteOperations: { grouping: true } grouping, filtering sorting1, summary calculation1
remoteOperations: { summary: true } summary calculation filtering1, sorting2, grouping2
  1. If this functionality is used in the widget.
  2. If group summary calculation is used.
  3. If grouping.autoExpandAll is set to false.
NOTE
Paging, filtering, and sorting are performed on the server side for the ODataStore, but you can change them to the client side by setting the corresponding remoteOperations fields to false. Other operations are always client-side.

The following restrictions apply to widget functionality when operations are remote:

Web API Service Demo Custom Service Demo

See Also

renderAsync

Specifies whether to render the filter row, command columns, and columns with showEditorAlways set to true after other elements.

Type:

Boolean

Default Value: false

See Also

repaintChangesOnly

Specifies whether to repaint only those cells whose data changed.

Type:

Boolean

Default Value: false

See Also

rowAlternationEnabled

Specifies whether rows should be shaded differently.

Type:

Boolean

Default Value: false

All rows are monochrome without any visual distinctions by default. However, if you set this option to true, ordinary-looking rows will alternate with slightly shaded ones.

View Demo

rowComponent

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

rowDragging

Configures row reordering using drag and drop gestures.

Type:

Object

rowRender

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

rowTemplate

Specifies a custom template for rows.

Type:

template

Template Data:

Object

The Row object extended by the DataGrid's instance (the component field) and the column configuration (columns).

NOTE

Disable column reordering, grouping, and column fixing when you specify the row template. Its content cannot automatically synchronize with the column layout, which makes these features inoperative. Command columns are not supported either.

You should also implement the following features manually: editing, adaptability, multiple selection, and master-detail interface. Follow the links to see the API that can help you with this task.

In AngularJS and Knockout, use the dxTemplate and declare it within a <table> element. In other cases, declare the markup in a <tbody> element with the dx-row class.

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        rowTemplate: function(container, item) {
            var data = item.data,
                markup = "<tbody class='dx-row'>" +
                    "<tr>" +
                        "<td>" + item.data.id + "</td>" +
                        "<td>" + item.data.name + "</td>" +  
                    "</tr>" +
                "</tbody>";
            container.append(markup);
        }
    });
});
Angular
HTML
TypeScript
<dx-data-grid ...
    rowTemplate="rowTemplateName">
    <tbody class="dx-row" *dxTemplate="let item of 'rowTemplateName'" >
        <tr>
            <td>{{item.data.id}}</td>
            <td>{{item.data.name}}</td>
        </tr>
    </tbody>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
AngularJS
HTML
<div dx-data-grid="{
        ...
        rowTemplate: 'rowTemplateName'
    }" dx-item-alias="item">
        <table data-options="dxTemplate: { name: 'rowTemplateName' }" >
            <tr>
                <td>{{item.data.id}}</td>
                <td>{{item.data.name}}</td>
            </tr>
        </table>
    </div>
Knockout
HTML
<div data-bind="dxDataGrid: {
        ...
        rowTemplate: 'rowTemplateName'
    }">
        <table data-options="dxTemplate: { name: 'rowTemplateName' }" >
            <tr>
                <td data-bind="text: data.id"></td>
                <td data-bind="text: data.name"></td>
            </tr>
        </table>
    </div>
Vue
<template>
    <DxDataGrid ...
        row-template="dataRowTemplate">
        <tbody
            slot="dataRowTemplate"
            slot-scope="{ data: { data: { id, name } } }"
            class="dx-row">
            <tr>
                <td>{{id}}</td>
                <td>{{name}}</td>
            </tr>
        </tbody>
    </DxDataGrid>
</template>
<script>
import { DxDataGrid } from 'devextreme-vue/data-grid';

export default {
    components: {
        DxDataGrid
    }
};
</script>
React
import React from 'react';
import DataGrid from 'devextreme-react/data-grid';

class Row extends React.PureComponent {
    render() {
        const { data: { id, name } } = this.props.data;
        return (
            <tbody className={"dx-row"}>
                <tr>
                    <td>{id}</td>
                    <td>{name}</td>
                </tr>
            </tbody>
        );
    }
}

class App extends React.Component {
    render() {
        return (
            <DataGrid ...
                rowComponent={Row}>
            </DataGrid>
        );
    }
}
export default App;
ASP.NET MVC Controls
Razor C#
@(Html.DevExtreme().DataGrid()
    // ...
    .RowTemplate(@<text>
        <tbody class="dx-row">
            <tr>
                <td><%= data.id %></td>
                <td><%= data.name %></td>
            </tr>
        </tbody>
    </text>)
)

View Demo

You can also use a 3rd-party template engine to customize row appearance. See the 3rd-Party Template Engines article for more information. Note that the <tbody> element that represents a row should have the dx-row class to ensure all widget features work properly.

View Demo

See Also

rtlEnabled

Switches the widget to a right-to-left representation.

Type:

Boolean

Default Value: false

When this option is set to true, the widget text flows from right to left, and the layout of elements is reversed. To switch the entire application/site to the right-to-left representation, assign true to the rtlEnabled field of the object passed to the DevExpress.config(config) method.

JavaScript
DevExpress.config({
    rtlEnabled: true
});
See Also

scrolling

Configures scrolling.

Type:

Object

Scrolling allows a user to browse data left outside the current viewport. The widget provides several scrolling modes detailed in the mode option description.

View Demo

See Also

searchPanel

Configures the search panel.

Type:

Object

The search panel allows searching for values in several columns at once. The widget searches against only those columns whose allowSearch option is set to true.

DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid SearchPanel

To make the search panel visible, set the searchPanel.visible option to true.

View Demo

See Also

selectedRowKeys

Allows you to select rows or determine which rows are selected. Applies only if selection.deferred is false.

Type:

Array<any>

Raised Events: onSelectionChanged

Keys are stored in the order the user selects rows.

To access a row using its key, specify the data field that provides key values. Assign the data field's name to the key option of the store that underlies the dataSource.

See Also

selection

Configures runtime selection.

Type:

Object

A user can select rows in a single or multiple mode. In multiple mode, a user can select all rows at once. To disable this feature, assign false to the allowSelectAll.

By default, once a user selects a row, the data source is instantly notified about it. This may lower the widget performance if the data source is remote and the user is allowed to select all rows at once. In this case, we recommend making the selection deferred.

View Demo

See Also

selectionFilter

Specifies filters for the rows that must be selected initially. Applies only if selection.deferred is true.

Default Value: []
Raised Events: onOptionChanged

This option also allows you to obtain filter expressions for the currently selected rows. Note that if all records are selected, the selectionFilter value is null. If there are no selected records, the value contains an empty array.

See Also

showBorders

Specifies whether the outer borders of the widget are visible.

Type:

Boolean

Default Value: false

showColumnHeaders

Specifies whether column headers are visible.

Type:

Boolean

Default Value: true

See Also

showColumnLines

Specifies whether vertical lines that separate one column from another are visible.

Type:

Boolean

Default Value: true, false (Material)

NOTE
If you use the Android or iOS theme, specifying this option doesn't affect anything. These themes avoid displaying column lines in order to provide a native look for the widget. In case you still require the column lines to be displayed, choose another theme.
See Also

showRowLines

Specifies whether horizontal lines that separate one row from another are visible.

Type:

Boolean

Default Value: false, true (iOS, Material)

See Also

sortByGroupSummaryInfo[]

Allows you to sort groups according to the values of group summary items.

Type:

Array<Object>

Default Value: undefined

Normally, when records are grouped by a column, the groups are sorted according to the values of this column. In a number of cases, such approaches cannot address your needs, e.g., when you require to sort groups by the number of records in each. For these cases, you can implement sorting according to the values of group summary items. These items are specified in the groupItems array. Assume that you have the following code that specifies three group summary items.

jQuery
JavaScript
$(function () {
    $("#dataGridContainer").dxDataGrid({
        // ...
        summary: {
            groupItems: [{
                column: "Age",
                summaryType: "avg",
                name: "Average Age Group Summary"
            }, {
                column: "Income",
                summaryType: "max"
            }, {
                column: "Tasks",
                summaryType: "min"
            }]
        }
    });
});
Angular
HTML
TypeScript
 <dx-data-grid ... >
     <dxo-summary>
         <dxi-group-item
             column="Age"
             summaryType="avg"
             name="Average Age Group Summary">
         </dxi-group-item>
         <dxi-group-item
             column="Income"
             summaryType="max">
         </dxi-group-item>
         <dxi-group-item
             column="Tasks"
             summaryType="min">
         </dxi-group-item>
     </dxo-summary>
 </dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid>
        <DxSummary>
            <DxGroupItem 
                column="Age"
                summary-type="avg"
                name="Average Age Group Summary"
            />
            <DxGroupItem
                column="Income"
                summary-type="max"
            />
            <DxGroupItem
                column="Tasks"
                summary-type="min"
            />
        </DxSummary>
    </DxDataGrid>
</template>

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

import { DxDataGrid, DxSummary, DxGroupItem } from 'devextreme-vue/data-grid';

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

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

import { DataGrid, Summary, GroupItem } from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid>
                <Summary>
                    <GroupItem 
                        column="Age"
                        summaryType="avg"
                        name="Average Age Group Summary" />
                    <GroupItem 
                        column="Income"
                        summaryType="max" />
                    <GroupItem 
                        column="Tasks" 
                        summaryType="min" />
                </Summary>
            </DataGrid>
        );
    }
}
export default App;

To use these summary items for sorting groups, assign an array of objects to the sortByGroupSummaryInfo option. In each object of this array, specify the summaryItem field. This field determines the summary item to be used for summary-based sorting. In the following code, three objects form the sortByGroupSummaryInfo array. In each object, the summaryItem option determines different summary items using different values.

jQuery
JavaScript
$(function () {
    $("#dataGridContainer").dxDataGrid({
        // ...
        sortByGroupSummaryInfo: [
            { summaryItem: 1 }, // determines the maximum income item using its index in the "groupItems" array
            { summaryItem: "min" }, // determines the minimum tasks item using its aggregate function
            { summaryItem: "Average Age Group Summary" } // determines the average age item using its name
        ]
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxi-sort-by-group-summary-info 
        [summaryItem]="1"> <!-- determines the maximum income item using its index in the "groupItems" array -->
    </dxi-sort-by-group-summary-info>
    <dxi-sort-by-group-summary-info 
        summaryItem="min"> <!-- determines the minimum tasks item using its aggregate function -->
    </dxi-sort-by-group-summary-info>
    <dxi-sort-by-group-summary-info 
        summaryItem="Average Age Group Summary"> <!-- determines the average age item using its name -->
    </dxi-sort-by-group-summary-info>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid>
        <DxSortByGroupSummaryInfo
            :summary-item="1"/> <!-- determines the maximum income item using its index in the "groupItems" array -->
        <DxSortByGroupSummaryInfo
            summary-item="min"/> <!-- determines the minimum tasks item using its aggregate function -->
        <DxSortByGroupSummaryInfo
            summary-item="Average Age Group Summary"/> <!-- determines the average age item using its name -->
    </DxDataGrid>
</template>

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

import {
    DxDataGrid,
    DxSortByGroupSummaryInfo
} from 'devextreme-vue/data-grid';

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

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

import { DataGrid, SortByGroupSummaryInfo } from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid>
                <SortByGroupSummaryInfo
                    summaryItem={1}/> {/* determines the maximum income item using its index in the "groupItems" array */}
                <SortByGroupSummaryInfo
                    summaryItem="min"/> {/* determines the minimum tasks item using its aggregate function */}
                <SortByGroupSummaryInfo
                    summaryItem="Average Age Group Summary"/> {/* determines the average age item using its name */}
            </DataGrid>
        );
    }
}
export default App;

After that, set the groupColumn option for objects in the sortByGroupSummaryInfo array. This option identifies the column that must be used in grouping in order that a particular summary-based sorting setting be applied. If you have omitted this option from an object, the sorting setting specified by this object will be applied regardless of the column used in grouping.

jQuery
JavaScript
$(function () {
    $("#gridContainer").dxDataGrid({
        // ...
        sortByGroupSummaryInfo: [
            { summaryItem: 1, groupColumn: "Tasks" }, // applies sorting only when records are grouped by the "Tasks" column
            { summaryItem: "min", groupColumn: "Last Name" }, // applies sorting only when records are grouped by a "Last Name" column
            { summaryItem: "Average Age Group Summary" } // applies sorting regardless the grouping column
        ]
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxi-sort-by-group-summary-info 
        [summaryItem]="1" groupColumn="Tasks"> <!-- applies sorting only when records are grouped by the "Tasks" column -->
    </dxi-sort-by-group-summary-info>
    <dxi-sort-by-group-summary-info 
        summaryItem="min"
        groupColumn="Last Name"> <!-- applies sorting only when records are grouped by a "Last Name" column -->
    </dxi-sort-by-group-summary-info>
    <dxi-sort-by-group-summary-info 
        summaryItem="Average Age Group Summary"> <!--  applies sorting regardless the grouping column -->
    </dxi-sort-by-group-summary-info>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid>
        <DxSortByGroupSummaryInfo
            :summary-item="1"
            group-column="Tasks"
        /> <!-- applies sorting only when records are grouped by the "Tasks" column -->
        <DxSortByGroupSummaryInfo
            summary-item="min"
            group-column="Last Name"
        /> <!-- applies sorting only when records are grouped by a "Last Name" column -->
        <DxSortByGroupSummaryInfo
            summary-item="Average Age Group Summary"
        /> <!-- applies sorting regardless the grouping column -->
    </DxDataGrid>
</template>

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

import {
    DxDataGrid,
    DxSortByGroupSummaryInfo
} from 'devextreme-vue/data-grid';

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

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

import { DataGrid, SortByGroupSummaryInfo } from 'devextreme-react/data-grid';

class App extends React.Component {
    render() {
        return (
            <DataGrid>
                <SortByGroupSummaryInfo
                    summaryItem={1}
                    groupColumn="Tasks"
                /> {/* applies sorting only when records are grouped by the "Tasks" column */}
                <SortByGroupSummaryInfo
                    summaryItem="min"
                    groupColumn="Last Name"
                /> {/* applies sorting only when records are grouped by a "Last Name" column */}
                <SortByGroupSummaryInfo
                    summaryItem="Average Age Group Summary"
                /> {/* applies sorting regardless the grouping column */}
            </DataGrid>
        );
    }
}
export default App;

If several summary-based sorting settings match the current grouping, their indexes in the sortByGroupSummaryInfo array will dictate the order of their application.

In addition, you can set an ascending or descending sort order for each summary-based sorting object using its sortOrder option.

NOTE
This feature does not work when remoteOperations.groupPaging is set to true.
See Also

sorting

Configures runtime sorting.

Type:

Object

A user can sort rows by values of a single or multiple columns depending on the value of the sorting.mode option.

DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Sorting

To apply sorting to a column, a user clicks its header or selects a command from the context menu.

DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Sorting

View Demo

See Also

stateStoring

Configures state storing.

Type:

Object

State storing enables the widget to save applied settings and restore them the next time the widget is loaded. Assign true to the stateStoring.enabled option to enable this functionality.

State storing saves the following options:

View Demo

See Also

summary

Specifies the options of the grid summary.

Type:

Object

A summary is a grid feature that provides a synopsis of data contained in the grid. A summary consists of several items. A summary item displays a value that is a product of applying an aggregate function to the data of a specific column.

There are two types of summary in DataGrid: group and total. The group summary is calculated on a group of data, which is segregated during grouping. To specify the items of the group summary, declare an array of objects and assign it to the summary.groupItems field.

The total summary is calculated on all data contained in the grid. To specify the items of the total summary, declare an array of objects and assign it to the summary.totalItems field.

tabIndex

Specifies the number of the element when the Tab key is used for navigating.

Type:

Number

Default Value: 0

The value of this option will be passed to the tabindex attribute of the HTML element that underlies the widget.

twoWayBindingEnabled

Specifies whether to enable two-way data binding.

Type:

Boolean

Default Value: true

Two-way data binding ensures that the UI tracks changes made in the data source by a 3rd-party component, and vice versa. This way, the widget and its data source stay synchronized. If you implement two-way data binding in the widget on your own using the cellTemplate and/or editCellTemplate options, make sure to set the twoWayBindingEnabled option to false.

NOTE
The widget provides two-way data binding through Knockout, Angular or AngularJS resources, so make sure to add these libraries to your app.

visible

Specifies whether the widget is visible.

Type:

Boolean

Default Value: true

width

Specifies the widget's width.

Type:

Number

|

String

|

Function

Return Value:

Number

|

String

The widget's width.

Default Value: undefined

This option accepts a value of one of the following types:

  • Number
    The width in pixels.

  • String
    A CSS-accepted measurement of width. For example, "55px", "80%", "auto", "inherit".

  • Function
    A function returning either of the above. For example:

    JavaScript
    width: function() {
        return window.innerWidth / 1.5;
    }

wordWrapEnabled

Specifies whether text that does not fit into a column should be wrapped.

Type:

Boolean

Default Value: false