Vue DataGrid Props

This section describes the configuration properties of the DataGrid UI component.

accessKey

Specifies the shortcut key that sets focus on the UI component.

Selector: access-key
Type:

String

Default Value: undefined

The value of this property will be passed to the accesskey attribute of the HTML element that underlies the UI component.

activeStateEnabled

Specifies whether the UI component changes its visual state as a result of user interaction.

Selector: active-state-enabled
Type:

Boolean

Default Value: false

The UI component switches to the active state when users press down the primary mouse button. When this property is set to true, the CSS rules for the active state apply. You can change these rules to customize the component.

Use this property when you display the component on a platform whose guidelines include the active state change for UI components.

allowColumnReordering

Specifies whether a user can reorder columns.

Selector: allow-column-reordering
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 property to true.

DataGrid Demo TreeList Demo

See Also

allowColumnResizing

Specifies whether a user can resize columns.

Selector: allow-column-resizing
Type:

Boolean

Default Value: false

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

DataGrid Demo TreeList Demo

See Also

autoNavigateToFocusedRow

Automatically scrolls the component to the focused row when the focusedRowKey is changed. Incompatible with infinite scrolling mode.

Selector: auto-navigate-to-focused-row
Type:

Boolean

Default Value: true

NOTE
You must specify the component's height to ensure that the autoNavigateToFocusedRow property works properly.

If you set the remoteOperations property to true, the DataGrid generates additional requests with comparison operators (for example, < and >). This logic does not work if ODataStore is bound to a table with GUID keys. You need to disable the autoNavigateToFocusedRow or remoteOperations properties to ensure it operates correctly.

View Demo

cacheEnabled

Specifies whether data should be cached.

Selector: cache-enabled
Type:

Boolean

Default Value: true

When this property is set to true, data loaded once is saved in cache. Then, the UI component 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 UI component or the reload() method of the DataSource:

jQuery
JavaScript
$("#dataGridContainer").dxDataGrid("refresh");
// ===== or =====
const dataGridDataSource = $("#dataGridContainer").dxDataGrid("getDataSource");
dataGridDataSource.reload();
Angular
TypeScript
import { ..., ViewChild } from "@angular/core";
import { DxDataGridModule, DxDataGridComponent } from "devextreme-angular";
// ...
export class AppComponent {
    @ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
    // Prior to Angular 8
    // @ViewChild(DxDataGridComponent) dataGrid: DxDataGridComponent;
    refreshData () {
        this.dataGrid.instance.refresh();
        // ===== or =====
        const dataGridDataSource = this.dataGrid.instance.getDataSource();
        dataGridDataSource.reload();
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid :ref="dataGridRefKey">
        <!-- ... -->
    </DxDataGrid>
</template>

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

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

const dataGridRefKey = "my-data-grid";

export default {
    components: {
        DxDataGrid
    },
    data() {
        return {
            dataGridRefKey
        }
    },
    methods: {
        refreshData() {
            this.dataGrid.refresh();
            // ===== or =====
            const dataGridDataSource = this.dataGrid.getDataSource();
            dataGridDataSource.reload();
        }
    },
    computed: {
        dataGrid: function() {
            return this.$refs[dataGridRefKey].instance;
        }
    }
}
</script>
React
App.js
import React from 'react';

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

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

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

        this.dataGridRef = React.createRef();

        this.refreshData = () => {
            this.dataGrid.refresh();
            // ===== or =====
            const dataGridDataSource = this.dataGrid.getDataSource();
            dataGridDataSource.reload();
        }
    }

    get dataGrid() {
        return this.dataGridRef.current.instance();
    }

    render() {
        return (
            <DataGrid ref={this.dataGridRef}>
                {/* ... */ }
            </DataGrid>
        );
    }
}
export default App;
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 the 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.

Selector: cell-hint-enabled
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 property.

columnAutoWidth

Specifies whether columns should adjust their widths to the content.

Selector: column-auto-width
Type:

Boolean

Default Value: false

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

If the DataGrid is wider than its overall content, the columns are stretched to occupy all available width. To avoid this, set the columnWidth or columns.width property to "auto".

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

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

DataGrid Demo TreeList Demo

See Also

columnChooser

Configures the column chooser.

Selector: DxColumnChooser
Type: common/grids:ColumnChooser

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

DevExtreme HTML5 JavaScript jQuery Angular Knockout DataGrid Column Chooser

DataGrid Demo TreeList Demo

See Also

columnFixing

Configures column fixing.

Selector: DxColumnFixing
Type:

ColumnFixing

When the width of all columns exceeds the UI component width, horizontal scrolling appears. If specific columns should be on screen constantly regardless of how far the UI component is scrolled, allow a user to fix them at runtime using the context menu. For this, set the columnFixing.enabled property 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 UI component should hide columns to adapt to the screen or container size. Ignored if allowColumnResizing is true and columnResizingMode is "widget".

Selector: column-hiding-enabled
Type:

Boolean

Default Value: false

This property set to true makes the UI component hide certain columns automatically if all the columns do not fit the UI component'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.

DataGrid Demo TreeList Demo

NOTE
If you set this property to true and columnResizingMode is set to 'nextColumn' (default), then also enable columnAutoWidth to ensure the component works properly.
See Also

columnMinWidth

Specifies the minimum width of columns.

Selector: column-min-width
Type:

Number

Default Value: undefined

columnResizingMode

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

Selector: column-resizing-mode
Default Value: 'nextColumn'

The columnResizingMode property 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 UI component changes.
    This mode is ignored if you specify the width of any column in percent.

DataGrid Demo TreeList Demo

NOTE
If this property is set to 'nextColumn' (default) and you enable the columnHidingEnabled property, then also enable columnAutoWidth to ensure the component works properly.

columns[]

An array of grid columns.

Selector: DxColumn
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 property. 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 properties 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 properties, apply a filter to grid records using the allowFiltering and filterOperations properties, and group grid records using the allowGrouping and groupIndex properties. In addition, you can change the visibility and width of a column using corresponding properties.

To get or set a property or several properties 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 property.

Selector: column-width
Type:

Number

|

Mode

Default Value: undefined

customizeColumns

Customizes columns after they are created.

Selector: customize-columns
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>
    <DxDataGrid ...
        :customize-columns="customizeColumns"> 
    />
</template>

<script>
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.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.
React

Note that the [elementName]Render and [elementName]Component (for example, the cellRender and cellComponent) do not work within the customizeColumn function. Instead, use the columns array.

App.js
import React from 'react';

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

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

class App extends React.Component {
    customizeColumns = (columns) => {
        // ...
        // This code does not work
        // columns[0].cellRender = cellRender;
    }

    render() {
        return (
            <DataGrid ...
                customizeColumns={this.customizeColumns}
            >
                <!-- ... -->
                <Column
                    dataField="Picture"
                    cellRender={cellRender} <!-- This code works correctly -->
                />
            </DataGrid>
        );
    }
}

