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 Lookup - Basics

The Lookup component allows users to search through its drop-down list and select a single item. The drop-down list can be grouped by category.

DevExtreme Accessibility Compliance
DevExtreme component libraries meet a variety of WCAG and Section 508 compliance standards. To assess this demo’s accessibility level, click the Run AXE® Validation button to launch the AXE® web accessibility evaluation tool.
All trademarks or registered trademarks are property of their respective owners. AXE® Terms of Use
The overall accessibility level of your application depends on the Lookup features used.
Backend API
import React from 'react'; import { Lookup, DropDownOptions } from 'devextreme-react/lookup'; import DataSource from 'devextreme/data/data_source'; import ArrayStore from 'devextreme/data/array_store'; import { employeesList, employeesTasks } from './data.ts'; const simpleLookupLabel = { 'aria-label': 'Simple lookup' }; const groupedLookupLabel = { 'aria-label': 'Grouped lookup' }; const groupedData = new DataSource({ store: new ArrayStore({ data: employeesTasks, key: 'ID' }), group: 'Assigned', }); const App = () => ( <div> <div className="dx-fieldset"> <div className="dx-fieldset-header">Simple lookup</div> <div className="dx-field"> <Lookup items={employeesList} defaultValue={employeesList[0]} inputAttr={simpleLookupLabel} > <DropDownOptions showTitle={false} /> </Lookup> </div> </div> <div className="dx-fieldset"> <div className="dx-fieldset-header">Grouped lookup</div> <div className="dx-field"> <Lookup dataSource={groupedData} grouped={true} displayExpr="Subject" inputAttr={groupedLookupLabel} > <DropDownOptions hideOnOutsideClick={true} showTitle={false} /> </Lookup> </div> </div> </div> ); export default App;
import React from 'react'; import { Lookup, DropDownOptions } from 'devextreme-react/lookup'; import DataSource from 'devextreme/data/data_source'; import ArrayStore from 'devextreme/data/array_store'; import { employeesList, employeesTasks } from './data.js'; const simpleLookupLabel = { 'aria-label': 'Simple lookup' }; const groupedLookupLabel = { 'aria-label': 'Grouped lookup' }; const groupedData = new DataSource({ store: new ArrayStore({ data: employeesTasks, key: 'ID', }), group: 'Assigned', }); const App = () => ( <div> <div className="dx-fieldset"> <div className="dx-fieldset-header">Simple lookup</div> <div className="dx-field"> <Lookup items={employeesList} defaultValue={employeesList[0]} inputAttr={simpleLookupLabel} > <DropDownOptions showTitle={false} /> </Lookup> </div> </div> <div className="dx-fieldset"> <div className="dx-fieldset-header">Grouped lookup</div> <div className="dx-field"> <Lookup dataSource={groupedData} grouped={true} displayExpr="Subject" inputAttr={groupedLookupLabel} > <DropDownOptions hideOnOutsideClick={true} showTitle={false} /> </Lookup> </div> </div> </div> ); export default App;
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.tsx'; ReactDOM.render( <App />, document.getElementById('app'), );
export const employeesList = ['John Heart', 'Samantha Bright', 'Arthur Miller', 'Robert Reagan', 'Greta Sims', 'Brett Wade', 'Sandra Johnson', 'Ed Holmes', 'Barb Banks', 'Kevin Carter', 'Cindy Stanwick', 'Sammy Hill', 'Davey Jones', 'Victor Norris', 'Mary Stern', 'Robin Cosworth', 'Kelly Rodriguez', 'James Anderson', 'Antony Remmen', 'Olivia Peyton', 'Taylor Riley', 'Amelia Harper', 'Wally Hobbs', 'Brad Jameson', 'Karen Goodson', 'Marcus Orbison', 'Sandy Bright', 'Morgan Kennedy', 'Violet Bailey', 'Ken Samuelson', 'Nat Maguiree', 'Bart Arnaz', 'Leah Simpson', 'Arnie Schwartz', 'Billy Zimmer', 'Samantha Piper', 'Maggie Boxter', 'Terry Bradley', 'Gabe Jones', 'Lucy Ball', 'Jim Packard', 'Hannah Brookly', 'Harv Mudd', 'Clark Morgan', 'Todd Hoffman', 'Jackie Garmin', 'Lincoln Bartlett', 'Brad Farkus', 'Jenny Hobbs', 'Dallas Lou', 'Stu Pizaro']; export const employeesTasks = [{ ID: 1, Assigned: 'Mr. John Heart', Subject: 'Choose between PPO and HMO Health Plan', }, { ID: 2, Assigned: 'Mr. John Heart', Subject: 'Google AdWords Strategy', }, { ID: 3, Assigned: 'Mr. John Heart', Subject: 'New Brochures', }, { ID: 4, Assigned: 'Mr. John Heart', Subject: 'Update NDA Agreement', }, { ID: 5, Assigned: 'Mr. John Heart', Subject: 'Review Product Recall Report by Engineering Team', }, { ID: 6, Assigned: 'Mrs. Olivia Peyton', Subject: 'Update Personnel Files', }, { ID: 7, Assigned: 'Mrs. Olivia Peyton', Subject: 'Review Health Insurance Options Under the Affordable Care Act', }, { ID: 8, Assigned: 'Mrs. Olivia Peyton', Subject: 'Non-Compete Agreements', }, { ID: 9, Assigned: 'Mrs. Olivia Peyton', Subject: 'Give Final Approval for Refunds', }, { ID: 10, Assigned: 'Mr. Robert Reagan', Subject: 'Deliver R&D Plans for 2013', }, { ID: 11, Assigned: 'Mr. Robert Reagan', Subject: 'Decide on Mobile Devices to Use in the Field', }, { ID: 12, Assigned: 'Mr. Robert Reagan', Subject: 'Try New Touch-Enabled WinForms Apps', }, { ID: 13, Assigned: 'Mr. Robert Reagan', Subject: 'Approval on Converting to New HDMI Specification', }, { ID: 14, Assigned: 'Ms. Greta Sims', Subject: 'Approve Hiring of John Jeffers', }, { ID: 15, Assigned: 'Ms. Greta Sims', Subject: 'Update Employee Files with New NDA', }, { ID: 16, Assigned: 'Ms. Greta Sims', Subject: 'Provide New Health Insurance Docs', }];
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'));
export const employeesList = [ 'John Heart', 'Samantha Bright', 'Arthur Miller', 'Robert Reagan', 'Greta Sims', 'Brett Wade', 'Sandra Johnson', 'Ed Holmes', 'Barb Banks', 'Kevin Carter', 'Cindy Stanwick', 'Sammy Hill', 'Davey Jones', 'Victor Norris', 'Mary Stern', 'Robin Cosworth', 'Kelly Rodriguez', 'James Anderson', 'Antony Remmen', 'Olivia Peyton', 'Taylor Riley', 'Amelia Harper', 'Wally Hobbs', 'Brad Jameson', 'Karen Goodson', 'Marcus Orbison', 'Sandy Bright', 'Morgan Kennedy', 'Violet Bailey', 'Ken Samuelson', 'Nat Maguiree', 'Bart Arnaz', 'Leah Simpson', 'Arnie Schwartz', 'Billy Zimmer', 'Samantha Piper', 'Maggie Boxter', 'Terry Bradley', 'Gabe Jones', 'Lucy Ball', 'Jim Packard', 'Hannah Brookly', 'Harv Mudd', 'Clark Morgan', 'Todd Hoffman', 'Jackie Garmin', 'Lincoln Bartlett', 'Brad Farkus', 'Jenny Hobbs', 'Dallas Lou', 'Stu Pizaro', ]; export const employeesTasks = [ { ID: 1, Assigned: 'Mr. John Heart', Subject: 'Choose between PPO and HMO Health Plan', }, { ID: 2, Assigned: 'Mr. John Heart', Subject: 'Google AdWords Strategy', }, { ID: 3, Assigned: 'Mr. John Heart', Subject: 'New Brochures', }, { ID: 4, Assigned: 'Mr. John Heart', Subject: 'Update NDA Agreement', }, { ID: 5, Assigned: 'Mr. John Heart', Subject: 'Review Product Recall Report by Engineering Team', }, { ID: 6, Assigned: 'Mrs. Olivia Peyton', Subject: 'Update Personnel Files', }, { ID: 7, Assigned: 'Mrs. Olivia Peyton', Subject: 'Review Health Insurance Options Under the Affordable Care Act', }, { ID: 8, Assigned: 'Mrs. Olivia Peyton', Subject: 'Non-Compete Agreements', }, { ID: 9, Assigned: 'Mrs. Olivia Peyton', Subject: 'Give Final Approval for Refunds', }, { ID: 10, Assigned: 'Mr. Robert Reagan', Subject: 'Deliver R&D Plans for 2013', }, { ID: 11, Assigned: 'Mr. Robert Reagan', Subject: 'Decide on Mobile Devices to Use in the Field', }, { ID: 12, Assigned: 'Mr. Robert Reagan', Subject: 'Try New Touch-Enabled WinForms Apps', }, { ID: 13, Assigned: 'Mr. Robert Reagan', Subject: 'Approval on Converting to New HDMI Specification', }, { ID: 14, Assigned: 'Ms. Greta Sims', Subject: 'Approve Hiring of John Jeffers', }, { ID: 15, Assigned: 'Ms. Greta Sims', Subject: 'Update Employee Files with New NDA', }, { ID: 16, Assigned: 'Ms. Greta Sims', Subject: 'Provide New Health Insurance Docs', }, ];
<!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>
.dx-theme-generic .dx-fieldset, .dx-theme-material .dx-fieldset { width: 40%; float: left; } .dx-field > .dx-lookup { flex: 1; }

