Filtering and Editing a ForeignKey Column Bound to an Enum Field in Grid
Environment
Product | Telerik UI for ASP.NET Core Grid |
Product Version | 2024.4.1112 |
Description
How can I bind a Grid to a ForeignKey column and ensure that the names of enum members are displayed in the column's filter menu? Also, how to use a DropDownList editor for the enum field when the Grid enters edit mode?
Solution
When binding a ForeignKey column to an enum Model property, convert the enum members to a SelectListItem
data collection.
-
Binding the ForeignKey column to a local collection:
@(Html.Kendo().Grid<GridModel>() .Name("grid") .Columns(columns => { columns.ForeignKey(p => p.Status, (System.Collections.IEnumerable)ViewData["statuses"], "Value", "Text") .Filterable(x => x.Extra(false).Operators(operators => operators.ForEnums(str => str.Clear().IsEqualTo("Equals")))); }) ...// Additional configuration. )
@addTagHelper *, Kendo.Mvc <kendo-grid name="grid"> <columns> <foreign-key-column field="Status" values='(System.Collections.IEnumerable)ViewData["statuses"]' value-field="Value" text-field="Text"> <filterable enabled="true" extra="false"> <operators> <enums eq="Equals"/> </operators> </filterable> </foreign-key-column> </columns> <!-- Additional configuration --> </kendo-grid>
public IActionResult GridPage() // The Action method that returns the View with the Grid. { var enumList = EnumToSelectList(typeof(ShipmentStatus)); // Parse the enum members to List<SelectListItem>. ViewData["statuses"] = enumList; return View(); } public static List<SelectListItem> EnumToSelectList(Type enumType) { return Enum .GetValues(enumType) .Cast<int>() .Select(i => new SelectListItem { Value = i.ToString(), Text = Enum.GetName(enumType, i), } ) .ToList(); }
public class GridModel { public ShipmentStatus Status { get; set; } } public enum ShipmentStatus { [Display(Name = "In Process")] InProcess = 1, [Display(Name = "In Transit")] InTransit = 2, [Display(Name = "Received")] Received = 3, [Display(Name = "Lost In Shipment")] LostInShipment = 4 }
-
Binding the ForeignKey column to remote data:
@(Html.Kendo().Grid<GridModel>() .Name("grid") .Columns(columns => { columns.ForeignKey(p => p.Status, ds => ds.Read(r => r.Action("ReadStatuses", "Home")), "Value", "Text") .Filterable(x => x.Extra(false).Operators(operators => operators.ForEnums(str => str.Clear().IsEqualTo("Equals")))); }) ...// Additional configuration. )
@addTagHelper *, Kendo.Mvc <kendo-grid name="grid"> <columns> <foreign-key-column field="Status" value-field="Value" text-field="Text"> <datasource> <transport> <read url="@Url.Action("ReadStatuses", "Home")"/> </transport> </datasource> <filterable enabled="true" extra="false"> <operators> <enums eq="Equals"/> </operators> </filterable> </foreign-key-column> </columns> <!-- Additional configuration --> </kendo-grid>
public ActionResult ReadStatuses() { var enumList = EnumToSelectList(typeof(ShipmentStatus)); return Json(enumList); } public static List<SelectListItem> EnumToSelectList(Type enumType) { return Enum .GetValues(enumType) .Cast<int>() .Select(i => new SelectListItem { Value = i.ToString(), Text = Enum.GetName(enumType, i), } ) .ToList(); }
public class GridModel { public ShipmentStatus Status { get; set; } } public enum ShipmentStatus { [Display(Name = "In Process")] InProcess = 1, [Display(Name = "In Transit")] InTransit = 2, [Display(Name = "Received")] Received = 3, [Display(Name = "Lost In Shipment")] LostInShipment = 4 }
When the Grid is InCell or InLine editable, the Grid will look for the default GridForeignKey.cshtml
editor template in the ~Views\Shared\EditorTemplates folder, and populate it with the passed data collection through the column declaration:
@model object
@(Html.Kendo().DropDownListFor(m => m)
.BindTo((SelectList)ViewData[ViewData.TemplateInfo.GetFullHtmlFieldName("")+ "_Data"])
)
When the Grid is configured for Popup editng, decorate the Model property with the UIHint
attribute and add a DropDownList editor to the ~Views\Shared\EditorTemplates folder.
using System.ComponentModel.DataAnnotations;
public class GridModel
{
[UIHint("EnumEditor")]
public ShipmentStatus Status { get; set; }
}
// ~Views\Shared\EditorTemplates\EnumEditor.cshtml
@model ShipmentStatus
@(Html.Kendo().DropDownListFor(m => m)
.BindTo(EnumToSelectList(typeof(ShipmentStatus)))
)