Sorting

User Interaction

With the DataGrid widget, a user can sort by single and multiple columns. Use the sorting.mode option to specify the current sorting mode.

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        sorting: {
            mode: "single" // or "multiple" | "none"
        }
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxo-sorting
        mode="single"> <!-- or "multiple" | "none" -->
    </dxo-sorting>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid>
        <DxSorting mode="single"/> <!-- or "multiple" | "none" -->
    </DxDataGrid>
</template>

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

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

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

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

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

class App extends React.Component {
    render() {
        return (
            <DataGrid>
                <Sorting mode="single"/> {/* or "multiple" | "none" */}
            </DataGrid>
        );
    }
}
export default App;

In single mode, the user can click a column header to sort by the column. Subsequent clicks on the same header reverse the sort order. When the user sorts by a column, the sorting settings of other columns are canceled.

In multiple mode, the user clicks a column header while pressing the Shift key to sort by the column. Sorting settings of other columns remain intact.

In both modes, the user can use the column header's context menu to apply sorting.

DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Sorting

To cancel a column's sorting settings, the user clicks the column's header while pressing Ctrl or uses the context menu:

DevExtreme HTML5 JavaScript jQuery Angular Knockout Widget DataGrid Sorting

To disable sorting in the whole widget, set the sorting.mode option to "none"; to disable sorting only in a specific column, use its allowSorting option.

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        columns: [{
            // ...
            allowSorting: false
        }]
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxi-column [allowSorting]="false"></dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";
// ...
export class AppComponent {
    // ...
}
@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid>
        <DxColumn :allow-sorting="false"/>
    </DxDataGrid>
</template>

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

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

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

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

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

class App extends React.Component {
    render() {
        return (
            <DataGrid>
                <Column allowSorting={false}/>
            </DataGrid>
        );
    }
}
export default App;

View Demo

See Also

API

Initial and Runtime Sorting

Rows are sorted according to the data source by default. Set the sortOrder option to sort rows in the required order. Specify the sortIndex option as well to sort by multiple columns. Otherwise, each sorted column gets a sort index according to its position in the columns array. For example, the following code sorts rows first by the "Country", then by the "City" column:

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        // ...
        columns: [
            { dataField: "City",    sortIndex: 1, sortOrder: "asc" },
            { dataField: "Country", sortIndex: 0, sortOrder: "asc" },
            // ...
        ]
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxi-column
        dataField="City"
        [sortIndex]="1"
        sortOrder="asc">
    </dxi-column>
    <dxi-column
        dataField="Country"
        [sortIndex]="0"
        sortOrder="asc">
    </dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";

export class AppComponent {
    // ...
}

@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid>
        <DxColumn
            data-field="City"
            :sort-index="1"
            sort-order="asc"
        />
        <DxColumn
            data-field="Country"
            :sort-index="0"
            sort-order="asc"
        />
    </DxDataGrid>
</template>

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

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

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

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

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

class App extends React.Component {
    render() {
        return (
            <DataGrid>
                <Column
                    dataField="City"
                    defaultSortIndex={1}
                    defaultSortOrder="asc" />
                <Column
                    dataField="Country"
                    defaultSortIndex={0}
                    defaultSortOrder="asc" />
            </DataGrid>
        );
    }
}
export default App;

Change the sortOrder and sortIndex options using the columnOption method to sort at runtime.

