Your search did not match any results.
Data Grid

Custom Editors

Different editors can be used to edit cell values in grid columns. The default editor depends on the column configuration. The dependency is illustrated in the editorOptions object's description (this object is used to customize the default editor). In this demo, the SelectBox widget is the Status column's default editor, and the editorOptions object is used to specify the widget's itemTemplate.

If the default editor is unsuitable, replace it with a custom editor by specifying an editCellTemplate. In this template, configure the replacement editor's appearance and behavior. In this demo, the default editors in the Owner and Assignees columns are replaced with the DropDownBox and TagBox widgets.

@(Html.DevExtreme().DataGrid<DevExtreme.NETCore.Demos.Models.CustomEditorsTask>() .DataSource(d => d.Mvc() .Controller("DataGridCustomEditors") .LoadAction("Tasks") .InsertAction("InsertTask") .UpdateAction("UpdateTask") .Key("ID") ) .ShowBorders(true) .Editing(editing => { editing.Mode(GridEditMode.Cell); editing.AllowUpdating(true); editing.AllowAdding(true); }) .SearchPanel(sp => sp.Visible(true)) .HeaderFilter(hf => hf.Visible(true)) .Paging(p => p.PageSize(15)) .OnRowInserted("function(e) { e.component.navigateToRow(e.key); }") .Columns(columns => { columns.AddFor(m => m.Owner) .AllowSorting(false) .Lookup(lookup => lookup .DataSource(d => d.Mvc().Controller("DataGridCustomEditors").LoadAction("Employees").Key("ID")) .ValueExpr("ID") .DisplayExpr("FullName") ) .EditCellTemplate(new TemplateName("DropDownBoxTemplate")) .Width(150); columns.AddFor(m => m.AssignedEmployee) .AllowSorting(false) .Caption("Assignees") .Lookup(lookup => lookup .DataSource(d => d.Mvc().Controller("DataGridCustomEditors").LoadAction("Employees").Key("ID")) .ValueExpr("ID") .DisplayExpr("FullName") ) .CellTemplate(new JS("cellTemplate")) .CalculateFilterExpression(@<text> function(filterValue, selectedFilterOperation, target) { if(target === "search" && typeof(filterValue) === "string") { return [this.dataField, "contains", filterValue] } return function(data) { return (data.AssignedEmployee || []).indexOf(filterValue) !== -1 } }</text>) .EditCellTemplate(new TemplateName("TagBoxTemplate")) .Width(200); columns.AddFor(m => m.Subject); columns.AddFor(m => m.Status) .Width(200) .EditorOptions(new { itemTemplate = new JS("itemTemplate") }) .Lookup(lookup => lookup .DataSource(new JS("statuses")) .ValueExpr("id") .DisplayExpr("name") ); }) ) @using(Html.DevExtreme().NamedTemplate("TagBoxTemplate")) { @(Html.DevExtreme().TagBox() .DataSource(d => d.Mvc().Controller("DataGridCustomEditors").LoadAction("Employees").Key("ID")) .Value(new JS("value")) .ValueExpr("ID") .DisplayExpr("FullName") .ShowSelectionControls(true) .MaxDisplayedTags(3) .ShowMultiTagOnly(false) .ApplyValueMode(EditorApplyValueMode.UseButtons) .SearchEnabled(true) .OnValueChanged("function(e) { setValue(e.value); }") .OnSelectionChanged("function(e) { component.updateDimensions(); }") ) } @using(Html.DevExtreme().NamedTemplate("DropDownBoxTemplate")) { @(Html.DevExtreme().DropDownBox() .DataSource(d => d.Mvc().Controller("DataGridCustomEditors").LoadAction("Employees").Key("ID")) .Value(new JS("value")) .ValueExpr("ID") .DisplayExpr("FullName") .DropDownOptions(options => options.Width(500)) .Option("setValue", new JS("setValue")) .ContentTemplate(new TemplateName("ContentTemplate")) ) } @using(Html.DevExtreme().NamedTemplate("ContentTemplate")) { @(Html.DevExtreme().DataGrid() .DataSource(d => d.Mvc().Controller("DataGridCustomEditors").LoadAction("Employees").Key("ID")) .RemoteOperations(true) .Height(250) .Columns(c => { c.Add().DataField("FullName"); c.Add().DataField("Title"); c.Add().DataField("Department"); }) .Scrolling(s => s.Mode(GridScrollingMode.Virtual)) .HoverStateEnabled(true) .RemoteOperations(true) .Selection(s => s.Mode(SelectionMode.Single)) .SelectedRowKeys(new JS("[component.option('value')]")) .FocusedRowEnabled(true) .FocusedRowKey(new JS("component.option('value')")) .OnSelectionChanged("function(selectionChangedArgs) { onSelectionChanged(selectionChangedArgs, component) }") ) } <script> function cellTemplate(container, options) { var noBreakSpace = "\u00A0", text = (options.value || []).map(element => { return options.column.lookup.calculateCellValue(element); }).join(", "); container.text(text || noBreakSpace).attr("title", text); } function onSelectionChanged(selectionChangedArgs, component) { var setValue = component.option('setValue'); var selectedRowKey = selectionChangedArgs.selectedRowKeys[0]; component.option('value', selectedRowKey); setValue(selectedRowKey); if(selectionChangedArgs.selectedRowKeys.length > 0) { component.close(); } } function itemTemplate(itemData, itemIndex, itemElement) { if(itemData != null) { var imageContainer = $("<span>").addClass("status-icon middle").appendTo(itemElement); $("<img>").attr("src", "../../images/icons/status-" + itemData.id + ".png").appendTo(imageContainer); $("<span>").addClass("middle").text(itemData.name).appendTo(itemElement); } else { $("<span>").text("(All)").appendTo(itemElement); } } </script> <script src="~/data/statuses.js"></script>
using DevExtreme.NETCore.Demos.Models; using DevExtreme.NETCore.Demos.Models.DataGrid; using DevExtreme.NETCore.Demos.Models.SampleData; using Microsoft.AspNetCore.Mvc; using System.Linq; namespace DevExtreme.NETCore.Demos.Controllers { public class DataGridController : Controller { public ActionResult CustomEditors() { return View(); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json; using System.Linq; using DevExtreme.NETCore.Demos.Models.SampleData; using DevExtreme.NETCore.Demos.Models; using DevExtreme.NETCore.Demos.Models.DataGrid; namespace DevExtreme.NETCore.Demos.Controllers.ApiControllers { [Route("api/[controller]/[action]")] public class DataGridCustomEditorsController : Controller { InMemoryTasksDataContext _context; public DataGridCustomEditorsController(IHttpContextAccessor httpContextAccessor, IMemoryCache memoryCache) { _context = new InMemoryTasksDataContext(httpContextAccessor, memoryCache); } [HttpGet] public object Tasks(DataSourceLoadOptions loadOptions) { return DataSourceLoader.Load(_context.Tasks, loadOptions); } [HttpPost] public IActionResult InsertTask(string values) { var newTask = new CustomEditorsTask(); JsonConvert.PopulateObject(values, newTask); if(!TryValidateModel(newTask)) return BadRequest(ModelState.GetFullErrorMessage()); _context.Tasks.Add(newTask); _context.SaveChanges(); return Ok(newTask); } [HttpPut] public IActionResult UpdateTask(int key, string values) { var order = _context.Tasks.First(o => o.ID == key); JsonConvert.PopulateObject(values, order); if(!TryValidateModel(order)) return BadRequest(ModelState.GetFullErrorMessage()); _context.SaveChanges(); return Ok(order); } // additional actions [HttpGet] public object Employees(DataSourceLoadOptions loadOptions) { return DataSourceLoader.Load(SampleData.CustomEditorsEmployees, loadOptions); } } }
using System; using System.Collections.Generic; namespace DevExtreme.NETCore.Demos.Models.SampleData { public partial class SampleData { public static readonly IEnumerable<CustomEditorsTask> CustomEditorsTasks = new[] { new CustomEditorsTask { ID = 1, Subject = "Prepare 2013 Financial", Status = 5, Owner = 1, AssignedEmployee = new[] { 7, 1 } }, new CustomEditorsTask { ID = 2, Subject = "Prepare 2013 Marketing Plan", Status = 5, Owner = 1, AssignedEmployee = new[] { 4, 8 } }, new CustomEditorsTask { ID = 3, Subject = "Update Personnel Files", Status = 5, Owner = 1, AssignedEmployee = new[] { 2 } }, new CustomEditorsTask { ID = 4, Subject = "Review Health Insurance Options Under the Affordable Care Act", Status = 4, Owner = 1, AssignedEmployee = new[] { 2 } }, new CustomEditorsTask { ID = 5, Subject = "Choose between PPO and HMO Health Plan", Status = 4, Owner = 2, AssignedEmployee = new[] { 1 } }, new CustomEditorsTask { ID = 6, Subject = "Google AdWords Strategy", Status = 5, Owner = 4, AssignedEmployee = new[] { 1 } }, new CustomEditorsTask { ID = 7, Subject = "New Brochures", Status = 5, Owner = 4, AssignedEmployee = new[] { 1 } }, new CustomEditorsTask { ID = 8, Subject = "2013 Brochure Designs", Status = 5, Owner = 1, AssignedEmployee = new[] { 28 } }, new CustomEditorsTask { ID = 9, Subject = "Brochure Design Review", Status = 5, Owner = 28, AssignedEmployee = new[] { 29 } }, new CustomEditorsTask { ID = 10, Subject = "Website Re-Design Plan", Status = 5, Owner = 28, AssignedEmployee = new[] { 29 } }, new CustomEditorsTask { ID = 11, Subject = "Rollout of New Website and Marketing Brochures", Status = 5, Owner = 1, AssignedEmployee = new[] { 4 } }, new CustomEditorsTask { ID = 12, Subject = "Update Sales Strategy Documents", Status = 5, Owner = 4, AssignedEmployee = new[] { 8 } }, new CustomEditorsTask { ID = 13, Subject = "Create 2012 Sales Report", Status = 5, Owner = 8, AssignedEmployee = new[] { 41 } }, new CustomEditorsTask { ID = 14, Subject = "Direct vs Online Sales Comparison Report", Status = 5, Owner = 41, AssignedEmployee = new[] { 42 } }, new CustomEditorsTask { ID = 15, Subject = "Review 2012 Sales Report and Approve 2013 Plans", Status = 5, Owner = 41, AssignedEmployee = new[] { 4 } }, new CustomEditorsTask { ID = 16, Subject = "Deliver R&D Plans for 2013", Status = 5, Owner = 1, AssignedEmployee = new[] { 3 } }, new CustomEditorsTask { ID = 17, Subject = "Create 2013 R&D Plans", Status = 5, Owner = 3, AssignedEmployee = new[] { 32 } }, new CustomEditorsTask { ID = 18, Subject = "2013 QA Strategy Report", Status = 5, Owner = 32, AssignedEmployee = new[] { 33 } }, new CustomEditorsTask { ID = 19, Subject = "2013 Training Events", Status = 5, Owner = 33, AssignedEmployee = new[] { 31 } }, new CustomEditorsTask { ID = 20, Subject = "Approve Hiring of John Jeffers", Status = 5, Owner = 31, AssignedEmployee = new[] { 5 } }, new CustomEditorsTask { ID = 21, Subject = "Non-Compete Agreements", Status = 5, Owner = 5, AssignedEmployee = new[] { 2 } }, new CustomEditorsTask { ID = 22, Subject = "Update NDA Agreement", Status = 5, Owner = 2, AssignedEmployee = new[] { 1 } }, new CustomEditorsTask { ID = 23, Subject = "Update Employee Files with New NDA", Status = 2, Owner = 2, AssignedEmployee = new[] { 5 } }, new CustomEditorsTask { ID = 24, Subject = "Sign Updated NDA", Status = 5, Owner = 5, AssignedEmployee = new[] { 6 } }, new CustomEditorsTask { ID = 25, Subject = "Sign Updated NDA", Status = 5, Owner = 5, AssignedEmployee = new[] { 7 } }, new CustomEditorsTask { ID = 26, Subject = "Sign Updated NDA", Status = 2, Owner = 5, AssignedEmployee = new[] { 8 } }, new CustomEditorsTask { ID = 27, Subject = "Sign Updated NDA", Status = 4, Owner = 5, AssignedEmployee = new[] { 9 } }, new CustomEditorsTask { ID = 28, Subject = "Submit Questions Regarding New NDA", Status = 5, Owner = 9, AssignedEmployee = new[] { 17 } }, new CustomEditorsTask { ID = 29, Subject = "Submit Questions Regarding New NDA", Status = 5, Owner = 9, AssignedEmployee = new[] { 18 } }, new CustomEditorsTask { ID = 30, Subject = "Submit Questions Regarding New NDA", Status = 2, Owner = 9, AssignedEmployee = new[] { 19 } }, new CustomEditorsTask { ID = 31, Subject = "Submit Signed NDA", Status = 5, Owner = 10, AssignedEmployee = new[] { 14 } }, new CustomEditorsTask { ID = 32, Subject = "Submit Signed NDA", Status = 5, Owner = 10, AssignedEmployee = new[] { 13 } }, new CustomEditorsTask { ID = 33, Subject = "Submit Signed NDA", Status = 5, Owner = 10, AssignedEmployee = new[] { 15 } }, new CustomEditorsTask { ID = 34, Subject = "Submit Signed NDA", Status = 5, Owner = 10, AssignedEmployee = new[] { 16 } }, new CustomEditorsTask { ID = 35, Subject = "Update Revenue Projections", Status = 5, Owner = 1, AssignedEmployee = new[] { 7 } }, new CustomEditorsTask { ID = 36, Subject = "Review Revenue Projections", Status = 5, Owner = 7, AssignedEmployee = new[] { 8 } }, new CustomEditorsTask { ID = 37, Subject = "Comment on Revenue Projections", Status = 5, Owner = 7, AssignedEmployee = new[] { 41 } }, new CustomEditorsTask { ID = 38, Subject = "Comment on Revenue Projections", Status = 5, Owner = 7, AssignedEmployee = new[] { 42 } }, new CustomEditorsTask { ID = 39, Subject = "Comment on Revenue Projections", Status = 3, Owner = 7, AssignedEmployee = new[] { 45 } }, new CustomEditorsTask { ID = 40, Subject = "Provide New Health Insurance Docs", Status = 5, Owner = 11, AssignedEmployee = new[] { 5 } }, new CustomEditorsTask { ID = 41, Subject = "Review Changes to Health Insurance Coverage", Status = 5, Owner = 11, AssignedEmployee = new[] { 10 } }, new CustomEditorsTask { ID = 42, Subject = "Scan Health Insurance Forms", Status = 5, Owner = 10, AssignedEmployee = new[] { 14 } }, new CustomEditorsTask { ID = 43, Subject = "Sign Health Insurance Forms", Status = 5, Owner = 14, AssignedEmployee = new[] { 15 } }, new CustomEditorsTask { ID = 44, Subject = "Sign Health Insurance Forms", Status = 5, Owner = 14, AssignedEmployee = new[] { 13 } }, new CustomEditorsTask { ID = 45, Subject = "Sign Health Insurance Forms", Status = 3, Owner = 14, AssignedEmployee = new[] { 16 } }, new CustomEditorsTask { ID = 46, Subject = "Follow up with West Coast Stores", Status = 4, Owner = 9, AssignedEmployee = new[] { 18 } }, new CustomEditorsTask { ID = 47, Subject = "Follow up with East Coast Stores", Status = 4, Owner = 9, AssignedEmployee = new[] { 17 } }, new CustomEditorsTask { ID = 48, Subject = "Send Email to Customers about Recall", Status = 5, Owner = 9, AssignedEmployee = new[] { 19 } }, new CustomEditorsTask { ID = 49, Subject = "Submit Refund Report for 2013 Recall", Status = 5, Owner = 7, AssignedEmployee = new[] { 9 } }, new CustomEditorsTask { ID = 50, Subject = "Give Final Approval for Refunds", Status = 5, Owner = 7, AssignedEmployee = new[] { 2 } }, new CustomEditorsTask { ID = 51, Subject = "Prepare Product Recall Report", Status = 5, Owner = 3, AssignedEmployee = new[] { 32 } }, new CustomEditorsTask { ID = 52, Subject = "Review Product Recall Report by Engineering Team", Status = 5, Owner = 3, AssignedEmployee = new[] { 1 } }, new CustomEditorsTask { ID = 53, Subject = "Create Training Course for New TVs", Status = 5, Owner = 32, AssignedEmployee = new[] { 31 } }, new CustomEditorsTask { ID = 54, Subject = "Review Training Course for any Ommissions", Status = 5, Owner = 31, AssignedEmployee = new[] { 33 } }, new CustomEditorsTask { ID = 55, Subject = "Review Overtime Report", Status = 5, Owner = 5, AssignedEmployee = new[] { 6 } }, new CustomEditorsTask { ID = 56, Subject = "Submit Overtime Request Forms", Status = 5, Owner = 6, AssignedEmployee = new[] { 21 } }, new CustomEditorsTask { ID = 57, Subject = "Submit Overtime Request Forms", Status = 5, Owner = 6, AssignedEmployee = new[] { 22 } }, new CustomEditorsTask { ID = 58, Subject = "Submit Overtime Request Forms", Status = 5, Owner = 6, AssignedEmployee = new[] { 23 } }, new CustomEditorsTask { ID = 59, Subject = "Overtime Approval Guidelines", Status = 5, Owner = 6, AssignedEmployee = new[] { 2 } }, new CustomEditorsTask { ID = 60, Subject = "Refund Request Template", Status = 3, Owner = 12, AssignedEmployee = new[] { 8 } }, new CustomEditorsTask { ID = 61, Subject = "Recall Rebate Form", Status = 3, Owner = 12, AssignedEmployee = new[] { 8 } }, new CustomEditorsTask { ID = 62, Subject = "Create Report on Customer Feedback", Status = 5, Owner = 30, AssignedEmployee = new[] { 12 } }, new CustomEditorsTask { ID = 63, Subject = "Review Customer Feedback Report", Status = 5, Owner = 30, AssignedEmployee = new[] { 8 } }, new CustomEditorsTask { ID = 64, Subject = "Customer Feedback Report Analysis", Status = 3, Owner = 8, AssignedEmployee = new[] { 1 } }, new CustomEditorsTask { ID = 65, Subject = "Prepare Shipping Cost Analysis Report", Status = 5, Owner = 8, AssignedEmployee = new[] { 10 } }, new CustomEditorsTask { ID = 66, Subject = "Provide Feedback on Shippers", Status = 5, Owner = 10, AssignedEmployee = new[] { 13 } }, new CustomEditorsTask { ID = 67, Subject = "Provide Feedback on Shippers", Status = 5, Owner = 10, AssignedEmployee = new[] { 15 } }, new CustomEditorsTask { ID = 68, Subject = "Provide Feedback on Shippers", Status = 5, Owner = 10, AssignedEmployee = new[] { 16 } }, new CustomEditorsTask { ID = 69, Subject = "Select Preferred Shipper", Status = 5, Owner = 10, AssignedEmployee = new[] { 2 } }, new CustomEditorsTask { ID = 70, Subject = "Complete Shipper Selection Form", Status = 3, Owner = 2, AssignedEmployee = new[] { 1 } }, new CustomEditorsTask { ID = 71, Subject = "Upgrade Server Hardware", Status = 5, Owner = 22, AssignedEmployee = new[] { 6 } }, new CustomEditorsTask { ID = 72, Subject = "Upgrade Personal Computers", Status = 4, Owner = 21, AssignedEmployee = new[] { 6 } }, new CustomEditorsTask { ID = 73, Subject = "Approve Personal Computer Upgrade Plan", Status = 5, Owner = 6, AssignedEmployee = new[] { 2 } }, new CustomEditorsTask { ID = 74, Subject = "Decide on Mobile Devices to Use in the Field", Status = 5, Owner = 6, AssignedEmployee = new[] { 3 } }, new CustomEditorsTask { ID = 75, Subject = "Upgrade Apps to Windows RT or stay with WinForms", Status = 5, Owner = 24, AssignedEmployee = new[] { 6 } }, new CustomEditorsTask { ID = 76, Subject = "Estimate Time Required to Touch-Enable Apps", Status = 5, Owner = 24, AssignedEmployee = new[] { 25 } }, new CustomEditorsTask { ID = 77, Subject = "Report on Tranistion to Touch-Based Apps", Status = 5, Owner = 6, AssignedEmployee = new[] { 23 } }, new CustomEditorsTask { ID = 78, Subject = "Try New Touch-Enabled WinForms Apps", Status = 5, Owner = 6, AssignedEmployee = new[] { 3 } }, new CustomEditorsTask { ID = 79, Subject = "Rollout New Touch-Enabled WinForms Apps", Status = 4, Owner = 6, AssignedEmployee = new[] { 24 } }, new CustomEditorsTask { ID = 80, Subject = "Site Up-Time Report", Status = 5, Owner = 3, AssignedEmployee = new[] { 6 } }, new CustomEditorsTask { ID = 81, Subject = "Review Site Up-Time Report", Status = 5, Owner = 3, AssignedEmployee = new[] { 4 } }, new CustomEditorsTask { ID = 82, Subject = "Review Online Sales Report", Status = 5, Owner = 4, AssignedEmployee = new[] { 1 } }, new CustomEditorsTask { ID = 83, Subject = "Determine New Online Marketing Strategy", Status = 5, Owner = 4, AssignedEmployee = new[] { 8 } }, new CustomEditorsTask { ID = 84, Subject = "New Online Marketing Strategy", Status = 5, Owner = 8, AssignedEmployee = new[] { 42 } }, new CustomEditorsTask { ID = 85, Subject = "Approve New Online Marketing Strategy", Status = 5, Owner = 8, AssignedEmployee = new[] { 4 } }, new CustomEditorsTask { ID = 86, Subject = "Submit New Website Design", Status = 5, Owner = 8, AssignedEmployee = new[] { 28 } }, new CustomEditorsTask { ID = 87, Subject = "Create Icons for Website", Status = 5, Owner = 28, AssignedEmployee = new[] { 29 } }, new CustomEditorsTask { ID = 88, Subject = "Review PSDs for New Website", Status = 5, Owner = 28, AssignedEmployee = new[] { 6 } }, new CustomEditorsTask { ID = 89, Subject = "Create New Shopping Cart", Status = 5, Owner = 6, AssignedEmployee = new[] { 24 } }, new CustomEditorsTask { ID = 90, Subject = "Create New Product Pages", Status = 5, Owner = 6, AssignedEmployee = new[] { 25 } } }; } }
using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic; namespace DevExtreme.NETCore.Demos.Models.DataGrid { public class InMemoryTasksDataContext : InMemoryDataContext<CustomEditorsTask> { public InMemoryTasksDataContext(IHttpContextAccessor contextAccessor, IMemoryCache memoryCache) : base(contextAccessor, memoryCache) { } public ICollection<CustomEditorsTask> Tasks => ItemsInternal; protected override IEnumerable<CustomEditorsTask> Source => SampleData.SampleData.CustomEditorsTasks; protected override int GetKey(CustomEditorsTask item) => item.ID; protected override void SetKey(CustomEditorsTask item, int key) => item.ID = key; } }
.status-icon { height: 16px; width: 16px; display: inline-block; margin-right: 8px; } .middle { vertical-align: middle; }