Getting Started with TagBox

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

The TagBox is an editor that allows users to select multiple items from a drop-down list.

This tutorial explains how to add a TagBox to a page, populate the drop-down list, allow users to search through it, and log the selected item data to the console.

Each section in this tutorial covers a single configuration step. You can also find the full code in the following GitHub repository: getting-started-with-tagbox.

Create the TagBox

Use the code below to create an empty TagBox:

jQuery

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

index.js
index.html
$(function() {
    $("#tagBox").dxTagBox({ });
});
<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/21.1.6/css/dx.light.css">
        <script type="text/javascript" src="https://cdn3.devexpress.com/jslib/21.1.6/js/dx.all.js"></script>
        <script type="text/javascript" src="index.js"></script>
    </head>
    <body>
        <div id="tagBox"></div>
    </body>
</html>
Angular

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

app.component.html
app.component.ts
app.module.ts
<dx-tag-box></dx-tag-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 { DxTagBoxModule } from 'devextreme-angular';

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

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

App.vue
<template>
    <DxTagBox/>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';
import { DxTagBox } from 'devextreme-vue/tag-box';

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

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

App.js
import React from 'react';

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

import { TagBox } from 'devextreme-react/tag-box';

function App() {
    return (
        <TagBox
            {/* Configuration goes here */}
        >
        </TagBox>
    );
}

export default App;

Run the code and ensure the TagBox is displayed, and its drop-down list says "No data to display." In the next step, we will add a data source.

Bind the TagBox to Data

The TagBox can load data from different data source types. To use a local array, assign it to the dataSource property. If array elements are objects, set the fields that supply the TagBox's value (valueExpr) and displayed value (displayExpr). For information on other data source types, refer to the following articles:

jQuery
index.js
data.js
$(function() {
    $("#tagBox").dxTagBox({
        dataSource: data,
        valueExpr: "ID",
        displayExpr: "Name"
    });
});
const data = [{
    "ID": 1,
    "Name": "HD Video Player",
    "Category": "Video Players"
}, {
    "ID": 2,
    "Name": "SuperHD Player",
    "Category": "Video Players"
}, {
    "ID": 3,
    "Name": "SuperPlasma 50",
    "Category": "Televisions"
}, {
    "ID": 4,
    "Name": "SuperLED 50",
    "Category": "Televisions"
}, {
    "ID": 7,
    "Name": "SuperLCD 42",
    "Category": "Televisions"
}, {
    "ID": 8,
    "Name": "SuperPlasma 65",
    "Category": "Televisions"
}, {
    "ID": 10,
    "Name": "DesktopLED 21",
    "Category": "Monitors"
}, {
    "ID": 11,
    "Name": "DesktopLED 19",
    "Category": "Monitors"
}, {
    "ID": 12,
    "Name": "DesktopLCD 21",
    "Category": "Monitors"
}, {
    "ID": 13,
    "Name": "DesktopLCD 19",
    "Category": "Monitors"
}, {
    "ID": 14,
    "Name": "Projector Plus",
    "Category": "Projectors"
}, {
    "ID": 15,
    "Name": "Projector PlusHD",
    "Category": "Projectors"
}, {
    "ID": 16,
    "Name": "Projector PlusHT",
    "Category": "Projectors"
}, {
    "ID": 17,
    "Name": "ExcelRemote IR",
    "Category": "Automation"
}, {
    "ID": 18,
    "Name": "ExcelRemote BT",
    "Category": "Automation"
}];
Angular
app.component.html
app.component.ts
app.service.ts
<dx-tag-box
    [dataSource]="data"
    valueExpr="ID"
    displayExpr="Name">
</dx-tag-box>
import { Component } from '@angular/core';
import { AppService, Item } from './app.service';

// ...
export class AppComponent {
    data: Item[];

    constructor(service: AppService) {
        this.data = service.getItems();
    }
}
import { Injectable } from '@angular/core';

export class Item {
    ID: number;
    Name: string;
    Category: string;
}

