React DropDownBox - Getting Started

Drop-down editors allow users to navigate through a list of items, select one or multiple items, and search through the list. To learn how to choose a DevExtreme drop-down editor and for more details about the component's features, refer to the following article: How to Choose a Drop-Down Editor.

jQuery
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.
Angular
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.
Vue
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.
React
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.

The DropDownBox component consists of a text field that displays the current value and a drop-down field that can contain any UI element.

This tutorial shows how to add the DropDownBox component to your application and configure this component's core features.

Each section in this tutorial describes a single configuration step. You can also find the full source code in the GitHub repository.

View on GitHub

Create DropDownBox

jQuery

Add DevExtreme to your jQuery application and use the following code to create a DropDownBox component:

index.js
index.html
$(function() {
    $("#drop-down-box").dxDropDownBox({ });
});
<html>
    <head>
        <!-- ... -->
        <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        <link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/24.2.3/css/dx.light.css">
        <script type="text/javascript" src="https://cdn3.devexpress.com/jslib/24.2.3/js/dx.all.js"></script>
        <script type="text/javascript" src="index.js"></script>
    </head>
    <body>
        <div id="drop-down-box"></div>
    </body>
</html>
Angular

Add DevExtreme to your Angular application and use the following code to create a DropDownBox component:

app.component.html
app.component.ts
app.module.ts
<dx-drop-down-box></dx-drop-down-box>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {

}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { DxDropDownBoxModule } from 'devextreme-angular';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        DxDropDownBoxModule
    ],
    providers: [ ],
    bootstrap: [AppComponent]
})
export class AppModule { }
Vue

Add DevExtreme to your Vue application and use the following code to create a DropDownBox component:

App.vue
<template>
    <DxDropDownBox>
    </DxDropDownBox>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';
import { DxDropDownBox } from 'devextreme-vue/drop-down-box';

export default {
    components: {
        DxDropDownBox
    }
}
</script>
React

Add DevExtreme to your React application and use the following code to create a DropDownBox component:

App.js
import React from 'react';

import 'devextreme/dist/css/dx.light.css';

import { DropDownBox } from 'devextreme-react/drop-down-box';

function App() {
    return (
        <DropDownBox>
        </DropDownBox>
    );
}

export default App;

Add an Embedded Element

You can add any element in a DropDownBox content field. This tutorial uses the List component as an embedded element. To see how to use other components, such as DataGrid or TreeView, refer to the following demo: DropDownBox: Single Selection

Call the contentTemplate function or specify content inside the DropDownBox markup.

The following code adds the List component, binds it to data, enables the item deletion functionality and prevents users from deleting the last item. Additionally, the code gets the List's instance.

jQuery
index.js
const fruits = ["Apples", "Oranges", "Lemons", "Pears", "Pineapples"];
const dataSource = fruits;
let list;

$(function() {
    $("#drop-down-box").dxDropDownBox({
        contentTemplate: function(e) {
            const $list = $("<div>").dxList({
                dataSource,
                allowItemDeleting: true,
                onItemDeleting: function(e) {
                    if (dataSource.length === 1) {
                        e.cancel = true;
                    }
                }
            });
            list = $list.dxList('instance');
            return $list;
        },
    });
});
Angular
app.component.html
app.component.ts
app.module.ts
<dx-drop-down-box>
    <dx-list 
        [dataSource]="dataSource" 
        [allowItemDeleting]="true"
        (onItemDeleting)="onItemDeleting($event)"
    >
    </dx-list>
</dx-drop-down-box>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    @ViewChild(DxListComponent, { static: false }) list: DxListComponent
    fruits = ["Apples", "Oranges", "Lemons", "Pears", "Pineapples"];
    dataSource = this.fruits;

    onItemDeleting(e: { cancel: boolean; }) {
        if (this.dataSource.length === 1) {
            e.cancel = true;
        }
    }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { DxDropDownBoxModule, DxListModule } from 'devextreme-angular';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        DxDropDownBoxModule,
        DxListModule
    ],
    providers: [ ],
    bootstrap: [AppComponent]
})
export class AppModule { }
Vue
App.vue
<template>
    <DxDropDownBox>
        <DxList
            :data-source="dataSource"
            :allow-item-deleting="true"
            @item-deleting="onItemDeleting($event)"
            @initialized="saveListInstance"
        >
        </DxList>
    </DxDropDownBox>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';
import { DxDropDownBox } from 'devextreme-vue/drop-down-box';
import DxList from "devextreme-vue/list";

