Skip to content

Commit 771ceb2

Browse files
DropDownBox: add Search in Embedded Components topic (#8854)
1 parent 9d31035 commit 771ceb2

4 files changed

Lines changed: 1808 additions & 146 deletions

File tree

concepts/05 UI Components/DropDownBox/15 Synchronize with the Embedded Element.md

Lines changed: 90 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
You should synchronize the DropDownBox UI component with an embedded element. The following instructions show how to do it when the embedded element is another DevExtreme UI component, but they are also applicable in other cases.
1+
To use DropDownBox with an embedded UI component, synchronize the two components' data and selection state. The steps below use an embedded DataGrid as an example. The same approach applies to other DevExtreme UI components.
22

33
1. **Specify data sources**
4-
The DropDownBox's and embedded UI component's data sources can be the same or different. If they are different, the UI component's key field should be present in the DropDownBox's data source.
4+
The DropDownBox and embedded UI component can have the same data source or different data sources. If the data sources are different, the UI component's key field must be present in the DropDownBox data source.
55

66
<!--JavaScript-->
77
// Different data sources, both have the ID field
@@ -16,8 +16,8 @@ The DropDownBox's and embedded UI component's data sources can be the same or di
1616
// ...
1717
];
1818

19-
1. **Specify which data field provides the DropDownBox's values and the embedded UI component's keys**
20-
Assign the field's name to the DropDownBox's [valueExpr](/api-reference/10%20UI%20Components/DataExpressionMixin/1%20Configuration/valueExpr.md '/Documentation/ApiReference/UI_Components/dxDropDownBox/Configuration/#valueExpr') property and to the [key](/api-reference/30%20Data%20Layer/Store/1%20Configuration/key.md '/Documentation/ApiReference/Data_Layer/ArrayStore/Configuration/#key') property of the embedded UI component's store. The following example shows an [ArrayStore](/api-reference/30%20Data%20Layer/ArrayStore '/Documentation/ApiReference/Data_Layer/ArrayStore/'):
19+
1. **Specify the shared key field**
20+
Assign the field's name to the DropDownBox's [valueExpr](/api-reference/10%20UI%20Components/DataExpressionMixin/1%20Configuration/valueExpr.md '/Documentation/ApiReference/UI_Components/dxDropDownBox/Configuration/#valueExpr') property and to the [key](/api-reference/30%20Data%20Layer/Store/1%20Configuration/key.md '/Documentation/ApiReference/Data_Layer/ArrayStore/Configuration/#key') property of the embedded UI component's store. The following example uses an [ArrayStore](/api-reference/30%20Data%20Layer/ArrayStore '/Documentation/ApiReference/Data_Layer/ArrayStore/'):
2121

2222
---
2323
##### jQuery
@@ -49,15 +49,23 @@ Assign the field's name to the DropDownBox's [valueExpr](/api-reference/10%20UI%
4949
valueExpr="ID"
5050
displayExpr="email"
5151
[dataSource]="dropDownBoxData">
52-
<dx-data-grid ...
52+
<dx-data-grid
5353
[dataSource]="gridDataSource">
5454
</dx-data-grid>
5555
</dx-drop-down-box>
5656

5757
<!--TypeScript-->
58-
import { DxDropDownBoxModule, DxDataGridModule } from "devextreme-angular";
58+
import { Component } from "@angular/core";
59+
import { DxDropDownBoxComponent } from "devextreme-angular/ui/drop-down-box";
60+
import { DxDataGridComponent } from "devextreme-angular/ui/data-grid";
5961
import ArrayStore from "devextreme/data/array_store";
60-
// ...
62+
63+
@Component({
64+
selector: "app-root",
65+
templateUrl: "./app.component.html",
66+
standalone: true,
67+
imports: [DxDropDownBoxComponent, DxDataGridComponent]
68+
})
6169
export class AppComponent {
6270
widgetData: any;
6371
dropDownBoxData: any;
@@ -70,14 +78,6 @@ Assign the field's name to the DropDownBox's [valueExpr](/api-reference/10%20UI%
7078
});
7179
}
7280
}
73-
@NgModule({
74-
imports: [
75-
// ...
76-
DxDropDownBoxModule,
77-
DxDataGridModule
78-
],
79-
// ...
80-
})
8181

