Badhon Jain
Badhon Jain

Reputation: 1007

How to pass batch data to controller action from kendo UI grid in case of batch editing?

I'm trying to implement the kendo grid in my mvc 3 apps. I'm interested in batch editing. I need to send batch data from view to controller action method.

Here is my code for view:

<!DOCTYPE html>
<html>
<head>
<title>
    This is Home!!
</title>

<link href="../../Content/kendo/2013.1.319/kendo.common.min.css" rel="stylesheet" />

<link href="../../Content/kendo/2013.1.319/kendo.metro.min.css" rel="stylesheet" />
<script src="../../Scripts/jquery-2.0.2.min.js"></script>
<script src="../../Scripts/kendo/2013.1.319/kendo.web.min.js"></script>

<script type="text/javascript">


    var dataSource = new kendo.data.DataSource({
        schema: {
            model: {
                id: "EmployeeID",
                fields: {
                    EmployeeID: { editable: false, nullable: true },
                    EmployeeName: { validation: { required: true } }

                }
            }
        },
        transport: {
            read: {
                url: "/Home/GetData",
                type: "GET"
            },
            update: {
                url: "/Home/Update",
                type: "POST",
                contentType: 'application/json'
            },
            destroy: {
                url: "/Home/Destroy",
                type: "POST"
            },


            create: {
                url: "/Home/Create",
                type: "POST",
                contentType: 'application/json'
            },


            pageSize: 20,


            parameterMap: function (options, operation) {
                if (operation !== "read" && options.models) {
                    return { models: kendo.stringify(options.models) };
                }
            }
        }

    });





    $(document).ready(function () {


        $("#grid").kendoGrid({
            dataSource: dataSource,
            navigatable: true,
            pageable: true,
            height: 430,
            sortable: true,
            toolbar: ["create", "save", "cancel"],
            columns: [

                { field: "EmployeeID", title: "Employee ID", width: 110 },
                { field: "EmployeeName", title: "Employee Name", width: 110 },

                { command: "destroy", title: "Delete", width: 90 }],
            editable: true,
            selectable: "multiple row",
            groupable: true,
            navigatable: true
        });
    });



</script>

</head>
<body>

<div id="example" class="k-content">
    <div id="grid"></div>

</div>

</body>
</html>

Controller code:

 [HttpPost]
 public JsonResult Update(List<Employee> model) //Parameter gets no data.
 {
     var obj = new Employee();
     //return View();
     return Json(obj);
 }

//Parameter gets no data.
[HttpPost]
public ActionResult Create(List<Employee> model) 
{
   return View("Index");
}

if I'm not wrong, I'm doing something wrong in parameter mapping or the signature of the action method, can't figure out what? Please help. Thanks.

Upvotes: 1

Views: 10103

Answers (3)

Andrew Sin
Andrew Sin

Reputation: 93

Try:

Set in transport 'update' content type header to:

'contentType: "application/json; charset=utf-8",'

And use in parameterMap option either:

return kendo.stringify({ models: options.models });

or

return JSON.stringify({ models: options.models });

Upvotes: 0

RJohn
RJohn

Reputation: 121

I had the same issue and tried every option I found on the web the only one that worked for me was this

public ActionResult Products_Update([DataSourceRequest]DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<ProductViewModel> products)
{
    // Will keep the updated entitites here. Used to return the result later.
    var entities = new List<Product>();
    if (ModelState.IsValid)
    {
        using (var northwind = new NorthwindEntities())
        {
            foreach (var product in products)
            {
                // Create a new Product entity and set its properties from the posted ProductViewModel.
                var entity = new Product
                {
                    ProductID = product.ProductID,
                    ProductName = product.ProductName,
                    UnitsInStock = product.UnitsInStock
                };
                // Store the entity for later use.
                entities.Add(entity);
                // Attach the entity.
                northwind.Products.Attach(entity);
                // Change its state to Modified so Entity Framework can update the existing product instead of creating a new one.
                northwind.Entry(entity).State = EntityState.Modified;
                // Or use ObjectStateManager if using a previous version of Entity Framework.
                // northwind.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
            }
            // Update the entities in the database.
            northwind.SaveChanges();
        }
    }
    // Return the updated entities. Also return any validation errors.
    return Json(entities.ToDataSourceResult(request, ModelState, product => new ProductViewModel
    {
        ProductID = product.ProductID,
        ProductName = product.ProductName,
        UnitsInStock = product.UnitsInStock
    }));
}

This example I've pulled from Telerik site http://docs.telerik.com/aspnet-mvc/helpers/grid/editing/batch-editing

Upvotes: 0

OnaBai
OnaBai

Reputation: 40917

What you are doing wrong is that you did not say that it needs to be batch so you are actually sending the data to the server as soon as you finish editing the EmployeeName (exit edit mode) but your parameterMap function is incorrect when sending in non-batch mode because then there is no model in options (just directly the data).

So, either add batch: true to the DataSoure definition (if you want to go in batch mode):

var dataSource = new kendo.data.DataSource({
    batch: true,
    schema: {
        model: {
            id: "EmployeeID",
            fields: {
                EmployeeID: { editable: false, nullable: true },
                EmployeeName: { validation: { required: true } }

            }
        }
    },
    ...

or change parameter map to return options (only if you don't want to go with batch):

parameterMap: function (options, operation) {
    if (operation !== "read") {
        return options;
    }
}

Upvotes: 2

Related Questions