jQuery
JavaScript
var dataGrid = $("#dataGridContainer").dxDataGrid("instance");
dataGrid.columnOption("Country", {
    sortIndex: 2,
    sortOrder: "desc"
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxi-column
        dataField="Country"
        [(sortOrder)]="countrySortOrder">
    </dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";

export class AppComponent {
    countrySortOrder: string = "asc";

    sortByCountries(order: string) {
        this.countrySortOrder = order;
    }
}

@NgModule({
    imports: [
        //...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ...>
        <DxColumn
            data-field="Country"
            v-model:sort-order="countrySortOrder"
        />
    </DxDataGrid>
</template>

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

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

export default {
    components: {
        DxDataGrid,
        DxColumn
    },
    data() {
        return {
            countrySortOrder: "asc"
        }
    },
    methods: {
        sortByCountries(order) {
            this.countrySortOrder = order;
        }
    }
}
</script>
React
App.js
import React from 'react';

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

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

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            countrySortOrder: "asc"
        };
    }

    render() {
        return (
            <DataGrid ...
                onOptionChanged={this.onOptionChanged}>
                <Column
                    dataField="Country"
                    sortOrder={this.state.countrySortOrder} />
            </DataGrid>
        );
    }

    sortByCountries = (order) => {
        this.setState({
            countrySortOrder: order
        });
    }

    onOptionChanged = (e) => {
        if (e.fullName === "columns[0].sortOrder") {
            this.sortByCountries(e.value);
        }
    }
}
export default App;

Custom Sorting

Implement a custom sorting routine using the calculateSortValue option if standard sorting does not meet your requirements. It accepts the name of the data source field that provides values to be used in sorting...

jQuery
JavaScript
$(function() {
    $("#dataGridContainer").dxDataGrid({
        columns: [{
            dataField: "Position", // provides values for the column
            calculateSortValue: "isOnVacation" // provides values to be used in sorting 
        }]
    });
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxi-column
        dataField="Position" <!--provides values for the column -->
        calculateSortValue="isOnVacation"> <!-- provides values to be used in sorting -->
    </dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";

export class AppComponent {
    // ...
}

@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid>
        <!-- data-field provides values for the column -->
        <!-- calculate-sort-value provides values to be used in sorting -->
        <DxColumn
            data-field="Position"
            calculate-sort-value="isOnVacation"
        />
    </DxDataGrid>
</template>

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

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

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

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

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

class App extends React.Component {
    render() {
        return (
            <DataGrid>
                {/* dataField provides values for the column */}
                {/* calculateSortValue provides values to be used in sorting */}
                <Column
                    dataField="Position"
                    calculateSortValue="isOnVacation" />
            </DataGrid>
        );
    }
}
export default App;

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

jQuery
JavaScript
$(function() {
    var dataGrid = $("#dataGridContainer").dxDataGrid({
        columns: [{
            dataField: "Position",
            sortOrder: "asc",
            calculateSortValue: function (rowData) {
                if (rowData.Position == "CEO")
                    return dataGrid.columnOption('Position', 'sortOrder') == 'asc' ? "aaa" : "zzz"; // CEOs are always displayed at the top  
                else
                    return rowData.Position; // Others are sorted as usual
            }
        }]
    }).dxDataGrid("instance");
});
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxi-column
        dataField="Position"
        sortOrder="asc"
        [calculateSortValue]="calculateSortValue">
    </dxi-column>
</dx-data-grid>
import { DxDataGridModule } from "devextreme-angular";

export class AppComponent {
    calculateSortValue(rowData) {
        if (rowData.Position == "CEO")
            return this.sortOrder == 'asc' ? "aaa" : "zzz"; // CEOs are always displayed at the top
        else
            return rowData.Position; // Others are sorted as usual
    }
}

@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid ...>
        <DxColumn
            data-field="Position"
            sort-order="asc"
            :calculate-sort-value="calculateSortValue"
        />
    </DxDataGrid>
</template>

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

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

export default {
    components: {
        DxDataGrid,
        DxColumn
    },
    data() {
        return {
            calculateSortValue(rowData) {
                if (rowData.Position == "CEO")
                    return this.sortOrder == 'asc' ? "aaa" : "zzz"; // CEOs are always displayed at the top
                else
                    return rowData.Position; // Others are sorted as usual
            }
        };
    }
}
</script>
React
App.js
import React from 'react';

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

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

class App extends React.Component {
    render() {
        return (
            <DataGrid ...>
                <Column
                    dataField="Position"
                    defaultSortOrder="asc"
                    calculateSortValue={this.calculateSortValue} />
            </DataGrid>
        );
    }

    calculateSortValue(rowData) {
        if (rowData.Position == "CEO")
            return this.sortOrder == 'asc' ? "aaa" : "zzz"; // CEOs are always displayed at the top    
        else
            return rowData.Position; // Others are sorted as usual
    }
}
export default App;

Clear Sorting Settings

You can clear sorting settings for all columns by calling the clearSorting() method, or for a specific column - by setting its sortIndex option to undefined using the columnOption method.

jQuery
JavaScript
var dataGrid = $("#dataGridContainer").dxDataGrid("instance");
dataGrid.columnOption("Name", "sortIndex", undefined);
dataGrid.clearSorting();
Angular
HTML
TypeScript
<dx-data-grid ... >
    <dxi-column
        dataField="Name"
        [(sortIndex)]="nameSortIndex">
    </dxi-column>
</dx-data-grid>
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;

    nameSortIndex: number = 0;

    clearNameColumnSorting() {
        this.nameSortIndex = undefined;
    }

    clearAllSorting() {
        this.dataGrid.instance.clearSorting();
    }
}

@NgModule({
    imports: [
        // ...
        DxDataGridModule
    ],
    // ...
})
Vue
App.vue
<template>
    <DxDataGrid :ref="dataGridRefKey">
        <DxColumn
            data-field="Name"
            v-model:sort-index="nameSortIndex"
        />
    </DxDataGrid>
</template>

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

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

const dataGridRefKey = "my-data-grid";

export default {
    components: {
        DxDataGrid
    },
    data() {
        return {
            dataGridRefKey,
            nameSortIndex: 0
        };
    },
    methods: {
        clearNameColumnSorting() {
            this.nameSortIndex = undefined;
        },
        clearAllSorting() {
            this.dataGrid.clearSorting();
        }
    },
    computed: {
        dataGrid() {
            return this.$refs[dataGridRefKey].instance;
        }
    }
}
</script>
React
App.js
import React from 'react';

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

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

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

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

    render() {
        return (
            <DataGrid ref={this.dataGridRef} ...>
                <Column
                    dataField="Name"
                    defaultSortIndex={0} />
            </DataGrid>
        );
    }

    clearNameColumnSorting = () => {
        this.dataGrid.columnOption("Name", "sortIndex", undefined);
    }

    clearAllSorting = () => {
        this.dataGrid.clearSorting();
    }
}
export default App;
See Also