function cellRender(data) {
    return <img src={data.value} />;
}

export default App;

dataRowTemplate

Specifies a custom template for data rows.

Selector: data-row-template
Type:

template

Template Data:
Name Type Description
columns

Array<DataGrid Column>

All column configurations.

component

DataGrid

The UI component's instance.

data any

The row's data.

isExpanded

Boolean

Indicates whether the row is expanded or collapsed. Applies if this is a master row in the master-detail interface.

isSelected

Boolean

Indicates whether the row is selected.

key any

The row's key.

rowIndex

Number

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

values

Array<any>

Values displayed in the row cells.

The following details should be taken into account when you use a dataRowTemplate:

  • 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 implement the following features manually: editing, adaptability, selection, master-detail interface, and focused row. Follow the links to review the API that can help you with this task.

  • When DataGrid is exported to Excel, it omits customizations made in the template. However, you can use ExcelJS API to recreate the changes in the exported file. Use the customizeCell function to do this.

  • You should specify all CSS rules manually if you use this property. Refer to the following demo's styles.css tab to see an example:

View Demo

See Also

dataSource

Binds the UI component to data.

Selector: data-source
Default Value: null

The DataGrid works with collections of objects. We recommend that you use a plain object in data (no circulars, no prototypes, etc.). The DataGird uses JSON.stringify and other recursive methods. Circular object references can crash native recursive algorithms (such as serializers) with stack overflows.

Depending on your data source, bind 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 property 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 UI components 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.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.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

Review the following notes about data binding:

  • Data field names cannot be equal to this and should not contain the following characters: ., :, [, and ].

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

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

jQuery
  • The stores are immutable. You cannot change their configurations at runtime. Instead, create a new store or DataSource and assign it to the dataSource property as shown in the following help topic: Get and Set Properties.
Angular
  • The stores are immutable. You cannot change their configurations at runtime. Instead, create a new store or DataSource and assign it to the dataSource property as shown in the following help topic: Two-Way Property Binding.
Vue
  • The stores are immutable. You cannot change their configurations at runtime. Instead, create a new store or DataSource and assign it to the dataSource property as shown in the following help topic: Two-Way Property Binding.
React
  • The stores are immutable. You cannot change their configurations at runtime. Instead, create a new store or DataSource and assign it to the dataSource property as shown in the following help topic: Controlled Mode.

dateSerializationFormat

Specifies the format in which date-time values should be sent to the server.

Selector: date-serialization-format
Type:

String

Specify this property in the following cases:

  • The dataSource is empty or not set at design time. The dateSerializationFormat is needed, because the DataGrid cannot detect it automatically without a data source.

  • You use the createStore method from the DevExtreme.AspNet.Data extension and remote date-time values are specified in UTC. DevExtreme.AspNet.Data requires the dateSerializationFormat to correctly serialize these values.

Use one of the following values to specify the dateSerializationFormat property:

  • "yyyy-MM-dd" - local date

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

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

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

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

See Also

disabled

Specifies whether the UI component responds to user interaction.

Type:

Boolean

Default Value: false

editing

Configures editing.

Selector: DxEditing
Type:

Editing

The UI component can allow a user to add, update and delete data. To control which of these operations are allowed, use the allowAdding, allowUpdating and allowDeleting properties. Editing can be carried out in different modes, which are detailed in the mode property'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 global attributes to be attached to the UI component's container element.

Selector: DxElementAttr
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.

Selector: error-row-enabled
Type:

Boolean

Default Value: true

The error row displays data-related errors that may occur on the server during the UI component's runtime. Setting this property 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.

Selector: DxExport
Type:

Export

A user can click the Export button to save an Excel or PDF file with the exported data. Data types, sort, filter, and group settings are maintained.

DevExtreme HTML5 JavaScript DataGrid Export Button