const data: Item[] = [{
    "ID": 1,
    "Name": "HD Video Player",
    "Category": "Video Players"
}, {
    "ID": 2,
    "Name": "SuperHD Player",
    "Category": "Video Players"
}, {
    "ID": 3,
    "Name": "SuperPlasma 50",
    "Category": "Televisions"
}, {
    "ID": 4,
    "Name": "SuperLED 50",
    "Category": "Televisions"
}, {
    "ID": 7,
    "Name": "SuperLCD 42",
    "Category": "Televisions"
}, {
    "ID": 8,
    "Name": "SuperPlasma 65",
    "Category": "Televisions"
}, {
    "ID": 10,
    "Name": "DesktopLED 21",
    "Category": "Monitors"
}, {
    "ID": 11,
    "Name": "DesktopLED 19",
    "Category": "Monitors"
}, {
    "ID": 12,
    "Name": "DesktopLCD 21",
    "Category": "Monitors"
}, {
    "ID": 13,
    "Name": "DesktopLCD 19",
    "Category": "Monitors"
}, {
    "ID": 14,
    "Name": "Projector Plus",
    "Category": "Projectors"
}, {
    "ID": 15,
    "Name": "Projector PlusHD",
    "Category": "Projectors"
}, {
    "ID": 16,
    "Name": "Projector PlusHT",
    "Category": "Projectors"
}, {
    "ID": 17,
    "Name": "ExcelRemote IR",
    "Category": "Automation"
}, {
    "ID": 18,
    "Name": "ExcelRemote BT",
    "Category": "Automation"
}];

@Injectable({
    providedIn: 'root'
})

export class AppService {
    getItems(): Item[] {
        return data;
    }
}
Vue
App.vue
data.js
<template>
    <DxTagBox
        :data-source="data"
        value-expr="ID"
        display-expr="Name"
    />
</template>

<script>
// ...
import { data } from './data';

export default {
    components: {
        DxTagBox
    },
    data() {
        return {
            data
        }
    }
}
</script>
export const data = [{
    "ID": 1,
    "Name": "HD Video Player",
    "Category": "Video Players"
}, {
    "ID": 2,
    "Name": "SuperHD Player",
    "Category": "Video Players"
}, {
    "ID": 3,
    "Name": "SuperPlasma 50",
    "Category": "Televisions"
}, {
    "ID": 4,
    "Name": "SuperLED 50",
    "Category": "Televisions"
}, {
    "ID": 7,
    "Name": "SuperLCD 42",
    "Category": "Televisions"
}, {
    "ID": 8,
    "Name": "SuperPlasma 65",
    "Category": "Televisions"
}, {
    "ID": 10,
    "Name": "DesktopLED 21",
    "Category": "Monitors"
}, {
    "ID": 11,
    "Name": "DesktopLED 19",
    "Category": "Monitors"
}, {
    "ID": 12,
    "Name": "DesktopLCD 21",
    "Category": "Monitors"
}, {
    "ID": 13,
    "Name": "DesktopLCD 19",
    "Category": "Monitors"
}, {
    "ID": 14,
    "Name": "Projector Plus",
    "Category": "Projectors"
}, {
    "ID": 15,
    "Name": "Projector PlusHD",
    "Category": "Projectors"
}, {
    "ID": 16,
    "Name": "Projector PlusHT",
    "Category": "Projectors"
}, {
    "ID": 17,
    "Name": "ExcelRemote IR",
    "Category": "Automation"
}, {
    "ID": 18,
    "Name": "ExcelRemote BT",
    "Category": "Automation"
}];
React
App.js
data.js
// ...
import { data } from './data';

function App() {
    return (
        <TagBox
            dataSource={data}
            valueExpr="ID"
            displayExpr="Name"
        />
    );
}

