import React, { useCallback, useState } from 'react';
import ODataStore from 'devextreme/data/odata/store';
import { Autocomplete, AutocompleteTypes } from 'devextreme-react/autocomplete';
import CustomStore from 'devextreme/data/custom_store';
import 'whatwg-fetch';
import { names, surnames, positions } from './data.ts';
function isNotEmpty(value: string) {
return value !== undefined && value !== null && value !== '';
}
const positionLabel = { 'aria-label': 'Position' };
const position = positions[0];
const states = new ODataStore({
version: 2,
url: 'https://js.devexpress.com/Demos/DevAV/odata/States?$select=Sate_ID,State_Long,State_Short',
key: 'Sate_ID',
keyType: 'Int32',
});
const clientsStore = new CustomStore({
key: 'Value',
useDefaultSearch: true,
load: (loadOptions) => {
let params = '?';
['skip', 'take', 'filter'].forEach((option) => {
if (option in loadOptions && isNotEmpty(loadOptions[option])) {
params += `${option}=${JSON.stringify(loadOptions[option])}&`;
}
});
params = params.slice(0, -1);
return fetch(`https://js.devexpress.com/Demos/Mvc/api/DataGridWebApi/CustomersLookup${params}`)
.then((response) => response.json())
.then((data) => ({
data: data.data,
}))
.catch(() => {
throw new Error('Data Loading Error');
});
},
});
const renderState = (data) => (
<span>
{data.State_Long} ({data.State_Short})
</span>
);
function App() {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [state, setState] = useState('');
const [currentClient, setCurrentClient] = useState('');
const handleFirstNameChange = useCallback((e: AutocompleteTypes.ValueChangedEvent) => {
setFirstName(e.value);
}, []);
const handleLastNameChange = useCallback((e: AutocompleteTypes.ValueChangedEvent) => {
setLastName(e.value);
}, []);
const handleStateChange = useCallback((e: AutocompleteTypes.ValueChangedEvent) => {
setState(e.value);
}, []);
const handleCurrentClientChange = useCallback((e: AutocompleteTypes.ValueChangedEvent) => {
setCurrentClient(e.value);
}, []);
let fullInfo = '';
fullInfo += `${firstName || ''} ${lastName || ''}`.trim();
fullInfo += fullInfo && position ? `, ${position}` : position || '';
fullInfo += fullInfo && state ? `, ${state}` : state || '';
fullInfo += fullInfo && currentClient ? `, ${currentClient}` : currentClient || '';
return (
<div className="form">
<div className="dx-fieldset">
<div className="dx-fieldset-header">Default Mode</div>
<div className="dx-field">
<div className="dx-field-label">First Name</div>
<div className="dx-field-value">
<Autocomplete
dataSource={names}
value={firstName}
onValueChanged={handleFirstNameChange}
placeholder="Type first name..."
/>
</div>
</div>
</div>
<div className="dx-fieldset">
<div className="dx-fieldset-header">With Clear Button</div>
<div className="dx-field">
<div className="dx-field-label">Last Name</div>
<div className="dx-field-value">
<Autocomplete
dataSource={surnames}
value={lastName}
onValueChanged={handleLastNameChange}
showClearButton={true}
placeholder="Type last name..."
/>
</div>
</div>
</div>
<div className="dx-fieldset">
<div className="dx-fieldset-header">Disabled</div>
<div className="dx-field">
<div className="dx-field-label">Position</div>
<div className="dx-field-value">
<Autocomplete
dataSource={positions}
value={position}
disabled={true}
inputAttr={positionLabel}
/>
</div>
</div>
</div>
<div className="dx-fieldset">
<div className="dx-fieldset-header">Custom Item Template and Data Source Usage</div>
<div className="dx-field">
<div className="dx-field-label">State</div>
<div className="dx-field-value">
<Autocomplete
dataSource={states}
value={state}
valueExpr="State_Long"
onValueChanged={handleStateChange}
placeholder="Type state name..."
itemRender={renderState}
/>
</div>
</div>
</div>
<div className="dx-fieldset">
<div className="dx-fieldset-header">Custom Store and Search Options</div>
<div className="dx-field">
<div className="dx-field-label">Current Client</div>
<div className="dx-field-value">
<Autocomplete
dataSource={clientsStore}
value={currentClient}
valueExpr="Text"
onValueChanged={handleCurrentClientChange}
minSearchLength={2}
searchTimeout={500}
placeholder="Type client name..."
/>
</div>
</div>
</div>
<div className="dx-fieldset">
<div className="dx-fieldset-header">Event Handling</div>
<div className="employees-data">
Employee data: <span>{fullInfo}</span>
</div>
</div>
</div>
);
}
export default App;
import React, { useCallback, useState } from 'react';
import ODataStore from 'devextreme/data/odata/store';
import { Autocomplete } from 'devextreme-react/autocomplete';
import CustomStore from 'devextreme/data/custom_store';
import 'whatwg-fetch';
import { names, surnames, positions } from './data.js';
function isNotEmpty(value) {
return value !== undefined && value !== null && value !== '';
}
const positionLabel = { 'aria-label': 'Position' };
const position = positions[0];
const states = new ODataStore({
version: 2,
url: 'https://js.devexpress.com/Demos/DevAV/odata/States?$select=Sate_ID,State_Long,State_Short',
key: 'Sate_ID',
keyType: 'Int32',
});
const clientsStore = new CustomStore({
key: 'Value',
useDefaultSearch: true,
load: (loadOptions) => {
let params = '?';
['skip', 'take', 'filter'].forEach((option) => {
if (option in loadOptions && isNotEmpty(loadOptions[option])) {
params += `${option}=${JSON.stringify(loadOptions[option])}&`;
}
});
params = params.slice(0, -1);
return fetch(`https://js.devexpress.com/Demos/Mvc/api/DataGridWebApi/CustomersLookup${params}`)
.then((response) => response.json())
.then((data) => ({
data: data.data,
}))
.catch(() => {
throw new Error('Data Loading Error');
});
},
});
const renderState = (data) => (
<span>
{data.State_Long} ({data.State_Short})
</span>
);
function App() {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [state, setState] = useState('');
const [currentClient, setCurrentClient] = useState('');
const handleFirstNameChange = useCallback((e) => {
setFirstName(e.value);
}, []);
const handleLastNameChange = useCallback((e) => {
setLastName(e.value);
}, []);
const handleStateChange = useCallback((e) => {
setState(e.value);
}, []);
const handleCurrentClientChange = useCallback((e) => {
setCurrentClient(e.value);
}, []);
let fullInfo = '';
fullInfo += `${firstName || ''} ${lastName || ''}`.trim();
fullInfo += fullInfo && position ? `, ${position}` : position || '';
fullInfo += fullInfo && state ? `, ${state}` : state || '';
fullInfo += fullInfo && currentClient ? `, ${currentClient}` : currentClient || '';
return (
<div className="form">
<div className="dx-fieldset">
<div className="dx-fieldset-header">Default Mode</div>
<div className="dx-field">
<div className="dx-field-label">First Name</div>
<div className="dx-field-value">
<Autocomplete
dataSource={names}
value={firstName}
onValueChanged={handleFirstNameChange}
placeholder="Type first name..."
/>
</div>
</div>
</div>
<div className="dx-fieldset">
<div className="dx-fieldset-header">With Clear Button</div>
<div className="dx-field">
<div className="dx-field-label">Last Name</div>
<div className="dx-field-value">
<Autocomplete
dataSource={surnames}
value={lastName}
onValueChanged={handleLastNameChange}
showClearButton={true}
placeholder="Type last name..."
/>
</div>
</div>
</div>
<div className="dx-fieldset">
<div className="dx-fieldset-header">Disabled</div>
<div className="dx-field">
<div className="dx-field-label">Position</div>
<div className="dx-field-value">
<Autocomplete
dataSource={positions}
value={position}
disabled={true}
inputAttr={positionLabel}
/>
</div>
</div>
</div>
<div className="dx-fieldset">
<div className="dx-fieldset-header">Custom Item Template and Data Source Usage</div>
<div className="dx-field">
<div className="dx-field-label">State</div>
<div className="dx-field-value">
<Autocomplete
dataSource={states}
value={state}
valueExpr="State_Long"
onValueChanged={handleStateChange}
placeholder="Type state name..."
itemRender={renderState}
/>
</div>
</div>
</div>
<div className="dx-fieldset">
<div className="dx-fieldset-header">Custom Store and Search Options</div>
<div className="dx-field">
<div className="dx-field-label">Current Client</div>
<div className="dx-field-value">
<Autocomplete
dataSource={clientsStore}
value={currentClient}
valueExpr="Text"
onValueChanged={handleCurrentClientChange}
minSearchLength={2}
searchTimeout={500}
placeholder="Type client name..."
/>
</div>
</div>
</div>
<div className="dx-fieldset">
<div className="dx-fieldset-header">Event Handling</div>
<div className="employees-data">
Employee data: <span>{fullInfo}</span>
</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 names = ['James', 'John', 'Robert', 'Michael', 'William', 'David', 'Richard', 'Charles', 'Joseph', 'Thomas', 'Christopher', 'Daniel', 'Paul', 'Mark', 'Donald', 'George', 'Kenneth', 'Steven', 'Edward', 'Brian', 'Ronald', 'Anthony', 'Kevin', 'Jason', 'Jeff', 'Mary', 'Patricia', 'Linda', 'Barbara', 'Elizabeth', 'Jennifer', 'Maria', 'Susan', 'Margaret', 'Dorothy', 'Lisa', 'Nancy', 'Karen', 'Betty', 'Helen', 'Sandra', 'Donna', 'Carol', 'Ruth', 'Sharon', 'Michelle', 'Laura', 'Sarah', 'Kimberly', 'Deborah'];
export const surnames = ['Anderson', 'Smith', 'Johnson', 'Williams', 'Jones', 'Brown', 'Davis', 'Miller', 'Wilson', 'Moore', 'Taylor', 'Thomas', 'Jackson', 'White', 'Harris', 'Martin', 'Thompson', 'Garcia', 'Martinez', 'Robinson', 'Clark', 'Rodriguez', 'Lewis', 'Lee',
'Walker', 'Hall', 'Allen', 'Young', 'Hernandez', 'King', 'Wright', 'Lopez', 'Hill', 'Scott', 'Green', 'Adams', 'Baker', 'Gonzalez', 'Nelson', 'Carter', 'Mitchell', 'Perez', 'Roberts', 'Turner', 'Phillips', 'Campbell',
'Parker', 'Evans', 'Edwards', 'Collins',
];
export const positions = ['CEO', 'COO', 'CTO', 'CMO', 'HR Manager', 'IT Manager', 'Controller', 'Sales Manager', 'Support Manager'];
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',
'whatwg-fetch': 'npm:whatwg-fetch@2.0.4/fetch.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 names = [
'James',
'John',
'Robert',
'Michael',
'William',
'David',
'Richard',
'Charles',
'Joseph',
'Thomas',
'Christopher',
'Daniel',
'Paul',
'Mark',
'Donald',
'George',
'Kenneth',
'Steven',
'Edward',
'Brian',
'Ronald',
'Anthony',
'Kevin',
'Jason',
'Jeff',
'Mary',
'Patricia',
'Linda',
'Barbara',
'Elizabeth',
'Jennifer',
'Maria',
'Susan',
'Margaret',
'Dorothy',
'Lisa',
'Nancy',
'Karen',
'Betty',
'Helen',
'Sandra',
'Donna',
'Carol',
'Ruth',
'Sharon',
'Michelle',
'Laura',
'Sarah',
'Kimberly',
'Deborah',
];
export const surnames = [
'Anderson',
'Smith',
'Johnson',
'Williams',
'Jones',
'Brown',
'Davis',
'Miller',
'Wilson',
'Moore',
'Taylor',
'Thomas',
'Jackson',
'White',
'Harris',
'Martin',
'Thompson',
'Garcia',
'Martinez',
'Robinson',
'Clark',
'Rodriguez',
'Lewis',
'Lee',
'Walker',
'Hall',
'Allen',
'Young',
'Hernandez',
'King',
'Wright',
'Lopez',
'Hill',
'Scott',
'Green',
'Adams',
'Baker',
'Gonzalez',
'Nelson',
'Carter',
'Mitchell',
'Perez',
'Roberts',
'Turner',
'Phillips',
'Campbell',
'Parker',
'Evans',
'Edwards',
'Collins',
];
export const positions = [
'CEO',
'COO',
'CTO',
'CMO',
'HR Manager',
'IT Manager',
'Controller',
'Sales Manager',
'Support Manager',
];
<!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>
.employees-data {
padding-top: 16px;
padding-bottom: 10px;
}