export default {
    components: {
        DxDropDownBox,
        DxList
    },
    data() {
        const fruits = ["Apples", "Oranges", "Lemons", "Pears", "Pineapples"];
        return {
            dataSource: fruits,
            listInstance: null
        }
    },
    methods: {
        onItemDeleting(e) {
            if (this.dataSource.length === 1) {
                e.cancel = true;
            }
        },
        saveListInstance(e) {
            this.listInstance = e.component;
        }
    }
}
</script>
React
App.js
import React, { useState, useRef, useCallback } from 'react';

import 'devextreme/dist/css/dx.light.css';

import { DropDownBox } from 'devextreme-react/drop-down-box';
import { List } from "devextreme-react/list";

const fruits = ["Apples", "Oranges", "Lemons", "Pears", "Pineapples"];

function App() {
    const [dataSource, setDataSource] = useState(fruits);
    const listRef = useRef(null);
    const onItemDeleting = useCallback((e) => {
        if (dataSource.length === 1) {
            e.cancel = true;
        }
    }, [dataSource]);
    return (
        <DropDownBox>
            <List
                ref={listRef}
                dataSource={dataSource}
                allowItemDeleting={true}
                onItemDeleting={onItemDeleting}
            />
        </DropDownBox>
    );
}

export default App;

Configure Selection

The previous topic shows how to embed the List component into the DropDownBox component's drop-down field. To implement a scenario where the values selected in the List appear in the component's text field, do the following:

  1. Bind the same data source to the List and DropDownBox components. This tutorial uses a basic array as a data source.

  2. Specify the List selectionMode property to enable selection.

  3. Implement the onSelectionChanged event handler. In this handler, pass the selected value to the DropDownBox component's value option.

The Synchronize with the Embedded Element article shows how to implement other synchronization scenarios. For example, you can:

  • Bind the DropDownBox and the embedded element to different data sources.

  • Specify complex data sources.

  • Select the initial value.

Refer to the article to learn more.

jQuery
index.js
// ...
$(function() {
    $("#drop-down-box").dxDropDownBox({
        dataSource,
        contentTemplate: function(e) {
            const $list = $("<div>").dxList({
                // ...
                selectionMode: "single",
                onSelectionChanged: function(arg) {
                    e.component.option("value", arg.addedItems[0]);
                    e.component.close();
                },
            });
            // ...
        }
    });
});
Angular
app.component.html
app.component.ts
<dx-drop-down-box
    [dataSource]="dataSource" 
    [(value)]="selectedFruit" 
    [(opened)]="isDropDownBoxOpened"
>
    <dx-list ...
        selectionMode="single" 
        (onSelectionChanged)="changeDropDownBoxValue($event)"
    >
    </dx-list>
</dx-drop-down-box>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    // ...
    selectedFruit = '';
    isDropDownBoxOpened = false;

    changeDropDownBoxValue (args: { addedItems: string[]; }) {
        this.selectedFruit = args.addedItems[0];
        this.isDropDownBoxOpened = false;
    }
}
Vue
App.vue
<template>
    <DxDropDownBox
        :data-source="dataSource"
        v-model:value="selectedFruit"
        v-model:opened="isDropDownBoxOpened"
    >
        <DxList ...
            selection-mode="single"
            @selection-changed="changeDropDownBoxValue($event)"
        >
        </DxList>
    </DxDropDownBox>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';
import { DxDropDownBox } from 'devextreme-vue/drop-down-box';
import DxList from "devextreme-vue/list";

export default {
    components: {
        DxDropDownBox,
        DxList
    },
    data() {
        // ...
        return {
            // ...
            isDropDownBoxOpened: false,
            selectedFruit: '',
        }
    },
    methods: {
        // ...
        changeDropDownBoxValue(e) {
            this.selectedFruit = e.addedItems[0];
            this.isDropDownBoxOpened = false;
        }
    }
}
</script>
React
App.js
import React, { useState, useRef, useCallback } from 'react';

import 'devextreme/dist/css/dx.light.css';

import { DropDownBox } from 'devextreme-react/drop-down-box';
import { List } from "devextreme-react/list";

// ...

function App() {
    // ...
    const [selectedFruit, setSelectedFruit] = useState('');
    const dropDownBoxRef = useRef(null);
    const changeDropDownBoxValue = useCallback((arg) => {
        setSelectedFruit(arg.addedItems[0]);
        dropDownBoxRef.current.instance().close();
    }, []);
    const onValueChanged = useCallback((e) => {
        setSelectedFruit(e.value);
    }, []);
    return (
        <DropDownBox
            dataSource={dataSource}
            value={selectedFruit}
            ref={dropDownBoxRef}
            onValueChanged={onValueChanged}
        >
            <List ...
                selectionMode="single"
                onSelectionChanged={changeDropDownBoxValue}
            />
        </DropDownBox>
    );
}

