DevExtreme jQuery/JS - Synchronize with the Embedded Element

You should synchronize the DropDownBox widget with an embedded element. The following instructions show how to do it when the embedded element is another DevExtreme widget, but they are also applicable in other cases.

  1. Specify data sources
    The DropDownBox's and embedded widget's data sources can be the same or different. If they are different, the widget's key field should be present in the DropDownBox's data source.

    JavaScript
    // Different data sources, both have the ID field
    var widgetData = [
        { ID: 1, fullName: "John Heart", position: "CEO"},
        { ID: 2, fullName: "Samantha Bright", position: "COO", headID: 1 },
        // ...
    ];
    var 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 widget's keys
    Assign the field's name to the DropDownBox's valueExpr option and to the key option of the embedded widget's store. The following example shows an ArrayStore:

    jQuery
    JavaScript
    $(function() {
        // ...
        $("#dropDownBox").dxDropDownBox({ 
            dataSource: dropDownBoxData,
            valueExpr: "ID",
            displayExpr: "email",
            contentTemplate: function (e) {
                var $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
        ],
        // ...
    })
    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"))
            )
        )
    }
    Vue
    DxComponent.vue
    <template>
        <div>
            <dx-drop-down-box
                value-expr="ID"
                display-expr="email"
                :data-source="dropDownBoxData">
                <dx-data-grid 
                    :data-source="gridDataSource">
                </dx-data-grid>
            </dx-drop-down-box>
        </div>
    </template>
    
    <script>
    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>
  3. Synchronize the DropDownBox's value and the embedded widget's selection
    This step's implementation depends on the embedded widget'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 widget's selectedRowKeys/selectedItemKeys to the same variable. If not, handle events as described below.

    1. Set the initial selection in the embedded widget
      Implement the widget's onContentReady handler to select data items according to the DropDownBox's initial value. In some widgets, 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 widget's onSelectionChanged handler to update the DropDownBox's value when the selection changes.
    jQuery
    JavaScript
    $(function() {
        // ...
        var dataGridInstance;
        $("#dropDownBox").dxDropDownBox({ 
            // ...
            value: [1],
            contentTemplate: function (e) {
                var 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
        ],
        // ...
    })
    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>
    Vue
    DxComponent.vue
    <template>
        <div>
            <dx-drop-down-box ...
                :value.sync="dropDownBoxValues">
                <dx-data-grid ...
                    :selected-row-keys.sync="dropDownBoxValues">
                    <dx-selection mode="multiple" />
                </dx-data-grid>
            </dx-drop-down-box>
        </div>
    </template>
    
    <script>
    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>

Single Selection Demo Multiple Selection Demo

See Also