Search code examples
kendo-uigridtelerikkendo-gridtelerik-mvc

Telerik MVC Grid Update Dynamic Model


so I have Telerik MVC Grid populated by IEnumerable Model because I'll be adding dynamic product columns on the Grid. Users will be able to edit per row per product and it will be In-cell Batch Editing.

Now, I have this problem on how to fetch the dirty/updated records during save changes. I cant seem to retreive the updated records on when my gridUpdate was called.

@(Html.Kendo().Grid<dynamic>()
.Name("myGrid")
.ToolBar(tootlbar => tootlbar.Save())
.Columns(column =>
{
    column.Bound("Id").Hidden(true);
    column.Bound("LastName");
    column.Bound("FirstName");

    //--Products will be dynamic from Database Table
    column.Bound("ProductA");
    column.Bound("ProductB");
    column.Bound("ProductC");

})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.AutoBind(true)
.DataSource(dataSource => dataSource
    .Ajax()
    .Batch(true)
    .Model(model =>
    {
        model.Id("Id");

        model.Field("Id", typeof(int)).Editable(false);
        model.Field("LastName", typeof(int)).Editable(false);
        model.Field("FirstName", typeof(string)).Editable(false);

        model.Field("ProductA", typeof(string)).Editable(true);
        model.Field("ProductB", typeof(string)).Editable(true);
        model.Field("ProductC", typeof(string)).Editable(true);
    })
    .Read(read => read.Action("gridRead", "myController"))
    .Update(update => update.Action("gridUpdate", "myController"))
))



public JsonResult gridRead([DataSourceRequest] DataSourceRequest request)
    {
        try
        {
            List<dynamic> list = new List<dynamic>();
            
            for(int i = 0; i <= 50; i++)
            {
                dynamic obj = new ExpandoObject();
                obj.Id = i;
                obj.LastName = "Last Name " + i.ToString();
                obj.FirstName = "First Name " + i.ToString();

                //--Products will be dynamic from Database Table
                obj.ProductA = "Product A" + i.ToString();
                obj.ProductB = "Product A" + i.ToString();
                obj.ProductC = "Product A" + i.ToString();

                list.Add(obj);
            }

            return Json(list.ToDataSourceResult(request));
        }
        catch (Exception ex)
        {
            return Json(new DataSourceResult() { Errors = new { Message = "Error: " + ex.Message, ExceptionMessage = ex.Message } });
        }
    }

    public JsonResult gridUpdate([DataSourceRequest] DataSourceRequest request, IEnumerable<dynamic> data)
    {

        foreach(dynamic obj in data)
        {
            //--Always Null --//
            string Id1 = obj.Id; 

            //-- Also always null --//
            string Id2 = GetProperty(obj, "Id"); 
        }

        //--- GET BY ID AND UPDATE RECORD (CODE HERE) --//

        return Json(data.ToDataSourceResult(request));
    }

    private object GetProperty(dynamic obj, string propertyName)
    {
        var objDict = obj as IDictionary<string, object>;
        if (objDict.ContainsKey(propertyName))
        {
            var value = objDict[propertyName];

            if (value != null)
                return value;
        }

        return null;
    }

Solution

  • With batch editing the Grid will submit the updated values with a prefix models, so you can try the following:

     public IActionResult gridUpdate([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")] IFormCollection models)
     {
      ...
     }