Editing Grid with Cascading DropDownLists
Environment
Product | Telerik UI for ASP.NET Core Grid, Telerik UI for ASP.NET Core DropDownList |
Description
How can I implement cascading DropDownLists for editing rows in Telerik UI for ASP.NET Core Grid component?
Solution
The Grid supports three editing modes—InCell, InLine, and PopUp. Typically, for cascading components to function correctly, all related components must be rendered simultaneously.
InLine and PopUp Edit Mode
For InLine and PopUp editing modes, refer to the Handle Cascading DropDownLists within the Grid article.
InCell Edit Mode
When using InCell edit mode, a single cell can be edited at a time. For this reason, to use cascading DropDownLists as editors in the Grid, follow the next steps:
-
Define at least two
ForeignKey
columns:Razor@model ForeignKeyValues @(Html.Kendo().Grid<License>() .Name("Grid") .Columns(columns => { columns.ForeignKey(p => p.CustomerId, Model.Customers, "CustomerId", "CustomerName").Width(300); columns.ForeignKey(p => p.VendorId, Model.Vendors, "VendorId", "VendorName").Width(300); columns.ForeignKey(p => p.ProductId, Model.Products, "ProductId", "ProductName").Width(300); }) ... // Additional configuration. )
-
Decorate each Model property with the
UIHint
Data Annotation attribute to speify the name of the view that contains the custom editor (for example, the DropDownList).C#public class License { [Required(ErrorMessage = "LicenseId is required")] public int LicenseId { get; set; } [UIHint("CustomerId")] [Required(ErrorMessage = "CustomerId is required")] public int CustomerId { get; set; } [UIHint("VendorId")] [Required(ErrorMessage = "VendorId is required")] public int VendorId { get; set; } [UIHint("ProductId")] [Required(ErrorMessage = "ProductId is required")] public int ProductId { get; set; } }
-
Add a view for each editor in the
Views/Shared/EditorTemplates
folder. Ensure that the names of the views match the specified names in theUIHint
attributes.CustomerId
DropDownList:
Razor@using Kendo.Mvc.UI @model int @(Html.Kendo().DropDownListFor(m => m) .ValuePrimitive(true) .OptionLabel("Select Customer...") .DataTextField("CustomerName") .DataValueField("CustomerId") .DataSource(dataSource => { dataSource.Read(read => read.Action("GetCustomers", "Home")) .ServerFiltering(true); }) ) @Html.ValidationMessageFor(m => m)
VendorId
DropDownList:
Razor@using Kendo.Mvc.UI @model int @(Html.Kendo().DropDownListFor(m => m) .AutoBind(false) .ValuePrimitive(true) .OptionLabel("Select Vendor...") .DataTextField("VendorName") .DataValueField("VendorId") .DataSource(dataSource => { dataSource.Read(read => read.Action("GetVendors", "Home").Data("filterVendors")) .ServerFiltering(true); }) .CascadeFrom("CustomerId") ) @Html.ValidationMessageFor(m => m)
ProductId
DropDownList:
Razor@using Kendo.Mvc.UI @model int @(Html.Kendo().DropDownListFor(m => m) .AutoBind(false) .ValuePrimitive(true) .OptionLabel("Select Product...") .DataTextField("ProductName") .DataValueField("ProductId") .DataSource(dataSource => { dataSource.Read(read => read.Action("GetProducts", "Home").Data("filterProducts")) .ServerFiltering(true); }) .CascadeFrom("VendorId") ) @Html.ValidationMessageFor(m => m)
-
Include the
filterVendors()
andfilterProducts()
JavaScript functions that send the value of the parent DropDownList to the server in the main view, where the Grid is defined.JS<script> function getCurrentEditedModel() { var grid = $("#Grid").data("kendoGrid"); var editRow = grid.tbody.find("tr:has(.k-edit-cell)"); return grid.dataItem(editRow); } function filterVendors() { var model = getCurrentEditedModel(); return { customerId: model.CustomerId }; } function filterProducts() { var model = getCurrentEditedModel(); return { vendorId: model.VendorId }; } </script>
-
Handle the
Change
event of the DataSource and manually reset the value of the cascaded field when the parent field is updated:JS<script> function onChange(e) { if (e.action == "itemchange") { if (e.field == "CustomerId") { var model = e.items[0]; model.set("VendorId", 0); } if (e.field == "VendorId") { var model = e.items[0]; model.set("ProductId", 0); } } } </script>
To see the complete example, refer to the ASP.NET MVC project on how to configure the InCell editable Grid to handle its cascading DropDownList editors. You can use this as a starting point to configure the same behavior in an ASP.NET Core project.