If you have technical questions, please create a support ticket in the DevExpress Support Center.
import React, { useCallback, useState } from 'react';
import {
DataGrid, Column, ColumnChooser, ColumnChooserSearch, ColumnChooserSelection, Position,
} from 'devextreme-react/data-grid';
import { SelectBox, SelectBoxTypes } from 'devextreme-react/select-box';
import { CheckBox, CheckBoxTypes } from 'devextreme-react/check-box';
import { employees } from './data.ts';
const columnChooserModes: {
key: 'select' | 'dragAndDrop',
name: string,
}[] = [{
key: 'dragAndDrop',
name: 'Drag and drop',
}, {
key: 'select',
name: 'Select',
}];
const searchEditorOptions = { placeholder: 'Search column' };
const columnChooserModeLabel = { 'aria-label': 'Column Chooser Mode' };
const App = () => {
const [mode, setMode] = useState(columnChooserModes[1].key);
const [searchEnabled, setSearchEnabled] = useState(true);
const [allowSelectAll, setAllowSelectAll] = useState(true);
const [selectByClick, setSelectByClick] = useState(true);
const [recursive, setRecursive] = useState(true);
const isDragMode = mode === columnChooserModes[0].key;
const onModeValueChanged = useCallback((e: SelectBoxTypes.ValueChangedEvent) => {
setMode(e.value);
}, []);
const onSearchEnabledValueChanged = useCallback((e: CheckBoxTypes.ValueChangedEvent) => {
setSearchEnabled(e.value);
}, []);
const onAllowSelectAllValueChanged = useCallback((e: CheckBoxTypes.ValueChangedEvent) => {
setAllowSelectAll(e.value);
}, []);
const onSelectByClickValueChanged = useCallback((e: CheckBoxTypes.ValueChangedEvent) => {
setSelectByClick(e.value);
}, []);
const onRecursiveValueChanged = useCallback((e: CheckBoxTypes.ValueChangedEvent) => {
setRecursive(e.value);
}, []);
return (
<div>
<DataGrid
id="employees"
dataSource={employees}
keyExpr="ID"
columnAutoWidth={true}
showRowLines={true}
width="100%"
showBorders={true}
>
<Column dataField='FirstName' allowHiding={false} />
<Column dataField='LastName' />
<Column dataField='Position' />
<Column dataField='City' />
<Column dataField='State' />
<Column caption="Contacts">
<Column dataField="MobilePhone" allowHiding={false} />
<Column dataField="Email" />
<Column dataField="Skype" visible={false} />
</Column>
<Column dataField="HireDate" dataType="date" />
<ColumnChooser
height='340px'
enabled={true}
mode={mode}
>
<Position
my="right top"
at="right bottom"
of=".dx-datagrid-column-chooser-button"
/>
<ColumnChooserSearch
enabled={searchEnabled}
editorOptions={searchEditorOptions} />
<ColumnChooserSelection
allowSelectAll={allowSelectAll}
selectByClick={selectByClick}
recursive={recursive} />
</ColumnChooser>
</DataGrid>
<div className="options">
<div className="caption">Options</div>
<div className="selectboxes-container">
<div className="option">
<span>Column chooser mode</span>
<SelectBox
items={columnChooserModes}
value={mode}
valueExpr="key"
inputAttr={columnChooserModeLabel}
displayExpr="name"
onValueChanged={onModeValueChanged}
/>
</div>
</div>
<div className='checkboxes-container'>
<div className="option">
<CheckBox
id="searchEnabled"
defaultValue={searchEnabled}
text="Search enabled"
onValueChanged={onSearchEnabledValueChanged}
/>
</div>
<div className="option">
<CheckBox
id="allowSelectAll"
defaultValue={allowSelectAll}
text="Allow select all"
onValueChanged={onAllowSelectAllValueChanged}
disabled={isDragMode}
/>
</div>
<div className="option">
<CheckBox
id="selectByClick"
defaultValue={selectByClick}
text="Select by click"
onValueChanged={onSelectByClickValueChanged}
disabled={isDragMode}
/>
</div>
<div className="option">
<CheckBox
id="recursive"
defaultValue={recursive}
text="Recursive"
onValueChanged={onRecursiveValueChanged}
disabled={isDragMode}
/>
</div>
</div>
</div>
</div>
);
};
export default App;
xxxxxxxxxx
import React, { useCallback, useState } from 'react';
import {
DataGrid,
Column,
ColumnChooser,
ColumnChooserSearch,
ColumnChooserSelection,
Position,
} from 'devextreme-react/data-grid';
import { SelectBox } from 'devextreme-react/select-box';
import { CheckBox } from 'devextreme-react/check-box';
import { employees } from './data.js';
const columnChooserModes = [
{
key: 'dragAndDrop',
name: 'Drag and drop',
},
{
key: 'select',
name: 'Select',
},
];
const searchEditorOptions = { placeholder: 'Search column' };
const columnChooserModeLabel = { 'aria-label': 'Column Chooser Mode' };
const App = () => {
const [mode, setMode] = useState(columnChooserModes[1].key);
const [searchEnabled, setSearchEnabled] = useState(true);
const [allowSelectAll, setAllowSelectAll] = useState(true);
const [selectByClick, setSelectByClick] = useState(true);
const [recursive, setRecursive] = useState(true);
const isDragMode = mode === columnChooserModes[0].key;
const onModeValueChanged = useCallback((e) => {
setMode(e.value);
}, []);
const onSearchEnabledValueChanged = useCallback((e) => {
setSearchEnabled(e.value);
}, []);
const onAllowSelectAllValueChanged = useCallback((e) => {
setAllowSelectAll(e.value);
}, []);
const onSelectByClickValueChanged = useCallback((e) => {
setSelectByClick(e.value);
}, []);
const onRecursiveValueChanged = useCallback((e) => {
setRecursive(e.value);
}, []);
return (
<div>
<DataGrid
id="employees"
dataSource={employees}
keyExpr="ID"
columnAutoWidth={true}
showRowLines={true}
width="100%"
showBorders={true}
>
<Column
dataField="FirstName"
allowHiding={false}
/>
<Column dataField="LastName" />
<Column dataField="Position" />
<Column dataField="City" />
<Column dataField="State" />
<Column caption="Contacts">
<Column
dataField="MobilePhone"
allowHiding={false}
/>
<Column dataField="Email" />
<Column
dataField="Skype"
visible={false}
/>
</Column>
<Column
dataField="HireDate"
dataType="date"
/>
<ColumnChooser
height="340px"
enabled={true}
mode={mode}
>
<Position
my="right top"
at="right bottom"
of=".dx-datagrid-column-chooser-button"
/>
<ColumnChooserSearch
enabled={searchEnabled}
editorOptions={searchEditorOptions}
/>
<ColumnChooserSelection
allowSelectAll={allowSelectAll}
selectByClick={selectByClick}
recursive={recursive}
/>
</ColumnChooser>
</DataGrid>
<div className="options">
<div className="caption">Options</div>
<div className="selectboxes-container">
<div className="option">
<span>Column chooser mode</span>
<SelectBox
items={columnChooserModes}
value={mode}
valueExpr="key"
inputAttr={columnChooserModeLabel}
displayExpr="name"
onValueChanged={onModeValueChanged}
/>
</div>
</div>
<div className="checkboxes-container">
<div className="option">
<CheckBox
id="searchEnabled"
defaultValue={searchEnabled}
text="Search enabled"
onValueChanged={onSearchEnabledValueChanged}
/>
</div>
<div className="option">
<CheckBox
id="allowSelectAll"
defaultValue={allowSelectAll}
text="Allow select all"
onValueChanged={onAllowSelectAllValueChanged}
disabled={isDragMode}
/>
</div>
<div className="option">
<CheckBox
id="selectByClick"
defaultValue={selectByClick}
text="Select by click"
onValueChanged={onSelectByClickValueChanged}
disabled={isDragMode}
/>
</div>
<div className="option">
<CheckBox
id="recursive"
defaultValue={recursive}
text="Recursive"
onValueChanged={onRecursiveValueChanged}
disabled={isDragMode}
/>
</div>
</div>
</div>
</div>
);
};
export default App;
xxxxxxxxxx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.tsx';
ReactDOM.render(
<App />,
document.getElementById('app'),
);
xxxxxxxxxx
export const employees = [{
ID: 1,
FirstName: 'John',
LastName: 'Heart',
Position: 'CEO',
BirthDate: '1964/03/16',
HireDate: '1995/01/15',
Title: 'Mr.',
Address: '351 S Hill St.',
City: 'Los Angeles',
State: 'California',
Zipcode: 90013,
Email: 'jheart@dx-email.com',
Skype: 'jheartDXskype',
HomePhone: '(213) 555-9208',
DepartmentID: 6,
MobilePhone: '(213) 555-9392',
}, {
ID: 2,
FirstName: 'Olivia',
LastName: 'Peyton',
Position: 'Sales Assistant',
BirthDate: '1981/06/03',
HireDate: '2012/05/14',
Title: 'Mrs.',
Address: '807 W Paseo Del Mar',
City: 'Los Angeles',
State: 'California',
Zipcode: 90036,
Email: 'oliviap@dx-email.com',
Skype: 'oliviapDXskype',
HomePhone: '(310) 555-2728',
DepartmentID: 5,
MobilePhone: '(818) 555-2387',
}, {
ID: 3,
FirstName: 'Robert',
LastName: 'Reagan',
Position: 'CMO',
BirthDate: '1974/09/07',
HireDate: '2002/11/08',
Title: 'Mr.',
Address: '4 Westmoreland Pl.',
City: 'Bentonville',
State: 'Arkansas',
Zipcode: 91103,
Email: 'robertr@dx-email.com',
Skype: 'robertrDXskype',
HomePhone: '(818) 555-2438',
DepartmentID: 6,
MobilePhone: '(818) 555-2387',
}, {
ID: 4,
FirstName: 'Greta',
LastName: 'Sims',
Position: 'HR Manager',
BirthDate: '1977/11/22',
HireDate: '1998/04/23',
Title: 'Ms.',
Address: '1700 S Grandview Dr.',
State: 'Georgia',
City: 'Atlanta',
Zipcode: 91803,
Email: 'gretas@dx-email.com',
Skype: 'gretasDXskype',
HomePhone: '(818) 555-0976',
DepartmentID: 5,
MobilePhone: '(818) 555-6546',
}, {
ID: 5,
FirstName: 'Brett',
LastName: 'Wade',
Position: 'IT Manager',
BirthDate: '1968/12/01',
HireDate: '2009/03/06',
Title: 'Mr.',
Address: '1120 Old Mill Rd.',
State: 'Idaho',
City: 'Boise',
Zipcode: 91108,
Email: 'brettw@dx-email.com',
Skype: 'brettwDXskype',
HomePhone: '(626) 555-5985',
DepartmentID: 7,
MobilePhone: '(626) 555-0358',
}, {
ID: 6,
FirstName: 'Sandra',
LastName: 'Johnson',
Position: 'Controller',
BirthDate: '1974/11/15',
HireDate: '2005/05/11',
Title: 'Mrs.',
Address: '4600 N Virginia Rd.',
State: 'Utah',
City: 'Beaver',
Zipcode: 90807,
Email: 'sandraj@dx-email.com',
Skype: 'sandrajDXskype',
HomePhone: '(562) 555-8272',
DepartmentID: 5,
MobilePhone: '(562) 555-2082',
}, {
ID: 7,
FirstName: 'Kevin',
LastName: 'Carter',
Position: 'Shipping Manager',
BirthDate: '1978/01/09',
HireDate: '2009/08/11',
Title: 'Mr.',
Address: '424 N Main St.',
State: 'California',
City: 'San Diego',
Zipcode: 90012,
Email: 'kevinc@dx-email.com',
Skype: 'kevincDXskype',
HomePhone: '(213) 555-8038',
DepartmentID: 3,
MobilePhone: '(213) 555-2840',
}, {
ID: 8,
FirstName: 'Cynthia',
LastName: 'Stanwick',
Position: 'HR Assistant',
BirthDate: '1985/06/05',
HireDate: '2008/03/24',
Title: 'Ms.',
Address: '2211 Bonita Dr.',
City: 'Little Rock',
State: 'Arkansas',
Zipcode: 90265,
Email: 'cindys@dx-email.com',
Skype: 'cindysDXskype',
HomePhone: '(818) 555-6808',
DepartmentID: 4,
MobilePhone: '(818) 555-6655',
}, {
ID: 9,
FirstName: 'Kent',
LastName: 'Samuelson',
Position: 'Ombudsman',
BirthDate: '1972/09/11',
HireDate: '2009/04/22',
Title: 'Dr.',
Address: '12100 Mora Dr',
City: 'St. Louis',
State: 'Missouri',
Zipcode: 90272,
Email: 'kents@dx-email.com',
Skype: 'kentsDXskype',
HomePhone: '(562) 555-1328',
DepartmentID: 26,
MobilePhone: '(562) 555-9282',
}, {
ID: 10,
FirstName: 'Taylor',
LastName: 'Riley',
Position: 'Network Admin',
BirthDate: '1982/08/14',
HireDate: '2012/04/14',
Title: 'Mr.',
Address: '7776 Torreyson Dr',
City: 'San Jose',
State: 'California',
Zipcode: 90012,
Email: 'taylorr@dx-email.com',
Skype: 'taylorrDXskype',
HomePhone: '(310) 555-9712',
DepartmentID: 5,
MobilePhone: '(310) 555-7276',
}];
xxxxxxxxxx
window.exports = window.exports || {};
window.config = {
transpiler: 'ts',
typescriptOptions: {
module: 'system',
emitDecoratorMetadata: true,
experimentalDecorators: true,
jsx: 'react',
},
meta: {
'react': {
'esModule': true,
},
'typescript': {
'exports': 'ts',
},
'devextreme/time_zone_utils.js': {
'esModule': true,
},
'devextreme/localization.js': {
'esModule': true,
},
'devextreme/viz/palette.js': {
'esModule': true,
},
'openai': {
'esModule': true,
},
},
paths: {
'npm:': 'https://unpkg.com/',
'bundles:': 'bundles/',
'externals:': 'bundles/externals/',
},
defaultExtension: 'js',
map: {
'ts': 'npm:plugin-typescript@8.0.0/lib/plugin.js',
'typescript': 'npm:typescript@4.2.4/lib/typescript.js',
'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js',
'react': 'npm:react@17.0.2/umd/react.development.js',
'react-dom': 'npm:react-dom@17.0.2/umd/react-dom.development.js',
'prop-types': 'npm:prop-types/prop-types.js',
'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js',
'luxon': 'npm:luxon@3.4.4/build/global/luxon.min.js',
'es6-object-assign': 'npm:es6-object-assign',
'devextreme': 'npm:devextreme@link:../../packages/devextreme/artifacts/npm/devextreme/cjs',
'devextreme-react': 'npm:devextreme-react@link:../../packages/devextreme-react/npm/cjs',
'devextreme-quill': 'npm:devextreme-quill@1.7.1/dist/dx-quill.min.js',
'devexpress-diagram': 'npm:devexpress-diagram@2.2.5/dist/dx-diagram.js',
'devexpress-gantt': 'npm:devexpress-gantt@4.1.54/dist/dx-gantt.js',
'@devextreme/runtime': 'npm:@devextreme/runtime@3.0.12',
'inferno': 'npm:inferno@7.4.11/dist/inferno.min.js',
'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js',
'inferno-create-element': 'npm:inferno-create-element@7.4.11/dist/inferno-create-element.min.js',
'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js',
'inferno-hydrate': 'npm:inferno-hydrate/dist/inferno-hydrate.min.js',
'inferno-clone-vnode': 'npm:inferno-clone-vnode/dist/inferno-clone-vnode.min.js',
'inferno-create-class': 'npm:inferno-create-class/dist/inferno-create-class.min.js',
'inferno-extras': 'npm:inferno-extras/dist/inferno-extras.min.js',
'devextreme-cldr-data': 'npm:devextreme-cldr-data@1.0.3',
// SystemJS plugins
'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js',
'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js',
// Prettier
'prettier/standalone': 'npm:prettier@2.8.8/standalone.js',
'prettier/parser-html': 'npm:prettier@2.8.8/parser-html.js',
},
packages: {
'devextreme': {
defaultExtension: 'js',
},
'devextreme-react': {
main: 'index.js',
},
'devextreme/events/utils': {
main: 'index',
},
'devextreme/localization/messages': {
format: 'json',
defaultExtension: 'json',
},
'devextreme/events': {
main: 'index',
},
'es6-object-assign': {
main: './index.js',
defaultExtension: 'js',
},
},
packageConfigPaths: [
'npm:@devextreme/*/package.json',
'npm:@devextreme/runtime@3.0.12/inferno/package.json',
],
babelOptions: {
sourceMaps: false,
stage0: true,
react: true,
},
};
System.config(window.config);
xxxxxxxxxx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
ReactDOM.render(<App />, document.getElementById('app'));
xxxxxxxxxx
export const employees = [
{
ID: 1,
FirstName: 'John',
LastName: 'Heart',
Position: 'CEO',
BirthDate: '1964/03/16',
HireDate: '1995/01/15',
Title: 'Mr.',
Address: '351 S Hill St.',
City: 'Los Angeles',
State: 'California',
Zipcode: 90013,
Email: 'jheart@dx-email.com',
Skype: 'jheartDXskype',
HomePhone: '(213) 555-9208',
DepartmentID: 6,
MobilePhone: '(213) 555-9392',
},
{
ID: 2,
FirstName: 'Olivia',
LastName: 'Peyton',
Position: 'Sales Assistant',
BirthDate: '1981/06/03',
HireDate: '2012/05/14',
Title: 'Mrs.',
Address: '807 W Paseo Del Mar',
City: 'Los Angeles',
State: 'California',
Zipcode: 90036,
Email: 'oliviap@dx-email.com',
Skype: 'oliviapDXskype',
HomePhone: '(310) 555-2728',
DepartmentID: 5,
MobilePhone: '(818) 555-2387',
},
{
ID: 3,
FirstName: 'Robert',
LastName: 'Reagan',
Position: 'CMO',
BirthDate: '1974/09/07',
HireDate: '2002/11/08',
Title: 'Mr.',
Address: '4 Westmoreland Pl.',
City: 'Bentonville',
State: 'Arkansas',
Zipcode: 91103,
Email: 'robertr@dx-email.com',
Skype: 'robertrDXskype',
HomePhone: '(818) 555-2438',
DepartmentID: 6,
MobilePhone: '(818) 555-2387',
},
{
ID: 4,
FirstName: 'Greta',
LastName: 'Sims',
Position: 'HR Manager',
BirthDate: '1977/11/22',
HireDate: '1998/04/23',
Title: 'Ms.',
Address: '1700 S Grandview Dr.',
State: 'Georgia',
City: 'Atlanta',
Zipcode: 91803,
Email: 'gretas@dx-email.com',
Skype: 'gretasDXskype',
HomePhone: '(818) 555-0976',
DepartmentID: 5,
MobilePhone: '(818) 555-6546',
},
{
ID: 5,
FirstName: 'Brett',
LastName: 'Wade',
Position: 'IT Manager',
BirthDate: '1968/12/01',
HireDate: '2009/03/06',
Title: 'Mr.',
Address: '1120 Old Mill Rd.',
State: 'Idaho',
City: 'Boise',
Zipcode: 91108,
Email: 'brettw@dx-email.com',
Skype: 'brettwDXskype',
HomePhone: '(626) 555-5985',
DepartmentID: 7,
MobilePhone: '(626) 555-0358',
},
{
ID: 6,
FirstName: 'Sandra',
LastName: 'Johnson',
Position: 'Controller',
BirthDate: '1974/11/15',
HireDate: '2005/05/11',
Title: 'Mrs.',
Address: '4600 N Virginia Rd.',
State: 'Utah',
City: 'Beaver',
Zipcode: 90807,
Email: 'sandraj@dx-email.com',
Skype: 'sandrajDXskype',
HomePhone: '(562) 555-8272',
DepartmentID: 5,
MobilePhone: '(562) 555-2082',
},
{
ID: 7,
FirstName: 'Kevin',
LastName: 'Carter',
Position: 'Shipping Manager',
BirthDate: '1978/01/09',
HireDate: '2009/08/11',
Title: 'Mr.',
Address: '424 N Main St.',
State: 'California',
City: 'San Diego',
Zipcode: 90012,
Email: 'kevinc@dx-email.com',
Skype: 'kevincDXskype',
HomePhone: '(213) 555-8038',
DepartmentID: 3,
MobilePhone: '(213) 555-2840',
},
{
ID: 8,
FirstName: 'Cynthia',
LastName: 'Stanwick',
Position: 'HR Assistant',
BirthDate: '1985/06/05',
HireDate: '2008/03/24',
Title: 'Ms.',
Address: '2211 Bonita Dr.',
City: 'Little Rock',
State: 'Arkansas',
Zipcode: 90265,
Email: 'cindys@dx-email.com',
Skype: 'cindysDXskype',
HomePhone: '(818) 555-6808',
DepartmentID: 4,
MobilePhone: '(818) 555-6655',
},
{
ID: 9,
FirstName: 'Kent',
LastName: 'Samuelson',
Position: 'Ombudsman',
BirthDate: '1972/09/11',
HireDate: '2009/04/22',
Title: 'Dr.',
Address: '12100 Mora Dr',
City: 'St. Louis',
State: 'Missouri',
Zipcode: 90272,
Email: 'kents@dx-email.com',
Skype: 'kentsDXskype',
HomePhone: '(562) 555-1328',
DepartmentID: 26,
MobilePhone: '(562) 555-9282',
},
{
ID: 10,
FirstName: 'Taylor',
LastName: 'Riley',
Position: 'Network Admin',
BirthDate: '1982/08/14',
HireDate: '2012/04/14',
Title: 'Mr.',
Address: '7776 Torreyson Dr',
City: 'San Jose',
State: 'California',
Zipcode: 90012,
Email: 'taylorr@dx-email.com',
Skype: 'taylorrDXskype',
HomePhone: '(310) 555-9712',
DepartmentID: 5,
MobilePhone: '(310) 555-7276',
},
];
xxxxxxxxxx
<html lang="en">
<head></head>
<body class="dx-viewport">
<div class="demo-container">
<div id="app"></div>
</div>
</body>
</html>
xxxxxxxxxx
#employees {
max-height: 440px;
}
.options {
padding: 20px;
margin-top: 20px;
background-color: rgba(191, 191, 191, 0.15);
}
.caption {
font-size: 18px;
font-weight: 500;
}
.option {
margin-top: 10px;
}
.option > span {
margin-right: 10px;
}
.option > .dx-selectbox {
display: inline-block;
vertical-align: middle;
}
.selectbox-container {
display: flex;
}
.checkboxes-container {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
margin-top: 15px;
}
.checkboxes-container > .option {
margin: 10px 30px 10px 0;
width: 200px;
}
To display the column chooser, click the appropriate toolbar button above the DataGrid. You can specify the column chooser's position via the columnChooser.position property. The manner in which users can display/hide columns depends on columnChooser.mode:
-
"dragAndDrop"
Users can drag and drop column headers to and from the column chooser. -
"select"
Users can select and deselect check boxes with column names.
In "select" mode, you can choose whether parent element selection affects child/nested elements. Use the selection.recursive property for this purpose.
If the column chooser contains multiple hidden columns, you can enable the DevExtreme Grid’s column search UI. Assign true to the search.enabled property for this purpose.
In this demo, use the check boxes below the DataGrid to toggle search and selection features.
To hide a column in code, set the columns[].visible property to false.