New to Telerik UI for ASP.NET CoreStart a free 30-day trial

Editing Grid with Cascading DropDownLists

Environment

ProductTelerik 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:

  1. 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.
    )
  2. 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; }
    }
  3. Add a view for each editor in the Views/Shared/EditorTemplates folder. Ensure that the names of the views match the specified names in the UIHint 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)
  4. Include the filterVendors() and filterProducts() 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>
  5. 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.

More ASP.NET Core Grid Resources

See Also