The following instructions show how to enable and configure client-side export:

  1. Install or reference the required libraries

    Install the following libraries for the export:

    jQuery
    <!-- Export to Excel -->
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.4.0/polyfill.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.4.0/exceljs.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.2/FileSaver.min.js"></script>
        <!-- Reference the DevExtreme sources here -->
    </head>
    
    <!-- Export to Pdf -->
    <head>
        <!-- ... -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.0.0/jspdf.umd.min.js"></script>
        <!-- Reference the DevExtreme sources here -->
    </head>
    Angular
    Installation command
    tsconfig.app.json
    <!-- Export to Pdf  -->
    npm install jspdf
    
    <!-- Export to Excel -->
    npm install --save exceljs file-saver
    npm i --save-dev @types/file-saver
    <!-- Export to Excel -->
    {
        "compilerOptions": {
            // ...
            "outDir": "./out-tsc/app",
            "types": ["node"]
        },
    }
    Vue
    Installation command
    <!-- Export to Pdf  -->
    npm install jspdf
    
    <!-- Export to Excel -->
    npm install --save exceljs file-saver
    React
    Installation command
    <!-- Export to Pdf  -->
    npm install jspdf
    
    <!-- Export to Excel -->
    npm install --save exceljs file-saver
  2. Enable the export UI
    Set the export.enabled property to true. This property enables export for all columns. Set a column's allowExporting property to false to prevent it from being exported:

    jQuery
    JavaScript
    $(function () {
        $("#dataGridContainer").dxDataGrid({
            export: {
                enabled: true
            },
            columns: [{ ...
                allowExporting: false
            }, 
                // ...
            ]
        });
    });
    Angular
    app.component.html
    app.component.ts
    app.module.ts
    <dx-data-grid ... >
        <dxo-export [enabled]="true"></dxo-export>
        <dxi-column ...
            [allowExporting]="false">
        </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 {
        // ...
    }
    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 ... >
            <DxExport
                :enabled="true"
            />
            <DxColumn ... 
                :allow-exporting="false"
            />
        </DxDataGrid>
    </template>
    
    <script>
    import 'devextreme/dist/css/dx.light.css';
    
    import { DxDataGrid, 
        DxExport,
        DxColumn
    } from 'devextreme-vue/data-grid';
    
    export default {
        components: {
            DxDataGrid,
            DxExport,
            DxColumn
        }
    }
    </script>
    React
    App.js
    import React from 'react';
    import 'devextreme/dist/css/dx.light.css';
    
    import DataGrid, {
        Export,
        Column
    } from 'devextreme-react/data-grid';
    
    class App extends React.Component {
        render() {
            return (
                <DataGrid ... >
                    <Export enabled={true} />
                    <Column ...
                        allowExporting={false}
                    />
                </DataGrid>
            );
        }
    }
    export default App;
  3. Export the DataGrid
    Implement the onExporting handler and call the excelExporter.exportDataGrid(options) or pdfExporter.exportDataGrid(options) method. In the code below, the exportDataGrid method exports the DataGrid as is. You can use ExcelExportDataGridProps/PdfExportDataGridProps to configure export settings. The DataGrid exports its data to an Excel worksheet or a PDF document. To save the Excel document, call the FileSaver's saveAs method. To save the PDF document, call the jsPDF's save method.

    The example below shows how to export DataGrid to Excel file.

    jQuery
    JavaScript
    $('#gridContainer').dxDataGrid({
        export: {
            enabled: true
        },
        onExporting: function(e) { 
            var workbook = new ExcelJS.Workbook(); 
            var worksheet = workbook.addWorksheet('Main sheet'); 
            DevExpress.excelExporter.exportDataGrid({ 
                worksheet: worksheet, 
                component: e.component,
                customizeCell: function(options) {
                    options.excelCell.font = { name: 'Arial', size: 12 };
                    options.excelCell.alignment = { horizontal: 'left' };
                } 
            }).then(function() {
                workbook.xlsx.writeBuffer().then(function(buffer) { 
                    saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx'); 
                }); 
            }); 
        }
    });
    Angular
    app.component.html
    app.component.ts
    app.module.ts
    <dx-data-grid ...
        (onExporting)="onExporting($event)">
        <dxo-export [enabled]="true"></dxo-export>
    </dx-data-grid>
    import { Component } from '@angular/core';
    import { exportDataGrid } from 'devextreme/excel_exporter';
    import { Workbook } from 'exceljs';
    import { saveAs } from 'file-saver';
    import { ExportingEvent } from 'devextreme/ui/data_grid';
    
    @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
    })
    export class AppComponent {
        onExporting(e: ExportingEvent) {
            const workbook = new Workbook();    
            const worksheet = workbook.addWorksheet('Main sheet');
            exportDataGrid({
                component: e.component,
                worksheet: worksheet,
                customizeCell: function(options) {
                    options.excelCell.font = { name: 'Arial', size: 12 };
                    options.excelCell.alignment = { horizontal: 'left' };
                } 
            }).then(function() {
                workbook.xlsx.writeBuffer()
                    .then(function(buffer: BlobPart) {
                        saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
                    });
            });
        }
    }
    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 ...
            @exporting="onExporting">
            <DxExport
                :enabled="true"
            />
        </DxDataGrid>
    </template>
    
    <script>
    import 'devextreme/dist/css/dx.light.css';
    
    import { DxDataGrid, DxExport } from 'devextreme-vue/data-grid';
    import { exportDataGrid } from 'devextreme/excel_exporter';
    import { Workbook } from 'exceljs';
    import saveAs from 'file-saver';
    
    export default {
        components: {
            DxDataGrid,
            DxExport
        },
        methods: {
            onExporting(e) {
                const workbook = new Workbook();
                const worksheet = workbook.addWorksheet('Main sheet');
                exportDataGrid({
                    component: e.component,
                    worksheet: worksheet,
                    customizeCell: function(options) {
                        options.excelCell.font = { name: 'Arial', size: 12 };
                        options.excelCell.alignment = { horizontal: 'left' };
                    } 
                }).then(function() {
                    workbook.xlsx.writeBuffer()
                        .then(function(buffer) {
                            saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
                        });
                });
            }
        }
    }
    </script>
    React
    App.js
    import React from 'react';
    import 'devextreme/dist/css/dx.light.css';
    
    import { Workbook } from 'exceljs';
    import saveAs from 'file-saver';
    import DataGrid, { Export } from 'devextreme-react/data-grid';
    import { exportDataGrid } from 'devextreme/excel_exporter';
    
    class App extends React.Component {
        render() {
            return (
                <DataGrid ...
                    onExporting={this.onExporting}>
                    <Export enabled={true} />
                </DataGrid>
            );
        }
        onExporting(e) {
            const workbook = new Workbook();
            const worksheet = workbook.addWorksheet('Main sheet');
            exportDataGrid({
                component: e.component,
                worksheet: worksheet,
                customizeCell: function(options) {
                    options.excelCell.font = { name: 'Arial', size: 12 };
                    options.excelCell.alignment = { horizontal: 'left' };
                } 
            }).then(function() {
                workbook.xlsx.writeBuffer()
                    .then(function(buffer) {
                        saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
                    });
            });
        }
    }
    export default App;

    The example below shows how to export DataGrid to PDF document.

    jQuery
    JavaScript
    $(function(){
        $('#exportButton').dxButton({
            // ...
            onClick: function() {
                const doc = new jsPDF();
                DevExpress.pdfExporter.exportDataGrid({
                    jsPDFDocument: doc,
                    component: dataGrid
                }).then(function() {
                    doc.save('Customers.pdf');
                });
            }
        });
        const dataGrid = $('#gridContainer').dxDataGrid({
            // ...
        }).dxDataGrid('instance');
    });
    Angular
    app.component.html
    app.component.ts
    app.module.ts
    <dx-button ... 
        (onClick)="exportGrid($event)">
    </dx-button>
    
    <dx-data-grid ... >
        <!-- ... -->
    </dx-data-grid>
    import { Component } from '@angular/core';
    import { exportDataGrid as exportDataGridToPdf } from 'devextreme/pdf_exporter';
    import { jsPDF } from 'jspdf';
    
    @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
    })
    export class AppComponent {
        @ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
        exportGrid() {
            const doc = new jsPDF();
            exportDataGridToPdf({
                jsPDFDocument: doc,
                component: this.dataGrid.instance
            }).then(() => {
                doc.save('Customers.pdf');
            })
        }
    }
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { AppComponent } from './app.component';
    import { DxDataGridModule, DxButtonModule } from 'devextreme-angular';
    
    @NgModule({
        declarations: [
            AppComponent
        ],
        imports: [
            BrowserModule,
            DxDataGridModule,
            DxButtonModule
        ],
        providers: [ ],
        bootstrap: [AppComponent]
    })
    export class AppModule { }
    Vue
    App.vue
    <template>
        <div>
            <DxButton ...
                @click="exportGrid()"
            />
            <DxDataGrid ...
                :ref="dataGridRef">
                <!-- ... -->
            </DxDataGrid>
        </div>
    </template>
    
    <script>
    import 'devextreme/dist/css/dx.light.css';
    
    import DxDataGrid from 'devextreme-vue/data-grid';
    import DxButton from 'devextreme-vue/button';
    import { jsPDF } from 'jspdf';
    import { exportDataGrid as exportDataGridToPdf } from 'devextreme/pdf_exporter';
    const dataGridRef = 'dataGrid';
    export default {
        components: {
            DxDataGrid,
            DxButton
        },
        data() {
            return {
                dataGridRef
            };
        },
        computed: {
            dataGrid: function() {
                return this.$refs[dataGridRef].instance;
            }
        },
        methods: {
            exportGrid() {
                const doc = new jsPDF();
                exportDataGridToPdf({
                    jsPDFDocument: doc,
                    component: this.dataGrid
                }).then(() => {
                    doc.save('Customers.pdf');
                });
            }
        }
    }
    </script>
    React
    App.js
    import React from 'react';
    import 'devextreme/dist/css/dx.light.css';
    
    import DataGrid from 'devextreme-react/data-grid';
    import Button from 'devextreme-react/button';
    import { jsPDF } from 'jspdf';
    import { exportDataGrid as exportDataGridToPdf } from 'devextreme/pdf_exporter';
    export default function App() {
        const dataGridRef = useRef(null);
        function exportGrid() {
            const doc = new jsPDF();
            const dataGrid = dataGridRef.current.instance();
            exportDataGridToPdf({
                jsPDFDocument: doc,
                component: dataGrid
            }).then(() => {
                doc.save('Customers.pdf');
            });
        }
        return (
            <React.Fragment>
                <div>
                    <Button ...
                        onClick={exportGrid}
                    />
                    <DataGrid ...
                        ref={dataGridRef}
                        >
                        {/* ... */}
                    </DataGrid>
                </div>
            </React.Fragment>
        );
    }