8282
##### Vue
8383

@@ -88,70 +88,52 @@ Assign the field's name to the DropDownBox's [valueExpr](/api-reference/10%20UI%
8888
value-expr="ID"
8989
display-expr="email"
9090
:data-source="dropDownBoxData">
91-
<DxDataGrid ...
92-
:data-source="gridDataSource">
93-
</DxDataGrid>
91+
<DxDataGrid :data-source="gridDataSource" />
9492
</DxDropDownBox>
9593
</div>
9694
</template>
9795

98-
<script>
96+
<script setup lang="ts">
9997
import 'devextreme/dist/css/dx.fluent.blue.light.css';
10098

101-
import DxDropDownBox from "devextreme-vue/drop-down-box";
102-
import DxDataGrid, DxSelection from "devextreme-vue/data-grid";
103-
import ArrayStore from "devextreme/data/array_store";
99+
import DxDropDownBox from 'devextreme-vue/drop-down-box';
100+
import { DxDataGrid } from 'devextreme-vue/data-grid';
101+
import ArrayStore from 'devextreme/data/array_store';
104102

105-
export default {
106-
components: {
107-
DxDropDownBox,
108-
DxDataGrid
109-
},
110-
data() {
111-
return {
112-
dropDownBoxData: dropDownBoxData,
113-
gridDataSource: new ArrayStore({
114-
data: widgetData,
115-
key: "ID"
116-
}),
117-
isDropDownBoxOpened: false
118-
}
119-
}
120-
}
103+
const dropDownBoxData = [/* ... */];
104+
const gridDataSource = new ArrayStore({
105+
data: widgetData,
106+
key: 'ID',
107+
});
121108
</script>
122109

123110
##### React
124111

112+
<!-- tab: App.tsx -->
125113
import React from 'react';
126114
import 'devextreme/dist/css/dx.fluent.blue.light.css';
127115

128116
import { DropDownBox } from 'devextreme-react/drop-down-box';
129-
import { DataGrid, Selection } from "devextreme-react/data-grid";
130-
import ArrayStore from "devextreme/data/array_store";
131-
132-
const dropDownBoxData = {/* ... */};
117+
import { DataGrid } from 'devextreme-react/data-grid';
118+
import ArrayStore from 'devextreme/data/array_store';
119+
120+
const dropDownBoxData = [/* ... */];
133121
const gridDataSource = new ArrayStore({
134122
data: widgetData,
135-
key: "ID"
123+
key: 'ID',
136124
});
137125

138-
class App extends React.Component {
139-
render() {
140-
return (
141-
<DropDownBox
142-
dataSource={dropDownBoxData}
143-
valueExpr="ID"
144-
displayExpr="email">
145-
<DataGrid ...
146-
dataSource={gridDataSource}
147-
/>
148-
</DropDownBox>
149-
);
150-
}
126+
export default function App() {
127+
return (
128+
<DropDownBox
129+
dataSource={dropDownBoxData}
130+
valueExpr="ID"
131+
displayExpr="email">
132+
<DataGrid dataSource={gridDataSource} />
133+
</DropDownBox>
134+
);
151135
}
152136

153-
export default App;
154-
155137
##### ASP.NET MVC Controls
156138

157139
<!--Razor C#-->
@@ -175,9 +157,9 @@ Assign the field's name to the DropDownBox's [valueExpr](/api-reference/10%20UI%
175157
---
176158

177159
1. **Synchronize the DropDownBox's value and the embedded UI component's selection**
178-
This step's implementation depends on the embedded UI component's API and the library/framework you use. If the library/framework supports two-way binding, you can bind the DropDownBox's [value](/api-reference/10%20UI%20Components/dxDropDownBox/1%20Configuration/value.md '/Documentation/ApiReference/UI_Components/dxDropDownBox/Configuration/#value') and the UI component's **selectedRowKeys**/**selectedItemKeys** to the same variable. If not, handle events as follows:
160+
The synchronization implementation depends on the embedded UI component's API and the library/framework you use. If the library/framework supports two-way binding, you can bind the DropDownBox's [value](/api-reference/10%20UI%20Components/dxDropDownBox/1%20Configuration/value.md '/Documentation/ApiReference/UI_Components/dxDropDownBox/Configuration/#value') and the UI component's **selectedRowKeys**/**selectedItemKeys** to the same variable. If not, handle events as follows:
179161
1. **Set the initial selection in the embedded UI component**
180-
Implement the UI component's **onContentReady** handler to select data items according to the DropDownBox's initial value. In some UI components, you can set the **selectedRowKeys** or **selectedItemKeys** option instead.
162+
Implement the UI component's **onContentReady** handler to select data items according to the DropDownBox's initial value. In some UI components, you can set **selectedRowKeys** or **selectedItemKeys** directly instead of using **onContentReady**.
181163
1. **Update the selection**
182164
Implement the DropDownBox's [onValueChanged](/api-reference/10%20UI%20Components/dxDropDownBox/1%20Configuration/onValueChanged.md '/Documentation/ApiReference/UI_Components/dxDropDownBox/Configuration/#onValueChanged') handler to update the selection when the DropDownBox's value changes.
183165
1. **Update the DropDownBox's value**
@@ -191,7 +173,7 @@ This step's implementation depends on the embedded UI component's API and the li
191173
<!--JavaScript-->
192174
$(function() {
193175
// ...
194-
const dataGridInstance;
176+
let dataGridInstance;
195177
$("#dropDownBox").dxDropDownBox({
196178
// ...
197179
value: [1],
@@ -217,20 +199,26 @@ This step's implementation depends on the embedded UI component's API and the li
217199
##### Angular
218200

219201
<!--HTML-->
220-
<dx-drop-down-box ...
202+
<dx-drop-down-box
221203
[(value)]="dropDownBoxValue">
222-
<dx-data-grid ...
223-
[selection]="{ mode: 'multiple' }"
204+
<dx-data-grid
224205
[(selectedRowKeys)]="dropDownBoxValue">
206+
<dxo-data-grid-selection mode="multiple"></dxo-data-grid-selection>
225207
</dx-data-grid>
226208
</dx-drop-down-box>
227209

228210
<!--TypeScript-->
229-
import { DxDropDownBoxModule, DxDataGridModule } from "devextreme-angular";
230-
import ArrayStore from "devextreme/data/array_store";
231-
// ...
211+
import { Component } from "@angular/core";
212+
import { DxDropDownBoxComponent } from "devextreme-angular/ui/drop-down-box";
213+
import { DxDataGridComponent, DxoDataGridSelectionComponent } from "devextreme-angular/ui/data-grid";
214+
215+
@Component({
216+
selector: "app-root",
217+
templateUrl: "./app.component.html",
218+
standalone: true,
219+
imports: [DxDropDownBoxComponent, DxDataGridComponent, DxoDataGridSelectionComponent]
220+
})
232221
export class AppComponent {
233-
// ...
234222
_dropDownBoxValue: number[] = [1];
235223
get dropDownBoxValue(): number[] {
236224
return this._dropDownBoxValue;
@@ -239,14 +227,6 @@ This step's implementation depends on the embedded UI component's API and the li
239227
this._dropDownBoxValue = value || [];
240228
}
241229
}
242-
@NgModule({
243-
imports: [
244-
// ...
245-
DxDropDownBoxModule,
246-
DxDataGridModule
247-
],
248-
// ...
249-
})
250230

251231
##### Vue
252232

@@ -263,87 +243,51 @@ This step's implementation depends on the embedded UI component's API and the li
263243
</div>
264244
</template>
265245

266-
<script>
246+
<script setup lang="ts">
267247
import 'devextreme/dist/css/dx.fluent.blue.light.css';
268248

269-
import DxDropDownBox from "devextreme-vue/drop-down-box";
270-
import { DxDataGrid, DxSelection } from "devextreme-vue/data-grid";
271-
import ArrayStore from "devextreme/data/array_store";
249+
import DxDropDownBox from 'devextreme-vue/drop-down-box';
250+
import { DxDataGrid, DxSelection } from 'devextreme-vue/data-grid';
251+
import { ref, computed } from 'vue';
272252

273-
export default {
274-
components: {
275-
DxDropDownBox,
276-
DxDataGrid,
277-
DxSelection
278-
},
279-
data() {
280-
// ...
281-
return {
282-
// ...
283-
dropDownBox_values: [1]
284-
}
285-
},
286-
computed: {
287-
dropDownBoxValues: {
288-
get: function() {
289-
return this.dropDownBox_values;
290-
},
291-
set: function(value) {
292-
this.dropDownBox_values = value || [];
293-
}
294-
}
295-
}
296-
}
253+
const _dropDownBoxValues = ref<number[]>([1]);
254+
255+
const dropDownBoxValues = computed<number[]>({
256+
get: () => _dropDownBoxValues.value,
257+
set: (value) => { _dropDownBoxValues.value = value ?? []; },
258+
});
297259
</script>
298260

299261
##### React
300262

301-
import React from 'react';
263+
<!-- tab: App.tsx -->
264+
import React, { useState, useRef } from 'react';
302265
import 'devextreme/dist/css/dx.fluent.blue.light.css';
303266

304-
import { DropDownBox } from 'devextreme-react/drop-down-box';
305-
import { DataGrid, Selection } from "devextreme-react/data-grid";
306-
import ArrayStore from "devextreme/data/array_store";
307-
308-
class App extends React.Component {
309-
constructor(props) {
310-
super(props);
311-
312-
this.state = {
313-
dropDownBoxValues: [1]
314-
};
315-
316-
this.dropDownBoxRef = React.createRef();
317-
318-
this.changeDropDownBoxValue = this.changeDropDownBoxValue.bind(this);
319-
}
320-
321-
changeDropDownBoxValue(e) {
322-
const keys = e.selectedRowKeys;
323-
this.setState({
324-
dropDownBoxValues: keys
325-
});
326-
327-
this.dropDownBoxRef.current.instance().close();
328-
}
329-
330-
render() {
331-
return (
332-
<DropDownBox ...
333-
ref={this.dropDownBoxRef}
334-
value="this.state.dropDownBoxValues">
335-
<DataGrid ...
336-
selectedRowKeys={this.state.dropDownBoxValues}
337-
onSelectionChanged={this.changeDropDownBoxValue}>
338-
<Selection mode="multiple" />
339-
</DataGrid>
340-
</DropDownBox>
341-
);
342-
}
267+
import { DropDownBox, DropDownBoxRef } from 'devextreme-react/drop-down-box';
268+
import { DataGrid, Selection } from 'devextreme-react/data-grid';
269+
import type { SelectionChangedEvent } from 'devextreme/ui/data_grid';
270+
271+
export default function App() {
272+
const [dropDownBoxValues, setDropDownBoxValues] = useState<number[]>([1]);
273+
const dropDownBoxRef = useRef<DropDownBoxRef>(null);
274+
const changeDropDownBoxValue = (e: SelectionChangedEvent) => {
275+
setDropDownBoxValues(e.selectedRowKeys as number[]);
276+
dropDownBoxRef.current?.instance().close();
277+
};
278+
return (
279+
<DropDownBox
280+
ref={dropDownBoxRef}
281+
value={dropDownBoxValues}>
282+
<DataGrid
283+
selectedRowKeys={dropDownBoxValues}
284+
onSelectionChanged={changeDropDownBoxValue}>
285+
<Selection mode="multiple" />
286+
</DataGrid>
287+
</DropDownBox>
288+
);
343289
}
344290

345-
export default App;
346-
347291
##### ASP.NET MVC Controls
348292

349293
<!--Razor C#-->

0 commit comments

Comments
 (0)