@model DevExtreme.NETCore.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)
.ShowSelectionControls(true)
.InputAttr("aria-label", "Product")
.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)
.AcceptCustomValue(true)
.InputAttr("aria-label", "Product")
.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)
.Value(new[] { Model.Items.First() })
.InputAttr("aria-label", "Product")
.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")
.InputAttr("aria-label", "Product")
.ValueExpr("ID")
.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.NETCore.Demos.Models.SampleData;
using DevExtreme.NETCore.Demos.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Linq;
namespace DevExtreme.NETCore.Demos.Controllers {
public class TagBoxController : Controller {
public ActionResult Overview() {
return View(new TagBoxViewModel {
Items = SampleData.Electronics.Select(i => i.Name)
});
}
[HttpGet]
public object GetProducts(DataSourceLoadOptions loadOptions) {
return DataSourceLoader.Load(SampleData.Electronics, loadOptions);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace DevExtreme.NETCore.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 = "../../images/products/1-small.png",
IconSrc = "../../images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 2,
Name = "SuperHD Player",
Price = 400,
CurrentInventory = 150,
Backorder = 0,
Manufacturing = 25,
Category = "Video Players",
ImageSrc = "../../images/products/2-small.png",
IconSrc = "../../images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 3,
Name = "SuperPlasma 50",
Price = 2400,
CurrentInventory = 0,
Backorder = 0,
Manufacturing = 0,
Category = "Televisions",
ImageSrc = "../../images/products/3-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 4,
Name = "SuperLED 50",
Price = 1600,
CurrentInventory = 77,
Backorder = 0,
Manufacturing = 55,
Category = "Televisions",
ImageSrc = "../../images/products/4-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 5,
Name = "SuperLED 42",
Price = 1450,
CurrentInventory = 445,
Backorder = 0,
Manufacturing = 0,
Category = "Televisions",
ImageSrc = "../../images/products/5-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 6,
Name = "SuperLED 55",
Price = 1350,
CurrentInventory = 345,
Backorder = 0,
Manufacturing = 5,
Category = "Televisions",
ImageSrc = "../../images/products/6-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 7,
Name = "SuperLCD 42",
Price = 1200,
CurrentInventory = 210,
Backorder = 0,
Manufacturing = 20,
Category = "Televisions",
ImageSrc = "../../images/products/7-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 8,
Name = "SuperPlasma 65",
Price = 3500,
CurrentInventory = 0,
Backorder = 0,
Manufacturing = 0,
Category = "Televisions",
ImageSrc = "../../images/products/8-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 9,
Name = "SuperLCD 70",
Price = 4000,
CurrentInventory = 95,
Backorder = 0,
Manufacturing = 5,
Category = "Televisions",
ImageSrc = "../../images/products/9-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 10,
Name = "DesktopLED 21",
Price = 175,
CurrentInventory = 0,
Backorder = 425,
Manufacturing = 75,
Category = "Monitors",
ImageSrc = "../../images/products/10-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 11,
Name = "DesktopLED 19",
Price = 165,
CurrentInventory = 425,
Backorder = 0,
Manufacturing = 110,
Category = "Monitors",
ImageSrc = "../../images/products/11-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 12,
Name = "DesktopLCD 21",
Price = 170,
CurrentInventory = 210,
Backorder = 0,
Manufacturing = 60,
Category = "Monitors",
ImageSrc = "../../images/products/12-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 13,
Name = "DesktopLCD 19",
Price = 160,
CurrentInventory = 150,
Backorder = 0,
Manufacturing = 210,
Category = "Monitors",
ImageSrc = "../../images/products/13-small.png",
IconSrc = "../../images/icons/tv.svg"
},
new ElectronicsItem {
ID = 14,
Name = "Projector Plus",
Price = 550,
CurrentInventory = 0,
Backorder = 55,
Manufacturing = 10,
Category = "Monitors",
ImageSrc = "../../images/products/14-small.png",
IconSrc = "../../images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 15,
Name = "Projector PlusHD",
Price = 750,
CurrentInventory = 110,
Backorder = 0,
Manufacturing = 90,
Category = "Projectors",
ImageSrc = "../../images/products/15-small.png",
IconSrc = "../../images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 16,
Name = "Projector PlusHT",
Price = 1050,
CurrentInventory = 0,
Backorder = 75,
Manufacturing = 57,
Category = "Projectors",
ImageSrc = "../../images/products/16-small.png",
IconSrc = "../../images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 17,
Name = "ExcelRemote IR",
Price = 150,
CurrentInventory = 650,
Backorder = 0,
Manufacturing = 190,
Category = "Automation",
ImageSrc = "../../images/products/17-small.png",
IconSrc = "../../images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 18,
Name = "ExcelRemote BT",
Price = 180,
CurrentInventory = 310,
Backorder = 0,
Manufacturing = 0,
Category = "Automation",
ImageSrc = "../../images/products/18-small.png",
IconSrc = "../../images/icons/video-player.svg"
},
new ElectronicsItem {
ID = 19,
Name = "ExcelRemote IP",
Price = 200,
CurrentInventory = 0,
Backorder = 325,
Manufacturing = 225,
Category = "Automation",
ImageSrc = "../../images/products/19-small.png",
IconSrc = "../../images/icons/video-player.svg"
}
};
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace DevExtreme.NETCore.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.NETCore.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;
}