The following restrictions apply when users export DataGrid:

Export to Excel Overview Demo Export to PDF Overview Demo Export Images to Excel Demo Export Images to PDF Demo

filterBuilder

Configures the integrated filter builder.

Selector: DxFilterBuilder
Default Value: {}

See the FilterBuilder configuration for properties that you can specify in this object. Do not specify the fields array because the DataGrid automatically populates it to sync filter builder fields with grid columns.

Angular
NOTE
The nested component that configures the filterBuilder property does not support event bindings and two-way property bindings.
Vue
NOTE
The nested component that configures the filterBuilder property does not support event bindings and two-way property bindings.

View Demo

See Also

filterBuilderPopup

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

Selector: DxFilterBuilderPopup
Default Value: {}

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

View Demo

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

filterPanel

Configures the filter panel.

Selector: DxFilterPanel
Type:

FilterPanel

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 property to false. In this case, the filter panel remains synchronized with the filter builder.

View Demo

NOTE
If the filter panel is visible and at least one column includes headerFilter.dataSource or lookup.dataSource, disable the syncLookupFilterValues property. Otherwise, the filter panel may not display data correctly.
See Also

filterRow

Configures the filter row.

Selector: DxFilterRow
Type:

FilterRow

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. Hovering over this icon 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 property.

NOTE
If you use a grouped data structure to display data in a lookup column, the All item in the filter row is not displayed.

DataGrid Demo TreeList 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 property.

Selector: filter-sync-enabled
Type:

Boolean

|

Mode

Default Value: 'auto'

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

filterValue

Specifies a filter expression.

Selector: filter-value
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.

Note that you should convert date strings into JavaScript Date objects before using them in the filter expression.

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.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.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 property 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.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.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 "between", "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. This index is taken from the columns array.

Selector: focused-column-index
Type:

Number

Default Value: -1
Raised Events: onFocusedCellChanged

Unlike banded columns, Band columns cannot be focused.

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

See Also

focusedRowEnabled

Specifies whether the focused row feature is enabled.

Selector: focused-row-enabled
Type:

Boolean

Default Value: false

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

NOTE
Specify the UI component's keyExpr or the Store's key property to ensure that the focused row feature works properly.

DataGrid generates additional requests with comparison operators (for example, < and >) to calculate the page number where a row with a focused key is located. This logic does not work for certain key types (for example, GUID) and data providers (for example, ODataStore). You need to disable the autoNavigateToFocusedRow property or set remoteOperations to false to ensure it operates correctly.

View Demo

See Also

focusedRowIndex

Specifies or indicates the focused data row's index.

Selector: focused-row-index
Type:

Number

Default Value: -1
Raised Events: onFocusedRowChanged

Ensure that focusedRowEnabled is true for focusedRowIndex to work.

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 of -1 indicates 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.

Selector: focused-row-key
Type: any
Default Value: undefined
Raised Events: onFocusedRowChanged

Ensure that focusedRowEnabled is true for focusedRowKey to work.

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

grouping

Configures grouping.

Selector: DxGrouping
Type:

Grouping

groupPanel

Configures the group panel.

Selector: DxGroupPanel
Type:

GroupPanel

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 property to true. Alternatively, the visibility of the group panel can depend on the device's screen size. To accomplish this behavior, set the visible property to "auto".

In case you need to show the group panel, but make it irresponsive, assign false to the groupPanel.allowColumnDragging property. 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.

Record Grouping Demo Remote Grouping Demo

See Also

headerFilter

Configures the header filter feature.

Selector: DxHeaderFilter
Type:

HeaderFilter

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 UI component DataGrid HeaderFilter

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

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

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

DataGrid Demo TreeList Demo

See Also

height

Specifies the UI component's height.

Type:

Number

|

String

|

Function

Return Value:

Number

|

String

The UI component's height.

Default Value: undefined

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

  • Number
    The height in pixels.

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

  • Function (deprecated since v21.2)
    Refer to the W0017 warning description for information on how you can migrate to viewport units.

NOTE
DataGrid does not support the transform: scale CSS rule. Specify height and width as a percentage instead.

highlightChanges

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

Selector: highlight-changes
Type:

Boolean

Default Value: false

Collaborative Editing Demo SignalR Service Demo

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 UI component.

Type:

String

Default Value: undefined

hoverStateEnabled

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

Selector: hover-state-enabled
Type:

Boolean

Default Value: false

keyboardNavigation

Configures keyboard navigation.

Selector: DxKeyboardNavigation

keyExpr

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

Selector: key-expr
Type:

String

|

Array<String>

Default Value: undefined

loadPanel

Configures the load panel.

Selector: DxLoadPanel
Type:

LoadPanel

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

DevExtreme HTML5 JavaScript jQuery Angular Knockout UI component DataGrid TreeList LoadPanel

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

See Also

masterDetail

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

Selector: DxMasterDetail
Type:

MasterDetail

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 property. After that, specify the template for detail sections using the masterDetail.template property. Templates allow you to place virtually anything into the detail sections. For example, you can display another DataGrid or any other UI component there. For more information on specifying the template for the detail sections, see the template property description.

Master-Detail View Demo Advanced Master-Detail View Demo

See Also

noDataText

Specifies a text string shown when the DataGrid does not display any data.

Selector: no-data-text
Type:

String

Default Value: 'No data'

onAdaptiveDetailRowPreparing

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

Selector: @adaptive-detail-row-preparing
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
formOptions

Object

The properties of the Form UI component.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

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

NOTE

