DevExtreme v24.2 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.

React Pivot Grid - Integrated Field Chooser

The field chooser allows users to manage pivot grid fields. You can configure the field chooser integrated into the PivotGrid or use it as a standalone component. This example demonstrates the integrated field chooser. To open the field chooser window, click the icon in the top-left corner or right-click a row or column header and select Show Field Chooser from the context menu.

Backend API
import React, { useState } from 'react'; import PivotGridDataSource from 'devextreme/ui/pivot_grid/data_source'; import SelectBox from 'devextreme-react/select-box'; import PivotGrid, { FieldChooser, } from 'devextreme-react/pivot-grid'; const applyChangesModeLabel = { 'aria-label': 'Apply Changes Mode' }; const App = () => { const [applyChangesMode, setApplyChangesMode] = useState<'instantly' | 'onDemand'>('instantly'); return ( <React.Fragment> <PivotGrid dataSource={dataSource} allowSortingBySummary={true} allowFiltering={true} allowSorting={true} height={470} showBorders={true} > <FieldChooser enabled={true} allowSearch={true} applyChangesMode={applyChangesMode} /> </PivotGrid> <div className="options"> <div className="caption">Options</div> <div className="option"> <span>Apply Changes Mode:</span> <SelectBox items={applyChangesModes} width={180} inputAttr={applyChangesModeLabel} value={applyChangesMode} onValueChange={setApplyChangesMode}> </SelectBox> </div> </div> </React.Fragment> ); }; const dataSource = new PivotGridDataSource({ fields: [ { dataField: '[Product].[Category]', area: 'row' }, { dataField: '[Product].[Subcategory]', area: 'row', headerFilter: { search: { enabled: true, }, }, }, { dataField: '[Ship Date].[Calendar Year]', area: 'column' }, { dataField: '[Ship Date].[Month of Year]', area: 'column' }, { dataField: '[Measures].[Customer Count]', area: 'data' }, ], store: { type: 'xmla', url: 'https://demos.devexpress.com/Services/OLAP/msmdpump.dll', catalog: 'Adventure Works DW Standard Edition', cube: 'Adventure Works', }, }); const applyChangesModes = ['instantly', 'onDemand']; export default App;
import React, { useState } from 'react'; import PivotGridDataSource from 'devextreme/ui/pivot_grid/data_source'; import SelectBox from 'devextreme-react/select-box'; import PivotGrid, { FieldChooser } from 'devextreme-react/pivot-grid'; const applyChangesModeLabel = { 'aria-label': 'Apply Changes Mode' }; const App = () => { const [applyChangesMode, setApplyChangesMode] = useState('instantly'); return ( <React.Fragment> <PivotGrid dataSource={dataSource} allowSortingBySummary={true} allowFiltering={true} allowSorting={true} height={470} showBorders={true} > <FieldChooser enabled={true} allowSearch={true} applyChangesMode={applyChangesMode} /> </PivotGrid> <div className="options"> <div className="caption">Options</div> <div className="option"> <span>Apply Changes Mode:</span> <SelectBox items={applyChangesModes} width={180} inputAttr={applyChangesModeLabel} value={applyChangesMode} onValueChange={setApplyChangesMode} ></SelectBox> </div> </div> </React.Fragment> ); }; const dataSource = new PivotGridDataSource({ fields: [ { dataField: '[Product].[Category]', area: 'row' }, { dataField: '[Product].[Subcategory]', area: 'row', headerFilter: { search: { enabled: true, }, }, }, { dataField: '[Ship Date].[Calendar Year]', area: 'column' }, { dataField: '[Ship Date].[Month of Year]', area: 'column' }, { dataField: '[Measures].[Customer Count]', area: 'data' }, ], store: { type: 'xmla', url: 'https://demos.devexpress.com/Services/OLAP/msmdpump.dll', catalog: 'Adventure Works DW Standard Edition', cube: 'Adventure Works', }, }); const applyChangesModes = ['instantly', 'onDemand']; export default App;
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.tsx'; ReactDOM.render( <App />, document.getElementById('app'), );
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);
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.js'; ReactDOM.render(<App />, document.getElementById('app'));
<!DOCTYPE html> <html lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/24.2.3/css/dx.light.css" /> <link rel="stylesheet" type="text/css" href="styles.css" /> <script src="https://unpkg.com/core-js@2.6.12/client/shim.min.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script type="text/javascript" src="config.js"></script> <script type="text/javascript"> System.import("./index.tsx"); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"></div> </div> </body> </html>
.options { padding: 20px; background-color: rgba(191, 191, 191, 0.15); margin-top: 20px; } .caption { font-size: 18px; font-weight: 500; } .option { margin-top: 10px; } .dx-selectbox { margin-top: 5px; }

Enable the Integrated Field Chooser

The integrated field chooser is configured in the fieldChooser object. To enable the field chooser, set the object's enabled property to true. This setting adds the Field Chooser icon to the PivotGrid and the Show Field Chooser command to the context menu.

Organize Fields

The field chooser window displays five field sections:

  • Row Fields
  • Column Fields
  • Data Fields
  • Filter Fields
  • All Fields

You can use the fieldChooser.layout property to arrange the sections in different ways.

The All Fields section includes fields declared in the fields[] array and auto-generated fields as shown in this demo. If you want to hide the auto-generated fields, disable the dataSource.retrieveFields property. You can also hide any particular field if you disable its visible property.

You can enable hierarchical display in the All Fields section. Specify the same displayFolder for the fields that should be grouped together. In this demo, the hierarchy is built on the server.

Users can drag and drop fields between the sections. When users move a field to the Row, Column, Data, or Filter Fields section, the PivotGrid adds this field to the corresponding area. To do the same programmatically, specify the field's area property. If a field is intended to be moved to the Data Fields section only, enable the field's isMeasure property, and vice versa: disable the isMeasure property for fields that should never be in the Data Fields section. In this demo, these restrictions are specified on the server.

After a user finishes moving fields between sections, the changes can either be applied immediately or after the user clicks OK. Use the fieldChooser.applyChangesMode property to set the desired mode. In this demo, you can change this property at runtime.

Enable Search

Users can search in the All Fields section if you enable the fieldChooser.allowSearch property as shown in this demo. In addition, you can specify the searchTimeout property to delay the search.