Bind the Component to Data

To bind the component to data, use one of these properties:

  • items[]
    Accepts a local data array (see the Simple Lookup code below).

  • dataSource
    Accepts a local data array or a DataSource object. This object works with local and remote arrays and allows you to shape data. In this demo, a DataSource instance is configured to group a local array of objects (see the Grouped Lookup code below).

Both properties work with arrays of primitives or objects. If you use objects, specify the following properties:

  • valueExpr
    A data field that contains unique values used to identify items.

  • displayExpr
    A data field whose values should be displayed in the drop-down list.

When a user selects an item, the Lookup component saves the corresponding value from the valueExpr data field in the value property. You can also specify the value property in code to preselect an item as shown in the Simple Lookup use case.

Group Data

You can group data items in the drop-down list.

If the data source contains ungrouped data items, use the DataSource's group property to specify the data field to group by.

The Lookup component can also work with initially grouped data items. In this case, the data array should contain objects with the key and items fields:

let dataSource = [{
    key: "Group 1", // Group caption 
    items: [ // Items in Group 1
        { /* ... */ },
        { /* ... */ }
    ]
}, {
    key: "Group 2",
    items: [
        { /* ... */ },
        { /* ... */ }
    ]
}];

If data objects are grouped but use other field names, implement the DataSource's map function to create key and items field mappings.

NOTE

Only one-level grouping is supported.

Regardless of the data source structure, enable the grouped property.

Configure the Drop-Down List

The Lookup component uses the Popover component as a drop-down list. To customize the Popover, use the dropDownOptions property. It accepts an object with Popover properties. Alternatively, you can set the usePopover property to false to display lookup items in a pop-up window.