The following Form properties cannot be specified using formOptions:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        onAdaptiveDetailRowPreparing: function(e) {
            e.formOptions.colCount = 2;
            e.formOptions.colCountByScreen = {
                xs: 2
            }
            e.formOptions.labelLocation = 'left';
        }
    })
})
Angular
TypeScript
HTML
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    onAdaptiveDetailRowPreparing(e) {
        e.formOptions.colCount = 2;
        e.formOptions.colCountByScreen = {
            xs: 2
        }
        e.formOptions.labelLocation = 'left';
    }
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
<dx-data-grid ...
    (onAdaptiveDetailRowPreparing)="onAdaptiveDetailRowPreparing($event)">
</dx-data-grid>
Vue
App.vue (Options API)
App.vue (Composition API)
<template>
    <DxDataGrid
        @adaptive-detail-row-preparing="onAdaptiveDetailRowPreparing"
    />
</template>

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

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

export default {
    components: {
        DxDataGrid
    },
    methods: {
        onAdaptiveDetailRowPreparing(e) {
            e.formOptions.colCount = 2;
            e.formOptions.colCountByScreen = {
                xs: 2
            }
            e.formOptions.labelLocation = 'left';
        }
    }
}
</script>
<template>
    <DxDataGrid
        @adaptive-detail-row-preparing="onAdaptiveDetailRowPreparing"
    />
</template>

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

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

const onAdaptiveDetailRowPreparing = (e) => {
    e.formOptions.colCount = 2;
    e.formOptions.colCountByScreen = {
        xs: 2
    }
    e.formOptions.labelLocation = 'left';
}
</script>
React
App.js
import { useCallback } from 'react';

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

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

export default function App() {
    const onAdaptiveDetailRowPreparing = useCallback((e) => {
        e.formOptions.colCount = 2;
        e.formOptions.colCountByScreen = {
            xs: 2
        }
        e.formOptions.labelLocation = 'left';
    }, []);

    return (
        <DataGrid
            onAdaptiveDetailRowPreparing={onAdaptiveDetailRowPreparing}
        />
    );
}
See Also

onCellClick

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

Selector: @cell-click
Type:

Function

Function parameters:

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 UI component'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 UI component'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 an EventObject or a jQuery.Event when you use jQuery.

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.

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.

Selector: @cell-dbl-click
Type:

Function

Function parameters:

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 UI component'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 UI component'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 an EventObject 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".

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.

Selector: @cell-hover-changed
Type:

Function

Function parameters:

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 UI component'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 UI component'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.

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.

View on GitHub

onCellPrepared

A function that is executed after a grid cell is created.

Selector: @cell-prepared
Type:

Function

Function parameters:

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 visible column index described in the following topic: Column and Row Indexes.

component

DataGrid

The UI component'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. Available if the rowType is "data".
Differs from the value field only when the column to which the prepared cell belongs uses lookup.

element

HTMLElement | jQuery

The UI component'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. Available if rowType is "data" 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. 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.

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. Available if the rowType is "data".

value any

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

watch

Function

Allows you to track a variable and execute 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

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.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.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>

View on GitHub

See Also

onContentReady

A function that is executed when the UI component is rendered and each time the component is repainted.

Selector: @content-ready
Type:

Function

Function parameters:

Information about the event.

Object structure:
Name Type Description
element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

onContextMenuPreparing

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

Selector: @context-menu-preparing
Type:

Function

Function parameters:

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 UI component's instance.

element

HTMLElement | jQuery

The UI component'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 property description. Each item also contains the onItemClick event handler, which allows you to access the clicked or tapped item's data.

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.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.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;

View on GitHub

onDataErrorOccurred

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

Selector: @data-error-occurred
Type:

Function

Function parameters:

Information on the occurred error.

Object structure:
Name Type Description
error

JavaScript Error Object

The standard Error object that defines the error.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

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 UI component is disposed of.

Selector: @disposing
Type:

Function

Function parameters:

Information about the event.

Object structure:
Name Type Description
element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

onEditCanceled

A function that is executed after row changes are discarded.

Selector: @edit-canceled
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
changes

Array<DataChange>

Discarded row changes.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

onEditCanceling

A function that is executed when the edit operation is canceled, but row changes are not yet discarded.

Selector: @edit-canceling
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
changes

Array<DataChange>

Row changes to be discarded.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

cancel

Boolean

Set this field to true if the row changes should not be discarded.

Default Value: null

An edit operation can be canceled from the UI (with the Cancel button) or programatically (with the cancelEditData() method).

View Demo

onEditingStart

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

Selector: @editing-start
Type:

Function

Function parameters:

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 "cell" and "batch" editing modes.

component

DataGrid

The UI component's instance.

data

Object

The data of a row to be edited.

element

HTMLElement | jQuery

The UI component'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.

Default Value: null

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

View Demo

onEditorPrepared

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

Selector: @editor-prepared
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
component

DataGrid

The UI component'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 UI component's container. It is an HTML Element or a jQuery Element when you use jQuery.

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 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.

Selector: @editor-preparing
Type:

Function

Function parameters:

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 UI component's instance.

dataField

String

The name of the field that supplies 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 UI components only, for example, "dxTextBox".
Import a new editor's module when DevExtreme modules are used.

editorOptions

Object

Gets and sets the editor's configuration.

element

HTMLElement | jQuery

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

parentType

String

The editor's location. One of "dataRow", "filterRow", "headerRow" or "searchPanel".
Properties 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 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") {
                    const defaultValueChangeHandler = e.editorOptions.onValueChanged;
                    e.editorOptions.onValueChanged = function(args) { // Override the default handler
                        // ...
                        // Custom commands go here
                        // ...
                        // If you want to modify the editor value, call the setValue function:
                        // e.setValue(newValue);
                        // Otherwise, call the default handler:
                        defaultValueChangeHandler(args);
                    }
                }
            }
        });
    });
    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') {
                const defaultValueChangeHandler = e.editorOptions.onValueChanged;
                e.editorOptions.onValueChanged = function (args) { // Override the default handler
                    // ...
                    // Custom commands go here
                    // ...
                    // If you want to modify the editor value, call the setValue function:
                    // e.setValue(newValue);
                    // Otherwise, call the default handler:
                    defaultValueChangeHandler(args);
                }
            }
        }
    }
    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.light.css';
    
    import DxDataGrid from 'devextreme-vue/data-grid';
    
    export default {
        components: {
            DxDataGrid
        },
        // ...
        methods: {
            overrideOnValueChanged(e) {
                if (e.dataField === 'requiredDataField' && e.parentType === 'dataRow') {
                    const defaultValueChangeHandler = e.editorOptions.onValueChanged;
                    e.editorOptions.onValueChanged = function (args) { // Override the default handler
                        // ...
                        // Custom commands go here
                        // ...
                        // If you want to modify the editor value, call the setValue function:
                        // e.setValue(newValue);
                        // Otherwise, call the default handler:
                        defaultValueChangeHandler(args);
                    }
                }
            }
        }
    }
    </script>
    React
    App.js
    import React from 'react';
    
    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') {
                const defaultValueChangeHandler = e.editorOptions.onValueChanged;
                e.editorOptions.onValueChanged = function (args) { // Override the default handler
                    // ...
                    // Custom commands go here
                    // ...
                    // If you want to modify the editor value, call the setValue function:
                    // e.setValue(newValue);
                    // Otherwise, call the default handler:
                    defaultValueChangeHandler(args);
                }
            }
        }
        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") {
                const defaultValueChangeHandler = e.editorOptions.onValueChanged;
                e.editorOptions.onValueChanged = function(args) { // Override the default handler
                    // ...
                    // Custom commands go here
                    // ...
                    // If you want to modify the editor value, call the setValue function:
                    // e.setValue(newValue);
                    // Otherwise, call the default handler:
                    defaultValueChangeHandler(args);
                }
            }
        }
    </script>
  • Customize editors used in the search panel, filter row, and selection column.
    Use the parentType function parameter to check if the editor that the function customizes belongs to one of these UI elements.

  • Dynamically change editor properties 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.

  • This function has the highest priority over the other editing tools. The order of priority is as follows: onEditorPreparing > columns.formItem > editing.form.

