Angular DropDownBox - Synchronize with the Embedded Element

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. Specify data sources
    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.

    JavaScript
    // Different data sources, both have the ID field
    const widgetData = [
        { ID: 1, fullName: "John Heart", position: "CEO"},
        { ID: 2, fullName: "Samantha Bright", position: "COO", headID: 1 },
        // ...
    ];
    const dropDownBoxData = [
        { ID: 1, email: "jheart@dx-email.com" },
        { ID: 2, email: "samanthab@dx-email.com" },
        // ...
    ];
  2. Specify which data field provides the DropDownBox's values and the embedded UI component's keys
    Assign the field's name to the DropDownBox's valueExpr property and to the key property of the embedded UI component's store. The following example shows an ArrayStore:

    jQuery
    JavaScript
    $(function() {
        // ...
        $("#dropDownBox").dxDropDownBox({ 
            dataSource: dropDownBoxData,
            valueExpr: "ID",
            displayExpr: "email",
            contentTemplate: function (e) {
                const $dataGrid = $("<div>").dxDataGrid({
                    dataSource: new DevExpress.data.ArrayStore({ 
                        key: "ID",
                        data: widgetData
                    }),
                    // ...
                });
                return $dataGrid;
            }
        });
    });
    Angular
    HTML
    TypeScript
    <dx-drop-down-box
        valueExpr="ID"
        displayExpr="email"
        [dataSource]="dropDownBoxData">
        <dx-data-grid ...
            [dataSource]="gridDataSource">
        </dx-data-grid>
    </dx-drop-down-box>
    import { DxDropDownBoxModule, DxDataGridModule } from "devextreme-angular";
    import ArrayStore from "devextreme/data/array_store";
    // ...
    export class AppComponent {
        widgetData: any;
        dropDownBoxData: any;
        gridDataSource: ArrayStore;
        constructor () {
            // ...
            this.gridDataSource = new ArrayStore({
                key: "ID",
                data: this.widgetData
            });
        }
    }
    @NgModule({
        imports: [
            // ...
            DxDropDownBoxModule,
            DxDataGridModule
        ],
        // ...
    })
    Vue
    App.vue
    <template>
        <div>
            <DxDropDownBox
                value-expr="ID"
                display-expr="email"
                :data-source="dropDownBoxData">
                <DxDataGrid ...
                    :data-source="gridDataSource">
                </DxDataGrid>
            </DxDropDownBox>
        </div>
    </template>
    
    <script>
    import 'devextreme/dist/css/dx.light.css';
    
    import DxDropDownBox from "devextreme-vue/drop-down-box";
    import DxDataGrid, DxSelection from "devextreme-vue/data-grid";
    import ArrayStore from "devextreme/data/array_store";
    
    export default {
        components: {
            DxDropDownBox,
            DxDataGrid
        },
        data() {
            return {
                dropDownBoxData: dropDownBoxData,
                gridDataSource: new ArrayStore({
                    data: widgetData,
                    key: "ID"
                }),
                isDropDownBoxOpened: false
            }
        }
    }
    </script>
    React
    import React from 'react';
    import 'devextreme/dist/css/dx.light.css';
    
    import { DropDownBox } from 'devextreme-react/drop-down-box';
    import { DataGrid, Selection } from "devextreme-react/data-grid";
    import ArrayStore from "devextreme/data/array_store";
    
    const dropDownBoxData = {/* ... */};
    const gridDataSource = new ArrayStore({
        data: widgetData,
        key: "ID"
    });
    
    class App extends React.Component {
        render() {
            return (
                <DropDownBox
                    dataSource={dropDownBoxData}
                    valueExpr="ID"
                    displayExpr="email">
                    <DataGrid ...
                        dataSource={gridDataSource}
                    />
                </DropDownBox>
            );
        }
    }
    
    export default App;
    ASP.NET MVC Controls
    Razor C#
    @(Html.DevExtreme().DropDownBox()
        .ID("dropDownBox")
        .DataSource(new JS("dropDownBoxData"))
        .ValueExpr("ID")
        .DisplayExpr("email")
        .ContentTemplate(new TemplateName("dataGrid"))
    )
    @using (Html.DevExtreme().NamedTemplate("dataGrid")) {
        @(Html.DevExtreme().DataGrid()
            .ID("dataGrid")
            .DataSource(ds => ds.Array()
                .Key("ID")
                .Data(new JS("widgetData"))
            )
        )
    }
  3. Synchronize the DropDownBox's value and the embedded UI component's selection
    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 and the UI component's selectedRowKeys/selectedItemKeys to the same variable. If not, handle events as described below.

    1. Set the initial selection in the embedded UI component
      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.
    2. Update the selection
      Implement the DropDownBox's onValueChanged handler to update the selection when the DropDownBox's value changes.
    3. Update the DropDownBox's value
      Implement the embedded UI component's onSelectionChanged handler to update the DropDownBox's value when the selection changes.
    jQuery
    JavaScript
    $(function() {
        // ...
        const dataGridInstance;
        $("#dropDownBox").dxDropDownBox({ 
            // ...
            value: [1],
            contentTemplate: function (e) {
                const value = e.component.option("value"),
                    $dataGrid = $("<div>").dxDataGrid({
                        // ...
                        selection: { mode: "multiple" },
                        selectedRowKeys: value,
                        onSelectionChanged: function (info) {
                            e.component.option("value", info.selectedRowKeys);
                        }
                    });
                dataGridInstance = $dataGrid.dxDataGrid("instance");
                return $dataGrid;
            },
            onValueChanged: function (e) {
                dataGridInstance.selectRows(e.value, false);
            }
        });
    });
    Angular
    HTML
    TypeScript
    <dx-drop-down-box ...
        [(value)]="dropDownBoxValue">
        <dx-data-grid ...
            [selection]="{ mode: 'multiple' }"
            [(selectedRowKeys)]="dropDownBoxValue">
        </dx-data-grid>
    </dx-drop-down-box>
    import { DxDropDownBoxModule, DxDataGridModule } from "devextreme-angular";
    import ArrayStore from "devextreme/data/array_store";
    // ...
    export class AppComponent {
        // ...
        _dropDownBoxValue: number[] = [1];
        get dropDownBoxValue(): number[] {
            return this._dropDownBoxValue;
        }
        set dropDownBoxValue(value: number[]) {
            this._dropDownBoxValue = value || [];
        }
    }
    @NgModule({
        imports: [
            // ...
            DxDropDownBoxModule,
            DxDataGridModule
        ],
        // ...
    })
    Vue
    App.vue
    <template>
        <div>
            <DxDropDownBox ...
                v-model:value="dropDownBoxValues">
                <DxDataGrid ...
                    v-model:selected-row-keys="dropDownBoxValues">
                    <DxSelection mode="multiple" />
                </DxDataGrid>
            </DxDropDownBox>
        </div>
    </template>
    
    <script>
    import 'devextreme/dist/css/dx.light.css';
    
    import DxDropDownBox from "devextreme-vue/drop-down-box";
    import { DxDataGrid, DxSelection } from "devextreme-vue/data-grid";
    import ArrayStore from "devextreme/data/array_store";
    
    export default {
        components: {
            DxDropDownBox,
            DxDataGrid,
            DxSelection
        },
        data() {
            // ...
            return {
                // ...
                dropDownBox_values: [1]
            }
        },
        computed: {
            dropDownBoxValues: {
                get: function() {
                    return this.dropDownBox_values;
                },
                set: function(value) {
                    this.dropDownBox_values = value || [];
                }
            }
        }
    }
    </script>
    React
    import React from 'react';
    import 'devextreme/dist/css/dx.light.css';
    
    import { DropDownBox } from 'devextreme-react/drop-down-box';
    import { DataGrid, Selection } from "devextreme-react/data-grid";
    import ArrayStore from "devextreme/data/array_store";
    
    class App extends React.Component {
        constructor(props) {
            super(props);
    
            this.state = {
                dropDownBoxValues: [1]
            };
    
            this.dropDownBoxRef = React.createRef();
    
            this.changeDropDownBoxValue = this.changeDropDownBoxValue.bind(this);
        }
    
        changeDropDownBoxValue(e) {
            const keys = e.selectedRowKeys;
            this.setState({
                dropDownBoxValues: keys
            });
    
            this.dropDownBoxRef.current.instance.close();
        }
    
        render() {
            return (
                <DropDownBox ...
                    ref={this.dropDownBoxRef}
                    value="this.state.dropDownBoxValues">
                    <DataGrid ...
                        selectedRowKeys={this.state.dropDownBoxValues}
                        onSelectionChanged={this.changeDropDownBoxValue}>
                        <Selection mode="multiple" />
                    </DataGrid>
                </DropDownBox>
            );
        }
    
    }
    
    export default App;
    ASP.NET MVC Controls
    Razor C#
    @(Html.DevExtreme().DropDownBox()
        // ...
        .Value(1)
        .ContentTemplate(new TemplateName("dataGrid"))
        .OnValueChanged("dropDownBox_valueChanged")
    )
    @using (Html.DevExtreme().NamedTemplate("dataGrid")) {
        @(Html.DevExtreme().DataGrid()
            // ...
            .Selection(s => s.Mode(SelectionMode.Single))
            .SelectedRowKeys(new JS("component.option('value')"))
            .OnSelectionChanged("innerDataGrid_selectionChanged")
        )
    }
    
    <script>
        function innerDataGrid_selectionChanged(info) {
            $("#dropDownBox").dxDropDownBox("option", "value", info.selectedRowKeys)
        }
        function dropDownBox_valueChanged(e) {
            $("#dataGrid").dxDataGrid("selectRows", e.value, false);
        }
    </script>

Single Selection Demo Multiple Selection Demo

See Also
  • Use the DropDownBox as a column editor in the DataGrid: jQuery