Your search did not match any results.

Overview

The TagBox allows users to select multiple items from a drop-down list. This demo illustrates the following TagBox properties:

  • items
    An array of items displayed by the TagBox.

  • searchEnabled
    Specifies whether the search is enabled.

  • showSelectionControls
    Defines whether to display the selection controls.

  • applyValueMode
    Specifies whether selected values are applied instantly or when a user clicks the OK button.

  • hideSelectedItems
    Specifies whether the selected items are removed from the drop-down list.

  • multiline
    Displays selected items on single or multiple lines.

  • acceptCustomValue
    Specifies whether users can enter custom values. Requires that you also implement the onCustomItemCreating handler.

  • placeholder
    Customizes the TagBox placeholder.

  • value
    Specifies items the TagBox currently displays.

  • disabled
    Defines whether the component responds to user interaction.

  • dataSource
    Binds the TagBox to data. Unlike the items property, dataSource accepts the DataSource object that allows users to sort, filter, group, and shape data. Note that you cannot use items and dataSource simultaneously.

  • itemTemplate
    Allows you to customize the drop-down list items.

To get started with the DevExtreme TagBox component, refer to the following tutorial for step-by-step instructions: Getting Started with TagBox.

Backend API
<template> <div class="dx-fieldset"> <div class="dx-field"> <div class="dx-field-label">Default mode</div> <div class="dx-field-value"> <DxTagBox :items="simpleProducts" :input-attr="{ 'aria-label': 'Product' }" /> </div> </div> <div class="dx-field"> <div class="dx-field-label">Search mode</div> <div class="dx-field-value"> <DxTagBox :items="simpleProducts" :search-enabled="true" :input-attr="{ 'aria-label': 'Product' }" /> </div> </div> <div class="dx-field"> <div class="dx-field-label">Batch selection</div> <div class="dx-field-value"> <DxTagBox :items="simpleProducts" :show-selection-controls="true" :input-attr="{ 'aria-label': 'Product' }" apply-value-mode="useButtons" /> </div> </div> <div class="dx-field"> <div class="dx-field-label">Hide selected items</div> <div class="dx-field-value"> <DxTagBox :items="simpleProducts" :input-attr="{ 'aria-label': 'Product' }" :hide-selected-items="true" /> </div> </div> <div class="dx-field"> <div class="dx-field-label">Single line mode</div> <div class="dx-field-value"> <DxTagBox :items="simpleProducts" :input-attr="{ 'aria-label': 'Product' }" :multiline="false" /> </div> </div> <div class="dx-field"> <div class="dx-field-label">Add custom items</div> <div class="dx-field-value"> <DxTagBox :items="editableProducts" :accept-custom-value="true" :input-attr="{ 'aria-label': 'Product' }" @customItemCreating="onCustomItemCreating" /> </div> </div> <div class="dx-field"> <div class="dx-field-label">With custom placeholder</div> <div class="dx-field-value"> <DxTagBox :items="simpleProducts" :input-attr="{ 'aria-label': 'Product' }" placeholder="Choose Product..." /> </div> </div> <div class="dx-field"> <div class="dx-field-label">Disabled</div> <div class="dx-field-value"> <DxTagBox :items="simpleProducts" :input-attr="{ 'aria-label': 'Product' }" :value="[simpleProducts[0]]" :disabled="true" /> </div> </div> <div class="dx-field"> <div class="dx-field-label">Data source</div> <div class="dx-field-value"> <DxTagBox :data-source="products" :input-attr="{ 'aria-label': 'Product' }" display-expr="Name" value-expr="Id" /> </div> </div> <div class="dx-field"> <div class="dx-field-label">Custom template</div> <div class="dx-field-value"> <DxTagBox :data-source="products" :value="value" :input-attr="{ 'aria-label': 'Product' }" display-expr="Name" value-expr="Id" item-template="item" tag-template="tag" > <template #item="{ data }"> <Item :item-data="data"/> </template> <template #tag="{ data }"> <Tag :tag-data="data"/> </template> </DxTagBox> </div> </div> </div> </template> <script setup lang="ts"> import { ref } from 'vue'; import DxTagBox from 'devextreme-vue/tag-box'; import Item from './Item.vue'; import Tag from './Tag.vue'; import { simpleProducts, products } from './data.js'; const editableProducts = ref(simpleProducts.slice()); const value = ref([1, 2]); const onCustomItemCreating = ref((args) => { const newValue = args.text; const isItemInDataSource = editableProducts.value.some((item) => item === newValue); if (!isItemInDataSource) { editableProducts.value = [newValue, ...editableProducts.value]; } args.customItem = newValue; }); </script> <style scoped> body .custom-item { padding-left: 7px; padding-right: 7px; } .custom-item > img { height: 30px; width: 40px; float: left; margin-top: 2px; } .custom-item > div.product-name { margin-left: 40px; line-height: 34px; font-size: 14px; } body .custom-item input { background-color: transparent; } body .dx-popup-content .custom-item { padding-top: 7px; padding-bottom: 8px; } .dx-popup-content .custom-item > div { padding-left: 8px; text-indent: 0; text-overflow: ellipsis; overflow: hidden; } </style>
<template> <div class="custom-item"> <img :src="itemData.ImageSrc"> <div class="product-name"> {{ itemData.Name }} </div> </div> </template> <script setup lang="ts"> withDefaults(defineProps<{ itemData?: {[key:string]: string} }>(), { itemData: () => ({ Name: '' }), }); </script>
<template> <div> <div ref="target" :class="{'dx-tag-content': true, 'disabled-tag': isDisabled}" :aria-disabled="isDisabled" @mouseenter="show = true" @mouseleave="show = false" > <img :src="tagData.ImageSrc" class="tag-img" > <span>{{ tagData.Name }}</span> <div v-if="!isDisabled" class="dx-tag-remove-button" /> </div> <DxPopover :visible="show" :target="target" > <p> <b>Name: </b><span>{{ tagData.Name }}</span> </p> <p> <b>Price: </b><span>{{ tagData.Price }}</span> </p> <p> <b>In-stock: </b><span>{{ tagData.Current_Inventory }}</span> </p> <p> <b>Category: </b><span>{{ tagData.Category }}</span> </p> </DxPopover> </div> </template> <script setup lang="ts"> import { ref } from 'vue'; import DxPopover from 'devextreme-vue/popover'; type TagData = Record<string, string>; const props = withDefaults(defineProps<{ tagData?: TagData }>(), { tagData: () => ({} as TagData), }); const isDisabled = ref(props.tagData.Name === 'SuperHD Video Player'); const show = ref(false); const target = ref(null); </script> <style scoped> .dx-tag-content { display: flex; align-items: center; } .tag-img { height: 30px; margin-right: 5px; } .dx-tag-content.disabled-tag { padding-right: 6px; opacity: 0.5; cursor: not-allowed; } </style>
import { createApp } from 'vue'; import App from './App.vue'; createApp(App).mount('#app');
<!DOCTYPE html> <html> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/23.1.5/css/dx.light.css" /> <script type="module"> import * as vueCompilerSFC from "https://unpkg.com/@vue/compiler-sfc@3.3.4/dist/compiler-sfc.esm-browser.js"; window.vueCompilerSFC = vueCompilerSFC; </script> <script src="https://unpkg.com/typescript@3.9.10/lib/typescript.js"></script> <script src="https://unpkg.com/core-js@2.6.12/client/shim.min.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script type="text/javascript" src="config.js"></script> <script type="text/javascript"> System.import("./index.js"); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"> </div> </div> </body> </html>
export const simpleProducts = [ 'HD Video Player', 'SuperHD Video Player', 'SuperPlasma 50', 'SuperLED 50', 'SuperLED 42', 'SuperLCD 55', 'SuperLCD 42', 'SuperPlasma 65', 'SuperLCD 70', 'Projector Plus', 'Projector PlusHT', 'ExcelRemote IR', 'ExcelRemote Bluetooth', 'ExcelRemote IP', ]; export const products = [{ Id: 1, Name: 'HD Video Player', Price: 330, Current_Inventory: 225, Backorder: 0, Manufacturing: 10, Category: 'Video Players', ImageSrc: '../../../../images/products/1.png', }, { Id: 2, Name: 'SuperHD Video Player', Price: 400, Current_Inventory: 150, Backorder: 0, Manufacturing: 25, Category: 'Video Players', ImageSrc: '../../../../images/products/2.png', }, { Id: 3, Name: 'SuperPlasma 50', Price: 2400, Current_Inventory: 0, Backorder: 0, Manufacturing: 0, Category: 'Televisions', ImageSrc: '../../../../images/products/3.png', }, { Id: 4, Name: 'SuperLED 50', Price: 1600, Current_Inventory: 77, Backorder: 0, Manufacturing: 55, Category: 'Televisions', ImageSrc: '../../../../images/products/4.png', }, { Id: 5, Name: 'SuperLED 42', Price: 1450, Current_Inventory: 445, Backorder: 0, Manufacturing: 0, Category: 'Televisions', ImageSrc: '../../../../images/products/5.png', }, { Id: 6, Name: 'SuperLCD 55', Price: 1350, Current_Inventory: 345, Backorder: 0, Manufacturing: 5, Category: 'Televisions', ImageSrc: '../../../../images/products/6.png', }, { Id: 7, Name: 'SuperLCD 42', Price: 1200, Current_Inventory: 210, Backorder: 0, Manufacturing: 20, Category: 'Televisions', ImageSrc: '../../../../images/products/7.png', }, { Id: 8, Name: 'SuperPlasma 65', Price: 3500, Current_Inventory: 0, Backorder: 0, Manufacturing: 0, Category: 'Televisions', ImageSrc: '../../../../images/products/8.png', }, { Id: 9, Name: 'SuperLCD 70', Price: 4000, Current_Inventory: 95, Backorder: 0, Manufacturing: 5, Category: 'Televisions', ImageSrc: '../../../../images/products/9.png', }, { Id: 10, Name: 'DesktopLED 21', Price: 175, Current_Inventory: null, Backorder: 425, Manufacturing: 75, Category: 'Monitors', ImageSrc: '../../../../images/products/10.png', }, { Id: 12, Name: 'DesktopLCD 21', Price: 170, Current_Inventory: 210, Backorder: 0, Manufacturing: 60, Category: 'Monitors', ImageSrc: '../../../../images/products/12.png', }, { Id: 13, Name: 'DesktopLCD 19', Price: 160, Current_Inventory: 150, Backorder: 0, Manufacturing: 210, Category: 'Monitors', ImageSrc: '../../../../images/products/13.png', }, { Id: 14, Name: 'Projector Plus', Price: 550, Current_Inventory: null, Backorder: 55, Manufacturing: 10, Category: 'Projectors', ImageSrc: '../../../../images/products/14.png', }, { Id: 15, Name: 'Projector PlusHD', Price: 750, Current_Inventory: 110, Backorder: 0, Manufacturing: 90, Category: 'Projectors', ImageSrc: '../../../../images/products/15.png', }, { Id: 16, Name: 'Projector PlusHT', Price: 1050, Current_Inventory: 0, Backorder: 75, Manufacturing: 57, Category: 'Projectors', ImageSrc: '../../../../images/products/16.png', }, { Id: 17, Name: 'ExcelRemote IR', Price: 150, Current_Inventory: 650, Backorder: 0, Manufacturing: 190, Category: 'Automation', ImageSrc: '../../../../images/products/17.png', }, { Id: 18, Name: 'ExcelRemote Bluetooth', Price: 180, Current_Inventory: 310, Backorder: 0, Manufacturing: 0, Category: 'Automation', ImageSrc: '../../../../images/products/18.png', }, { Id: 19, Name: 'ExcelRemote IP', Price: 200, Current_Inventory: 0, Backorder: 325, Manufacturing: 225, Category: 'Automation', ImageSrc: '../../../../images/products/19.png', }];
window.exports = window.exports || {}; window.config = { transpiler: 'plugin-babel', meta: { '*.vue': { loader: 'vue-loader', }, '*.ts': { loader: 'demo-ts-loader', }, '*.svg': { loader: 'svg-loader', }, 'devextreme/localization.js': { 'esModule': true, }, }, paths: { 'root:': '../../../../../', 'npm:': 'https://unpkg.com/', }, map: { 'vue': 'npm:vue@3.3.4/dist/vue.esm-browser.js', 'vue-loader': 'npm:dx-systemjs-vue-browser@1.1.1/index.js', 'demo-ts-loader': 'root:utils/demo-ts-loader.js', 'svg-loader': 'root:utils/svg-loader.js', 'mitt': 'npm:mitt/dist/mitt.umd.js', 'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js', 'luxon': 'npm:luxon@1.28.1/build/global/luxon.min.js', 'es6-object-assign': 'npm:es6-object-assign@1.1.0', 'devextreme': 'npm:devextreme@23.1.6/cjs', 'devextreme-vue': 'npm:devextreme-vue@23.1.6', 'jszip': 'npm:jszip@3.7.1/dist/jszip.min.js', 'devextreme-quill': 'npm:devextreme-quill@1.6.2/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.2.2/dist/dx-diagram.js', 'devexpress-gantt': 'npm:devexpress-gantt@4.1.49/dist/dx-gantt.js', '@devextreme/runtime': 'npm:@devextreme/runtime@3.0.12', 'inferno': 'npm:inferno@7.4.11/dist/inferno.min.js', 'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js', 'inferno-create-element': 'npm:inferno-create-element@7.4.11/dist/inferno-create-element.min.js', 'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js', 'inferno-hydrate': 'npm:inferno-hydrate@7.4.11/dist/inferno-hydrate.min.js', 'inferno-clone-vnode': 'npm:inferno-clone-vnode/dist/inferno-clone-vnode.min.js', 'inferno-create-class': 'npm:inferno-create-class/dist/inferno-create-class.min.js', 'inferno-extras': 'npm:inferno-extras/dist/inferno-extras.min.js', 'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js', 'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js', // Prettier 'prettier/standalone': 'npm:prettier@2.8.4/standalone.js', 'prettier/parser-html': 'npm:prettier@2.8.4/parser-html.js', }, packages: { 'devextreme-vue': { main: 'index.js', }, 'devextreme': { defaultExtension: 'js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/runtime@3.0.12/inferno/package.json', ], babelOptions: { sourceMaps: false, stage0: true, }, }; System.config(window.config);