See Also

onExporting

A function that is executed before data is exported.

Selector: @exporting
Type:

Function

Function parameters:

Information about the event that caused the function execution.

Object structure:
Name Type Description
cancel

Boolean

Deprecated.

component

DataGrid

The UI component's instance.

element

HTMLElement | jQuery

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

fileName

String

Deprecated.

format

DataGridExportFormat

|

String

Specifies the availability and captions of data export buttons.

selectedRowsOnly

Boolean

Specifies whether to export only selected data.

Default Value: null

You can use this function to adjust column properties before export. In the following code, the column.visible property's value is changed to export the hidden ID column to an Excel file.

jQuery
JavaScript
$(function() {
    $('#gridContainer').dxDataGrid({
        // ...
        export: {
            enabled: true
        },
        columns: [{
            dataField: 'ID',
            visible: false
        }, {
            // ...
        }],
        onExporting: function(e) { 
            e.component.beginUpdate();
            e.component.columnOption('ID', 'visible', true);
            var workbook = new ExcelJS.Workbook(); 
            var worksheet = workbook.addWorksheet('Main sheet');

            DevExpress.excelExporter.exportDataGrid({
                component: e.component,
                worksheet: worksheet
            }).then(function() {
                workbook.xlsx.writeBuffer().then(function(buffer) {
                    saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
                });
            }).then(function() {
                e.component.columnOption('ID', 'visible', false);
                e.component.endUpdate();
            });
        }
    });
});
Angular
app.component.html
app.component.ts
app.module.ts
<dx-data-grid ...
    (onExporting)="onExporting($event)">
    <dxo-export [enabled]="true"></dxo-export>
    <dxi-column dataField="ID" [visible]="false"></dxi-column>
</dx-data-grid>
import { Component } from '@angular/core';
import { exportDataGrid } from 'devextreme/excel_exporter';
import { Workbook } from 'exceljs';
import saveAs from 'file-saver';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    onExporting(e) {
        e.component.beginUpdate();
        e.component.columnOption('ID', 'visible', true);
        const workbook = new Workbook();
        const worksheet = workbook.addWorksheet('Employees');

        exportDataGrid({
            component: e.component,
            worksheet: worksheet
        }).then(function() {
            workbook.xlsx.writeBuffer().then(function(buffer: BlobPart) {
                saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
            });
        }).then(function() {
            e.component.columnOption('ID', 'visible', false);
            e.component.endUpdate();
        });
    }
}
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 ...
        @exporting="onExporting">
        <DxExport :enabled="true" />
        <DxColumn data-field="ID" :visible="false" />
    </DxDataGrid>
</template>

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

import { DxDataGrid, DxExport, DxColumn } from 'devextreme-vue/data-grid';
import { exportDataGrid } from 'devextreme/excel_exporter';
import { Workbook } from 'exceljs';
import saveAs from 'file-saver';

export default {
    components: {
        DxDataGrid,
        DxExport,
        DxColumn
    },
    methods: {
        onExporting(e) {
            e.component.beginUpdate();
            e.component.columnOption('ID', 'visible', true);
            const workbook = new Workbook();
            const worksheet = workbook.addWorksheet('Employees');

            exportDataGrid({
                component: e.component,
                worksheet: worksheet
            }).then(function() {
                workbook.xlsx.writeBuffer().then(function(buffer) {
                    saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
                });
            }).then(function() {
                e.component.columnOption('ID', 'visible', false);
                e.component.endUpdate();
            });
        }
    }
}
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

import { Workbook } from 'exceljs';
import saveAs from 'file-saver';
import DataGrid, { Export, Column } from 'devextreme-react/data-grid';
import { exportDataGrid } from 'devextreme/excel_exporter';

class App extends React.Component {
    render() {
        return (
            <DataGrid ...
                onExporting={this.onExporting}>
                <Export enabled={true} />
                <Column dataField="ID" visible={false} />
            </DataGrid>
        );
    }
    onExporting(e) {
        e.component.beginUpdate();
        e.component.columnOption('ID', 'visible', true);
        const workbook = new Workbook();
        const worksheet = workbook.addWorksheet('Employees');

        exportDataGrid({
            component: e.component,
            worksheet: worksheet
        }).then(function() {
            workbook.xlsx.writeBuffer().then(function(buffer) {
                saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
            });
        }).then(function() {
            e.component.columnOption('ID', 'visible', false);
            e.component.endUpdate();
        });
    }
}
export default App;

Export to Excel Overview Demo Export to PDF Overview Demo

See Also

onFocusedCellChanged

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

Selector: @focused-cell-changed
Type:

Function

Function parameters:

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 UI component's instance.

element

HTMLElement | jQuery

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

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.

Selector: @focused-cell-changing
Type:

Function

Function parameters:

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 UI component's instance.

element

HTMLElement | jQuery

The UI component'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 an EventObject 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.

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

View Demo

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.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.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.

Selector: @focused-row-changed
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
component

DataGrid

The UI component's instance.

element

HTMLElement | jQuery

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

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.

Selector: @focused-row-changing
Type:

Function

Function parameters:

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 UI component's instance.

element

HTMLElement | jQuery

The UI component'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 an EventObject or a jQuery.Event when you use jQuery.

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 UI component instance.

Selector: @initialized
Type:

Function

Function parameters:

Information about the event.

Object structure:
Name Type Description
element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

Angular
app.component.html
app.component.ts
<dx-data-grid ...
    (onInitialized)="saveInstance($event)">
