The TagBox component allows users to select multiple items from a drop-down list.
This demo illustrates the following TagBox properties:
items
An array of items to display in the drop-down list. Do not use the items property and the dataSource property in the same configuration.
dataSource
Binds the TagBox to a data source, which allows you to perform complex data operations. Do not use the dataSource property and the items property in the same configuration.
searchEnabled
Enables interactive item search.
showSelectionControls
Enables item selection controls.
applyValueMode
Specifies whether TagBox applies the selection instantly or after a confirmation.
hideSelectedItems
Specifies whether TagBox removes selected items from the drop-down list.
multiline
Specifies whether TagBox enables horizontal scrolling when the input field cannot fit all selected items.
acceptCustomValue
Allows users to enter custom values. To enable this capability, implement the onCustomItemCreating handler.
placeholder
Sets the value of the placeholder string.
value
Specifies the list of currently selected items.
disabled
Specifies whether the component responds to user interaction.
itemTemplate
Allows you to customize the appearance and content of list items.
tagTemplate Allows you to customize the appearance and content of list item tooltips.
To get started with the DevExtreme TagBox component, refer to the following tutorial for step-by-step instructions: Getting Started with TagBox.
@model DevExtreme.MVC.Demos.ViewModels.TagBoxViewModel
<div class="form">
<div class="dx-fieldset">
<div class="dx-field">
<div class="dx-field-label">Default mode</div>
<div class="dx-field-value">
@(Html.DevExtreme().TagBox()
.Items(Model.Items)
.InputAttr("aria-label", "Product")
)
</div>
</div>
<div class="dx-field">
<div class="dx-field-label">Search mode</div>
<div class="dx-field-value">
@(Html.DevExtreme().TagBox()
.Items(Model.Items)
.InputAttr("aria-label", "Product")
.SearchEnabled(true)
)
</div>
</div>
<div class="dx-field">
<div class="dx-field-label">Batch selection</div>
<div class="dx-field-value">
@(Html.DevExtreme().TagBox()
.Items(Model.Items)
.InputAttr("aria-label", "Product")
.ShowSelectionControls(true)
.ApplyValueMode(EditorApplyValueMode.UseButtons)
)
</div>
</div>
<div class="dx-field">
<div class="dx-field-label">Hide selected items</div>
<div class="dx-field-value">
@(Html.DevExtreme().TagBox()
.Items(Model.Items)
.InputAttr("aria-label", "Product")
.HideSelectedItems(true)
)
</div>
</div>
<div class="dx-field">
<div class="dx-field-label">Single line mode</div>
<div class="dx-field-value">
@(Html.DevExtreme().TagBox()
.Items(Model.Items)
.InputAttr("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">
@(Html.DevExtreme().TagBox()
.Items(Model.Items)
.InputAttr("aria-label", "Product")
.AcceptCustomValue(true)
.OnCustomItemCreating("customItem_creating")
)
</div>
</div>
<div class="dx-field">
<div class="dx-field-label">With custom placeholder</div>
<div class="dx-field-value">
@(Html.DevExtreme().TagBox()
.Items(Model.Items)
.InputAttr("aria-label", "Product")
.Placeholder("Choose Product...")
)
</div>
</div>
<div class="dx-field">
<div class="dx-field-label">Disabled</div>
<div class="dx-field-value">
@(Html.DevExtreme().TagBox()
.Items(Model.Items)
.InputAttr("aria-label", "Product")
.Value(new [] { Model.Items.First() })
.Disabled(true)
)
</div>
</div>
<div class="dx-field">
<div class="dx-field-label">Data source</div>
<div class="dx-field-value">
@(Html.DevExtreme().TagBox()
.DataSource(d => d.Mvc().LoadAction("GetProducts").Key("ID"))
.DisplayExpr("Name")
.InputAttr("aria-label", "Product")
.ValueExpr("ID")
)
</div>
</div>
<div class="dx-field">
<div class="dx-field-label">Custom template</div>
<div class="dx-field-value">
@(Html.DevExtreme().TagBox()
.DataSource(d => d.Mvc().LoadAction("GetProducts").Key("ID"))
.Value(new[] {1, 2})
.DisplayExpr("Name")
.ValueExpr("ID")
.InputAttr("aria-label", "Product")
.ItemTemplate(@<text>
<div class="custom-item">
<img src="<%- ImageSrc %>" alt="<%- Name %>. Picture"/>
<div class="product-name"><%- Name %></div>
</div>
</text>)
.TagTemplate(new JS("tagTemplate"))
)
@(Html.DevExtreme().Popover()
.ID("popover")
)
</div>
</div>
</div>
</div>
<script>
function customItem_creating(args) {
var newValue = args.text,
component = args.component,
currentItems = component.option("items");
const isItemInDataSource = currentItems.some((item) => item === newValue);
if (!isItemInDataSource) {
currentItems.unshift(newValue);
component.option('items', currentItems);
}
args.customItem = newValue;
}
function tagTemplate(data) {
const isDisabled = data.Name === 'SuperHD Player';
const popover = $('#popover').dxPopover('instance')
const tagImg = $('<img>', { class: 'tag-img' }).attr({
src: data.ImageSrc,
alt: `${data.Name}. Picture`
})
const tag = $('<div>')
.attr('aria-disabled', isDisabled)
.addClass(`dx-tag-content ${isDisabled && 'disabled-tag'}`)
.append(
tagImg,
$('<span>').text(data.Name),
!isDisabled && $('<div>').addClass('dx-tag-remove-button')
)
tag.on('dxhoverstart', function (args) {
popover.option({
contentTemplate: () => popoverContentTemplate(data),
target: args.target.closest('.dx-tag')
});
popover.show();
})
tag.on('dxhoverend', function (args) {
popover.hide();
})
return tag;
}
const popoverContentTemplate = function (product) {
return $('<div>').append(
$(`<p><b>Name: </b><span>${product.Name}</span></p>`),
$(`<p><b>Price: </b><span>$${product.Price}</span></p>`),
$(`<p><b>In-stock: </b><span>${product.CurrentInventory}</span></p>`),
$(`<p><b>Category: </b><span>${product.Category}</span></p>`),
);
};
</script>
using DevExtreme.AspNet.Data;
using DevExtreme.AspNet.Mvc;
using DevExtreme.MVC.Demos.Models.SampleData;
using DevExtreme.MVC.Demos.ViewModels;
using System.Linq;
using System.Text.Json;
using System.Web.Mvc;
namespace DevExtreme.MVC.Demos.Controllers {
public class TagBoxController : Controller {
public ActionResult Overview() {
return View(new TagBoxViewModel {
Items = SampleData.Electronics.Select(i => i.Name)
});
}
}
}
using System;
using System.Collections.Generic;
namespace DevExtreme.MVC.Demos.Models.SampleData {
public partial class SampleData {
public static readonly IEnumerable<ElectronicsItem> Electronics = new[] {
new ElectronicsItem {
ID = 1,
Name = "HD Video Player",
Price = 330,
CurrentInventory = 225,
Backorder = 0,
Manufacturing = 10,
Category = "Video Players",
ImageSrc = "../../Content/images/products/1-small.png",
IconSrc = "../../Content/images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 2,
Name = "SuperHD Player",
Price = 400,
CurrentInventory = 150,
Backorder = 0,
Manufacturing = 25,
Category = "Video Players",
ImageSrc = "../../Content/images/products/2-small.png",
IconSrc = "../../Content/images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 3,
Name = "SuperPlasma 50",
Price = 2400,
CurrentInventory = 0,
Backorder = 0,
Manufacturing = 0,
Category = "Televisions",
ImageSrc = "../../Content/images/products/3-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 4,
Name = "SuperLED 50",
Price = 1600,
CurrentInventory = 77,
Backorder = 0,
Manufacturing = 55,
Category = "Televisions",
ImageSrc = "../../Content/images/products/4-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 5,
Name = "SuperLED 42",
Price = 1450,
CurrentInventory = 445,
Backorder = 0,
Manufacturing = 0,
Category = "Televisions",
ImageSrc = "../../Content/images/products/5-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 6,
Name = "SuperLED 55",
Price = 1350,
CurrentInventory = 345,
Backorder = 0,
Manufacturing = 5,
Category = "Televisions",
ImageSrc = "../../Content/images/products/6-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 7,
Name = "SuperLCD 42",
Price = 1200,
CurrentInventory = 210,
Backorder = 0,
Manufacturing = 20,
Category = "Televisions",
ImageSrc = "../../Content/images/products/7-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 8,
Name = "SuperPlasma 65",
Price = 3500,
CurrentInventory = 0,
Backorder = 0,
Manufacturing = 0,
Category = "Televisions",
ImageSrc = "../../Content/images/products/8-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 9,
Name = "SuperLCD 70",
Price = 4000,
CurrentInventory = 95,
Backorder = 0,
Manufacturing = 5,
Category = "Televisions",
ImageSrc = "../../Content/images/products/9-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 10,
Name = "DesktopLED 21",
Price = 175,
CurrentInventory = 0,
Backorder = 425,
Manufacturing = 75,
Category = "Monitors",
ImageSrc = "../../Content/images/products/10-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 11,
Name = "DesktopLED 19",
Price = 165,
CurrentInventory = 425,
Backorder = 0,
Manufacturing = 110,
Category = "Monitors",
ImageSrc = "../../Content/images/products/11-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 12,
Name = "DesktopLCD 21",
Price = 170,
CurrentInventory = 210,
Backorder = 0,
Manufacturing = 60,
Category = "Monitors",
ImageSrc = "../../Content/images/products/12-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 13,
Name = "DesktopLCD 19",
Price = 160,
CurrentInventory = 150,
Backorder = 0,
Manufacturing = 210,
Category = "Monitors",
ImageSrc = "../../Content/images/products/13-small.png",
IconSrc = "../../Content/images/icons/tv.svg"
},
new ElectronicsItem {
ID = 14,
Name = "Projector Plus",
Price = 550,
CurrentInventory = 0,
Backorder = 55,
Manufacturing = 10,
Category = "Monitors",
ImageSrc = "../../Content/images/products/14-small.png",
IconSrc = "../../Content/images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 15,
Name = "Projector PlusHD",
Price = 750,
CurrentInventory = 110,
Backorder = 0,
Manufacturing = 90,
Category = "Projectors",
ImageSrc = "../../Content/images/products/15-small.png",
IconSrc = "../../Content/images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 16,
Name = "Projector PlusHT",
Price = 1050,
CurrentInventory = 0,
Backorder = 75,
Manufacturing = 57,
Category = "Projectors",
ImageSrc = "../../Content/images/products/16-small.png",
IconSrc = "../../Content/images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 17,
Name = "ExcelRemote IR",
Price = 150,
CurrentInventory = 650,
Backorder = 0,
Manufacturing = 190,
Category = "Automation",
ImageSrc = "../../Content/images/products/17-small.png",
IconSrc = "../../Content/images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 18,
Name = "ExcelRemote BT",
Price = 180,
CurrentInventory = 310,
Backorder = 0,
Manufacturing = 0,
Category = "Automation",
ImageSrc = "../../Content/images/products/18-small.png",
IconSrc = "../../Content/images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 19,
Name = "ExcelRemote IP",
Price = 200,
CurrentInventory = 0,
Backorder = 325,
Manufacturing = 225,
Category = "Automation",
ImageSrc = "../../Content/images/products/19-small.png",
IconSrc = "../../Content/images/icons/video-player.svg"
}
};
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DevExtreme.MVC.Demos.Models {
public class ElectronicsItem {
public int ID { get; set; }
public string Category { get; set; }
public string Name { get; set; }
public int CurrentInventory { get; set; }
public int Backorder { get; set; }
public int Manufacturing { get; set; }
public int Price { get; set; }
public string ImageSrc { get; set; }
public string IconSrc { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace DevExtreme.MVC.Demos.ViewModels {
public class TagBoxViewModel {
public IEnumerable<string> Items { get; set; }
}
}
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;
}
.dx-tag-content {
display: flex;
align-items: center;
}
.tag-img {
height: 30px;
margin-right: 5px;
}
.disabled-tag {
padding-right: 6px !important;
opacity: 0.5;
cursor: not-allowed;
}