export default App;

Handle Events

You can allow users to type in the DropDownBox text field to add more values to the List. In this tutorial, the Enter keystroke passes values to the List. To implement this functionality, enable the acceptCustomValue property, disable the openOnFieldClick property, and handle the enterKey event. In this handler, update the shared data source and reload the List.

jQuery
index.js
// ...
$(function() {
    $("#drop-down-box").dxDropDownBox({
        // ...
        acceptCustomValue: true,
        openOnFieldClick: false,
        onEnterKey: function(e) {
            dataSource.push(e.component.option("value"));
            e.component.option("value", "");
            list.reload();
        }
    });
});
Angular
app.component.html
app.component.ts
<dx-drop-down-box ...
    [acceptCustomValue]="true"
    [openOnFieldClick]="false"
    (onEnterKey)="addItem()"
>
    <dx-list ...
    >
    </dx-list>
</dx-drop-down-box>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    // ...
    addItem () {
        this.dataSource.push(this.selectedFruit);
        this.selectedFruit = '';
        this.list.instance.reload();
    }
}
Vue
App.vue
<template>
    <DxDropDownBox ...
        :accept-custom-value="true"
        :open-on-field-click="false"
        @enter-key="addItem"
    >
        <DxList ...
        >
        </DxList>
    </DxDropDownBox>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';
import { DxDropDownBox } from 'devextreme-vue/drop-down-box';
import DxList from "devextreme-vue/list";

export default {
    components: {
        DxDropDownBox,
        DxList
    },
    data() {
        // ...
    },
    methods: {
        // ...
        addItem() {
            this.dataSource.push(this.selectedFruit);
            this.selectedFruit = '';
            this.listInstance.reload();
        }
    }
}
</script>
React
App.js
import React, { useState, useRef, useCallback } from 'react';

import 'devextreme/dist/css/dx.light.css';

import { DropDownBox } from 'devextreme-react/drop-down-box';
import { List } from "devextreme-react/list";

// ...

function App() {
    // ...
    const addItem = useCallback(() => {
        setDataSource([...dataSource, selectedFruit]);
        setSelectedFruit('');
        listRef.current.instance().reload();
    }, [dataSource, selectedFruit]);
    return (
        <DropDownBox ...
            acceptCustomValue={true}
            openOnFieldClick={false}
            onEnterKey={addItem}
        >
            <List ...
            />
        </DropDownBox>
    );
}

export default App;

Customize Appearance

Specify the height and width properties to change the size of the DropDownBox text field. If you want to resize the drop-down field, use the dropDownOptions object.

To specify one of the predefined styles for the DropDownBox text field, use the stylingMode property. To customize the field appearance, specify the field template.

Use the placeholder property to give users a hint about what they should type in the DropDownBox text field. You can also use the label property for this purpose. If you specify the label property, set the labelMode property to one of the following values:

  • "static"
    The component displays the label above the input field.

  • "floating"
    The component uses the label as a placeholder, but when the editor receives focus, the label moves to the position above the input field.

  • "hidden"
    The label is hidden.

In this tutorial, the component also uses the label as a placeholder because the labelMode property is set to "floating".

Additionally, DropDownBox can display the following buttons:

jQuery
index.js
// ...
$(function() {
    $("#drop-down-box").dxDropDownBox({
        // ...
        label: "Fruits",
        labelMode: "floating"
    });
});
Angular
app.component.html
<dx-drop-down-box ...
    label="Fruits"
    labelMode="floating"
>
    <dx-list ...
    >
    </dx-list>
</dx-drop-down-box>
Vue
App.vue
<template>
    <DxDropDownBox ...
        label="Fruits"
        labelMode="floating"
    >
        <DxList ...
        >
        </DxList>
    </DxDropDownBox>
</template>

<script>
// ...
</script>
React
App.js
import React, { useState, useRef, useCallback } from 'react';

import 'devextreme/dist/css/dx.light.css';

import { DropDownBox } from 'devextreme-react/drop-down-box';
import { List } from "devextreme-react/list";

// ...

function App() {
    // ...
    return (
        <DropDownBox ...
            label="Fruits"
            labelMode="floating"
        >
            <List ...
            />
        </DropDownBox>
    );
}

export default App;