</dx-data-grid>
import { Component } from "@angular/core";
import DataGrid from "devextreme/ui/data_grid";
// ...
export class AppComponent {
    dataGridInstance: DataGrid;
    saveInstance (e) {
        this.dataGridInstance = e.component;
    }
}
Vue
App.vue (Options API)
App.vue (Composition API)
<template>
    <div>
        <DxDataGrid ...
            @initialized="saveInstance">
        </DxDataGrid>
    </div>
</template>

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

export default {
    components: {
        DxDataGrid
    },
    data: function() {
        return {
            dataGridInstance: null
        };
    },
    methods: {
        saveInstance: function(e) {
            this.dataGridInstance = e.component;
        }
    }
};
</script>
<template>
    <div>
        <DxDataGrid ...
            @initialized="saveInstance">
        </DxDataGrid>
    </div>
</template>

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

let dataGridInstance = null;

const saveInstance = (e) => {
    dataGridInstance = e.component;
}
</script>
React
App.js
import DataGrid from 'devextreme-react/data-grid';

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

        this.saveInstance = this.saveInstance.bind(this);
    }

    saveInstance(e) {
        this.dataGridInstance = e.component;
    }

    render() {
        return (
            <div>
                <DataGrid onInitialized={this.saveInstance} />
            </div>
        );
    }
}
See Also
jQuery
  • Get a UI component Instance in jQuery
Angular
  • Get a UI component Instance in Angular
Vue
  • Get a UI component Instance in Vue
React
  • Get a UI component Instance in React

onInitNewRow

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

Selector: @init-new-row
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
promise

Promise<void> (jQuery or native)

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

data

Object

The data of the inserted row; initially empty.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

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.

DataGrid Demo TreeList Demo

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';
import { lastValueFrom } from 'rxjs';

@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 lastValueFrom(this.httpClient.get("https://www.mywebsite.com/api/getDefaultData"))
            .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.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.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 UI component is in focus and a key has been pressed down.

Selector: @key-down
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
handled

Boolean

Indicates whether the UI component has already handled this event.

event

Event (jQuery or EventObject)

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

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

The following code shows how to handle a key combination:

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.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.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 UI component property is changed.

Selector: @option-changed
Type:

Function

Function parameters:

Information about the event.

Object structure:
Name Type Description
value any

The modified property's new value.

previousValue any

The UI component's previous value.

name

String

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

fullName

String

The path to the modified property that includes all parent properties.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

The following example shows how to subscribe to component property changes:

jQuery
index.js
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        onOptionChanged: function(e) {
            if(e.name === "changedProperty") {
                // handle the property change here
            }
        }
    });
});
Angular
app.component.html
app.component.ts
app.module.ts
<dx-data-grid ...
    (onOptionChanged)="handlePropertyChange($event)"> 
</dx-data-grid>
import { Component } from '@angular/core'; 

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'] 
}) 

export class AppComponent { 
    // ...
    handlePropertyChange(e) {
        if(e.name === "changedProperty") { 
            // handle the property change here
        }
    }
}
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 ...
        @option-changed="handlePropertyChange"
    />            
</template> 

<script>  
import 'devextreme/dist/css/dx.light.css'; 
import DxDataGrid from 'devextreme-vue/data-grid'; 

export default { 
    components: { 
        DxDataGrid
    }, 
    // ...
    methods: { 
        handlePropertyChange: function(e) {
            if(e.name === "changedProperty") {
                // handle the property change here
            }
        }
    } 
} 
</script> 
React
App.js
import React from 'react';  
import 'devextreme/dist/css/dx.light.css'; 

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

const handlePropertyChange = (e) => {
    if(e.name === "changedProperty") {
        // handle the property change here
    }
}

export default function App() { 
    return ( 
        <DataGrid ...
            onOptionChanged={handlePropertyChange}
        />        
    ); 
} 

onRowClick

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

Selector: @row-click
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
columns

Array<Object>

All column configurations.

component

DataGrid

The UI component's instance.

data

Object

The row's data.

element

HTMLElement | jQuery

The UI component'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 an EventObject 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 UI component functions have already handled the event.

isExpanded

Boolean

Indicates whether the row is expanded or collapsed. Available if rowType is "data" 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.

key any

The row's key.

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 UI component 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.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.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.

Selector: @row-collapsed
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
key any

The key of the row.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

onRowCollapsing

A function that is executed before a row is collapsed.

Selector: @row-collapsing
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
key any

The key of the row.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

cancel

Boolean

Allows you to cancel row collapsing.

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.

Selector: @row-dbl-click
Type:

Function

Function parameters:

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 UI component's instance.

data

Object

The row's data.

element

HTMLElement | jQuery

The UI component'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 an EventObject 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" 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".

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 UI component's container:

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

onRowExpanded

A function that is executed after a row is expanded.

Selector: @row-expanded
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
key any

The key of the row.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

onRowExpanding

A function that is executed before a row is expanded.

Selector: @row-expanding
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
key any

The key of the group or master row.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

cancel

Boolean

Allows you to cancel row expansion.

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.

Selector: @row-inserted
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
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.

error

JavaScript Error Object

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

data

Object

The data of the row.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

View Demo

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.

Selector: @row-inserting
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
data

Object

The data of the row that should be inserted.

cancel

Boolean

|

Promise<Boolean> (jQuery or native)

|

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.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

This function allows you to intercept row insertion and perform additional actions. 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 a user confirms it and 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) {
            const deferred = $.Deferred();
            const promptPromise = DevExpress.ui.dialog.confirm("Are you sure?", "Confirm changes");
            promptPromise.done((dialogResult) => {
                if (dialogResult) {
                    $.ajax({
                        url: "https://url/to/your/validation/service",
                        dataType: "json",
                        data: e.newData,
                        success: function(validationResult) {
                            if (validationResult.errorText) {
                                deferred.reject(validationResult.errorText);
                            } else {
                                deferred.resolve(false);
                            }
                        },
                        error: function() {
                            deferred.reject("Data Loading Error");
                        },
                        timeout: 5000
                    });
                } else {
                    deferred.resolve(true);              
                }
            });
            e.cancel = deferred.promise();
        }
    })
})
Angular
app.component.ts
app.component.html
app.module.ts
import { HttpClient, HttpClientModule, HttpParams } from "@angular/common/http";
import { confirm } from 'devextreme/ui/dialog';
import { lastValueFrom } from 'rxjs';
// ...

export class AppComponent {
    constructor(private httpClient: HttpClient) { /*...*/ }
    async insertRow(e) {
        try {
            const dialogResult = await this.confirmAsync("Are you sure?", "Confirm changes");
            if (dialogResult) {
                let params = new HttpParams();
                for (let key in e.newData) {
                    params = params.set(key, e.newData[key]);
                }
                const validationResult = await lastValueFrom(this.httpClient.get("https://url/to/your/validation/service", { params }));
                if (validationResult.errorText) {
                    throw validationResult.errorText;
                } else {
                    e.cancel = false;
                }
            } else {
                e.cancel = true;
            }
        } catch (error) {
            console.error("Validation or confirmation error", error);
            e.cancel = Promise.reject(error);
        }
    }