export default App;
export const data = [{
    "ID": 1,
    "Name": "HD Video Player",
    "Category": "Video Players"
}, {
    "ID": 2,
    "Name": "SuperHD Player",
    "Category": "Video Players"
}, {
    "ID": 3,
    "Name": "SuperPlasma 50",
    "Category": "Televisions"
}, {
    "ID": 4,
    "Name": "SuperLED 50",
    "Category": "Televisions"
}, {
    "ID": 7,
    "Name": "SuperLCD 42",
    "Category": "Televisions"
}, {
    "ID": 8,
    "Name": "SuperPlasma 65",
    "Category": "Televisions"
}, {
    "ID": 10,
    "Name": "DesktopLED 21",
    "Category": "Monitors"
}, {
    "ID": 11,
    "Name": "DesktopLED 19",
    "Category": "Monitors"
}, {
    "ID": 12,
    "Name": "DesktopLCD 21",
    "Category": "Monitors"
}, {
    "ID": 13,
    "Name": "DesktopLCD 19",
    "Category": "Monitors"
}, {
    "ID": 14,
    "Name": "Projector Plus",
    "Category": "Projectors"
}, {
    "ID": 15,
    "Name": "Projector PlusHD",
    "Category": "Projectors"
}, {
    "ID": 16,
    "Name": "Projector PlusHT",
    "Category": "Projectors"
}, {
    "ID": 17,
    "Name": "ExcelRemote IR",
    "Category": "Automation"
}, {
    "ID": 18,
    "Name": "ExcelRemote BT",
    "Category": "Automation"
}];

If you run this code and open the TagBox, you will see a populated drop-down list. Next, we will enable search.

Enable Search

To allow users to search through TagBox values, set searchEnabled to true:

jQuery
index.js
$(function() {
    $("#tagBox").dxTagBox({
        // ...
        searchEnabled: true
    });
});
Angular
app.component.html
<dx-tag-box ...
    [searchEnabled]="true">
</dx-tag-box>
Vue
App.vue
<template>
    <DxTagBox ...
        :search-enabled="true"
    />
</template>

<script>
    // ...
</script>
React
App.js
// ...

function App() {
    return (
        <TagBox ...
            searchEnabled={true}
        />
    );
}
export default App;

In the next step, we will handle the TagBox's value change event.

Handle the Value Change Event

Implement the onValueChanged handler to perform an action when a user selects an item. In the code below, this function logs the IDs of the currently and previously selected items.

jQuery
index.js
$(function() {
    $("#tagBox").dxTagBox({
        // ...
        onValueChanged: function(e) {
            console.log(e.value);
            console.log(e.previousValue);
        },
    });
});
Angular
app.component.html
app.component.ts
<dx-tag-box ...
    (onValueChanged)="onValueChanged($event)">
</dx-tag-box>
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    // ...
    onValueChanged(e) {
        console.log(e.previousValue);
        console.log(e.value);
    }
}
Vue
App.vue
<template>
    <DxTagBox ...
        @value-changed="onValueChanged"
    />
</template>

<script>
export default {
    // ...
    methods: {
        onValueChanged(e) {
            console.log(e.previousValue);
            console.log(e.value);
        }
    }
}
</script>
React
App.js
import React, { useCallback } from 'react';

function App() { 
    const onValueChanged = useCallback((e) => {
        console.log(e.previousValue);
        console.log(e.value);
    }, []);

    return (
        <TagBox ...
            onValueChanged={onValueChanged}
        />
    );
}

export default App;

Group Data

The TagBox can display data grouped by category. To implement this, we will use the data from the previous steps with the DataSource component. Its API allows you to sort, filter, select, and group data. At its core, the DataSource has a store - an object that keeps data and provides an API to access and modify it. To configure the store, use the DataSource's store object. Specify its type as "array", pass the initial data array to the data field, and set the key field.

To group data, specify the data field to group by the DataSource's group property and set the TagBox's grouped property to true.

jQuery
index.js
$(function() {
    const dataSource = new DevExpress.data.DataSource({
        store: data,
        type: "array",
        key: "ID",
        group: "Category"
    });

    $("#tagBox").dxTagBox({
        // ...
        grouped: true
    });
});
Angular
app.component.html
app.component.ts
<dx-tag-box ...
    [grouped]="true">
</dx-tag-box>
// ...
import DataSource from 'devextreme/data/data_source';

// ...
export class AppComponent {
    data: Item[];
    dataSource: DataSource;