    private confirmAsync(message: string, title?: string): Promise<boolean> {
        return new Promise<boolean>((resolve) => {
            const dialogResult = confirm(message, title);
            resolve(dialogResult);
        });
    }
}
<dx-data-grid ... 
    (onRowInserting)="insertRow($event)">
</dx-data-grid>
// ... 
import { DxDataGridModule } from 'devextreme-angular'; 
import { HttpClientModule } from "@angular/common/http";

@NgModule({
    imports: [
        // ...
        DxDataGridModule,
        HttpClientModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ...
        @row-inserting="insertRow">
    </DxDataGrid>
</template>
<script>
import DxDataGrid, { ... } from 'devextreme-vue/data-grid';
import { confirm } from 'devextreme/ui/dialog';
// ...

export default {
    components: {
        DxDataGrid,
        // ...
    },
    // ...
    methods: {
        insertRow(e) {
            const isCanceled = new Promise((resolve, reject) => {
                const promptPromise = confirm("Are you sure?", "Confirm changes");
                promptPromise.then((dialogResult) => {
                    if (dialogResult) {
                        let params = new HttpParams();
                        for (let key in e.newData) {
                            params = params.set(key, e.newData[key]);
                        }
                        fetch(`https://url/to/your/validation/service${params}`)
                            .then((validationResult) => {
                                if (validationResult.errorText) {
                                    reject(validationResult.errorText);
                                } else {
                                    resolve(false);
                                } 
                            });
                    } else {
                        return resolve(true);
                    }
                });
            });
            e.cancel = isCanceled;
        }
    },
};
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

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

function insertRow(e) {
    const isCanceled = new Promise((resolve, reject) => {
        const promptPromise = confirm("Are you sure?", "Confirm changes");
        promptPromise.then((dialogResult) => {
            if (dialogResult) {
                let params = new HttpParams();
                for (let key in e.newData) {
                    params = params.set(key, e.newData[key]);
                }
                fetch(`https://url/to/your/validation/service${params}`)
                    .then((validationResult) => {
                        if (validationResult.errorText) {
                            reject(validationResult.errorText);
                        } else {
                            resolve(false);
                        } 
                    });
            } else {
                return resolve(true);
            }
        });
    });
    e.cancel = isCanceled;
}

function App() {
    return (
        <DataGrid ...
            onRowInserting={insertRow}>
            // ...
        </DataGrid>
    );
}

export default App;
NOTE
  • Do not use this function to insert data. If you need a custom insert logic, implement CustomStore's insert function.

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

onRowPrepared

A function that is executed after a row is created.

Selector: @row-prepared
Type:

Function

Function parameters:

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 UI component's instance.

data

Object

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

element

HTMLElement | jQuery

The UI component'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. Available if rowType is "data" or "group".

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.

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.

Selector: @row-removed
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
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.

error

JavaScript Error Object

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

data

Object

The data of the row.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

View Demo

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.

Selector: @row-removing
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
key any

The row's key.

data

Object

The data of the row that should be removed.

cancel

Boolean

|

Promise<Boolean> (jQuery or native)

|

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.

element

HTMLElement | jQuery

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

component

DataGrid

The UI component's instance.

Default Value: null

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

This function allows you to intercept row removal and perform additional actions. The following code shows how to use the function parameter's cancel field to prevent or continue removal. In this code, a Promise is assigned to this field. Removal continues if a user confirms it and row validation on the server succeeds (the Promise is resolved); otherwise, removal is prevented (the Promise is rejected):

jQuery
JavaScript
$(function(){
    $("#dataGridContainer").dxDataGrid({
        // ...
        onRowRemoving: function(e) {
            var deferred = $.Deferred();
            $.ajax({
                url: `https://url/to/your/validation/service/${e.key}`,
                success: function(validationResult) {
                    if (validationResult.errorText) {
                        deferred.reject(validationResult.errorText);
                    } else {
                        deferred.resolve(false);
                    }
                },
                error: function() {
                    deferred.reject("Data Loading Error");
                },
                timeout: 5000
            });
            e.cancel = deferred.promise();
        },
    })
})
Angular
TypeScript
app.component.html
app.module.ts
import { DxDataGridModule } from "devextreme-angular";
import { HttpClient, HttpClientModule, HttpParams } from "@angular/common/http";
import { lastValueFrom } from 'rxjs';

export class AppComponent {
    constructor(private httpClient: HttpClient) { /*...*/ }
    validateRemove(e) {
        const isCanceled = new Promise((resolve, reject) => {
            const request$ = this.httpClient
                .get(`https://url/to/your/validation/service/${e.key}`);

            lastValueFrom(request$).then((validationResult) => {
                if (validationResult.errorText) {
                    reject(validationResult.errorText);
                } else {
                    resolve(false);
                }
            });
        });
        e.cancel = isCanceled;
    }
}
<dx-data-grid ... 
    (onRowRemoving)="validateRemove($event)">
</dx-data-grid>
// ... 
import { DxDataGridModule } from 'devextreme-angular'; 
import { HttpClientModule } from "@angular/common/http";

@NgModule({
    imports: [
        // ...
        DxDataGridModule,
        HttpClientModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ...
        @row-removing="validateRemove">
    </DxDataGrid>
</template>
<script>
import DxDataGrid, { ... } from 'devextreme-vue/data-grid';
// ...

export default {
    components: {
        DxDataGrid,
        // ...
    },
    // ...
    methods: {
        validateRemove(e) {
            const isCanceled = new Promise((resolve, reject) => {
                fetch(`https://url/to/your/validation/service/${e.key}`)
                    .then((validationResult) => {
                        if (validationResult.errorText) {
                            reject(validationResult.errorText);
                        } else {
                            resolve(false);
                        }
                    });
            });
            e.cancel = isCanceled;
        }
    },
};
</script>
React
App.js
import React from 'react';
import 'devextreme/dist/css/dx.light.css';

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

function validateRemove(e) {
    const isCanceled = new Promise((resolve, reject) => {
        fetch(`https://url/to/your/validation/service/${e.key}`)
            .then((validationResult) => {
                if (validationResult.errorText) {
                    reject(validationResult.errorText);
                } else {
                    resolve(false);
                }
            });
    });
    e.cancel = isCanceled;
}

function App() {
    return (
        <DataGrid ...
            onRowRemoving={validateRemove}>
            // ...
        </DataGrid>
    );
}

export default App;

onRowUpdated

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

Selector: @row-updated
Type:

Function

Function parameters:

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

Object structure:
Name Type Description
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.

error