    constructor(service: AppService) {
        this.data = service.getItems();
        this.dataSource = new DataSource({
            store: {
                data: this.data,
                type: 'array',
                key: 'ID'
            },
            group: "Category"
        });
    }
    // ...
}
Vue
App.vue
<template>
    <DxTagBox ...
        :grouped="true"
    />
</template>

<script>
// ...
import DataSource from 'devextreme/data/data_source';

export default {
    components: {
        DxTagBox
    },
    data() {
        return {
            dataSource: new DataSource({
                store: {
                    data: data,
                    type: 'array',
                    key: 'ID',
                },
                group: "Category"
            })
        }
    },
    // ...
}
</script>
React
App.js
// ...
import DataSource from 'devextreme/data/data_source';

const dataSource = new DataSource({
    store: {
        data: data,
        type: 'array',
        key: 'ID'
    },
    group: "Category"
})

function App() {
    // ...
    return (
        <TagBox ...
            grouped={true}
        />
    );   
}

export default App;

If your data is already grouped, ensure each group has the key and items fields as shown in the following article: Grouping in the Data Source. If the fields are named differently, implement the DataSource's map function to create key + items field mappings.

This demo shows additional search properties:

View Demo

Next, we will configure tag selection.

Configure Multiple Tags Selection

Use the following properties to adapt the TagBox text field to multiple selected tags:

  • multiline
    Set this property to true to display tags on multiple lines when the tags overflow the component's width.

  • maxDisplayedTags
    Use this property to specifiy the limit after which the TagBox replaces selected tags with a single multi-tag.

  • showMultiTagOnly
    Specifies whether to display the multi-tag without ordinary tags. This property is not demonstrated in this tutorial. Refer to the following demo to see it in action: Tag Count Limitation.

Drop-down list values can display selection checkboxes. To enable this feature, set the showSelectionControls property to true. This property also adds the "Select All" checkbox to the list.

jQuery
index.js
$(function() {
    $("#tagBox").dxTagBox({
        // ...
        multiline: true,
        maxDisplayedTags: 6,
        showSelectionControls: true
    });
});
Angular
app.component.html
<dx-tag-box ...
    [multiline]="true"
    [maxDisplayedTags]="6"
    [showSelectionControls]="true">
</dx-tag-box>
Vue
App.vue
<template>
    <DxTagBox ...
        :multiline="true"
        :max-displayed-tags="6"
        :show-selection-controls="true"
    />
</template>

<script>
    // ...
</script>
React
App.js
// ...
function App() {
    // ...
    return (
        <TagBox ...
            multiline={true}
            maxDisplayedTags={6}
            showSelectionControls={true}
        />
    );   
}

export default App;

Use the applyValueMode property to specify whether to apply values instantly or when users click the "OK" button. You can also enable the hideSelectedItems property if you want to remove already selected items from the drop-down list. These properties are not demonstrated in this tutorial.

Customize the Drop-Down Menu

The TagBox uses the Popup component as a drop-down menu. To customize the menu, specify Popup properties in the dropDownOptions object. For example, the following code sets the height of TagBox's drop-down menu to 300 pixels:

jQuery
index.js
$(function() {
    $("#tagBox").dxTagBox({
        // ...
        dropDownOptions: {
            height: 300
        }
    });
});
Angular
app.component.html
app.component.ts
<dx-tag-box ...
    [dropDownOptions]="dropDownOptions">
</dx-tag-box>
// ...
export class AppComponent {
    // ...
    dropDownOptions = {
        height: 300
    }
}
Vue
App.vue
<template>
    <DxTagBox ...
        :drop-down-options="dropDownOptions"
    />
</template>

<script>
// ...
export default {
    data() {
        return {
            // ...
            dropDownOptions: {
                height: 300
            }
        };
    }
}
</script>
React
App.js
// ...
const dropDownOptions = {
    height: 300
};

function App() {
    return (
        <TagBox ...
            dropDownOptions={dropDownOptions}
        />
    );
}

export default App;

You have configured basic TagBox features. To take a more detailed look at this UI component, explore the following resources: