11
votes

I am trying to build a very simple Kendo CRUD grid with a table that has only two columns: ID and Name. I have configured the grid with serverside pagination and serverside filtering.

Everything seems to function as expected but after the new record is created, the grid shows the new record but without the ID field. On creation, the request has ID null but I am sending the value of id and the full object after creation. In example grids, the grid is updated with new values. What do I need to change / add to ensure that the ID of the newly created record shows up in Grid as well?

Following is the JSP:

        <script>


        $(function() {
            var dataSource =  new kendo.data.DataSource({
                transport: {
                    read: {
                        url:"http://localhost:8181/baseweb/countrylist",
                        dataType: "jsonp"
                    },
                    update: {
                        url: "http://localhost:8181/baseweb/countryupdate",
                        dataType: "jsonp"
                    },    
                    destroy: {
                        url: "http://localhost:8181/baseweb/countrydelete",
                        dataType: "jsonp"
                    }, 
                    create: {
                        url: "http://localhost:8181/baseweb/countrycreate",
                        dataType: "jsonp"
                    },                        
                    parameterMap: function(data, operation) {
                        if (operation !== "read" && data.models) {
                            return {grid_options: kendo.stringify(data.models)};
                        }
                        return {grid_options: kendo.stringify(data)};
                    }                       
                },
                serverPaging: true,
                serverFiltering: true,
                pageSize: 10,
                schema: {
                    data: "data",        
                    total: "total",                     
                    model: {
                        id: "id",
                        fields: {
                            id: { editable: false, nullable: true },
                            name: { validation: { required: true } }                                
                        }

                    }
                }                   
        });

            $("#grid").kendoGrid({
                dataSource: dataSource,
                pageable: true,
                filterable: true,
                height: 400,  
                toolbar: ["create"],                    
                columns: [
                          { field: "id", title:"Identification"}, 
                          { field: "name", title:"Country Name" },
                          { command: ["edit", "destroy"], title: "&nbsp;", width: "160px" }
                          ],
                editable: "popup"           
            });
        });

    </script> 

Parameter Sent to the server on create: _ 1380846899054 callback jQuery19108827040256333442_1380846899052 grid_options {"id":null,"name":"testing"}

Parameter sent back from server as response: jQuery19108827040256333442_1380846899052([ {"id":"4028828f4180d64a014180e3bda20002","name":"testing"}])

I am expecting that the ID sent back by server should be displayed in the Grid. I have searched this forum, Kendo documentation and Google for an answer but I am unable to find a solution.

What am I missing?


Update with Solution:

Jack's answer provided the clue to finding the solution. I was making two mistakes:

a. The callback in Kendo Grid seems to expect the data back in a "data:" attribute. I was not naming the result set as "data:" in my response. b. The callback also expects a JSONArray of objects in the data: attribute. I was sending a JSONObject since I was only creating one object.

After I changed the response to include data: attribute and JSONArray, it works perfectly. The request parameter from the client looks like this:

_   1386350196768
callback    jQuery19101285024500179227_1386350196765
grid_options    {"id":null,"name":"Ghana"}

The edited response looks like this:

jQuery19101285024500179227_1386350196765( {"data":[{"id":"2c9323ca42c8df630142c944450b0002","name":"Ghana"}]})

Hope it helps someone else as this is not clearly documented in the official documentation.

2
Did you ever figure this out? I am having the same issue, the ID I am returning is not set in the clients dataset, thus leaving it as a "new" item. Messes up all operations thereafter (create, update, delete).Jack
Your answer helped me figure out the solution. Thank you. I will post my own answer to ensure that it is properly documented for others.sohail

2 Answers

6
votes

I've had the same problem and think I may have found the answer. If in the schema you define the object that holds the results, you must return the result of the created link in that same object. Example:

schema: {
         data: "data",        
         total: "total",  .... 
 }

Example MVC method:

public JsonResult CreateNewRow(RowModel rowModel)
{
    // rowModel.id will be defaulted to 0

    // save row to server and get new id back
    var newId = SaveRowToServer(rowModel);

    // set new id to model
    rowModel.id = newId;

    return Json(new {data= new[] {rowModel}});
}
12
votes

There is a nice clean way of doing this...

If your grid is created in script block:

dataSource: {
    transport: {
        read: {
            url: "..."
        },
        create: {
            url: "...",
            type: "POST",
            complete: function(e) {
                $("#grid").data("kendoGrid").dataSource.read(); 
        }
    },
}...

OR in HTML

@(Html.Kendo().Grid<ViewModel>()
  .Name("grid")
  .DataSource(dataSource => dataSource
      .Ajax()
      .PageSize(10)
      .Model(model =>
        {
            model.Id(i => i.Cde);
            model.Field(i => i.Description).Editable(true);
        })
      .Read(read => read.Action("EditingInline_Read", "UserGroups"))
      .Update(update => update.Action("EditingInline_Update", "UserGroups")).Read("EditingInline_Read", "UserGroups")
      .Destroy(delete => delete.Action("EditingInline_Delete", "UserGroups"))
      .Create(create => create.Action("EditingInline_Create", "UserGroups")).Read("EditingInline_Read", "UserGroups")
   )
  .Columns(columns =>
  {
      columns.Bound(s => s.Decription);
      columns.Bound(s => s.enabled);
      columns.Command(command => { command.Edit(); command.Destroy(); }).Width(200);
  })
  .Pageable()
  .Sortable()
  .Selectable(selectable => selectable
        .Mode(GridSelectionMode.Single))
  .ToolBar(toolbar => toolbar.Create()))

Check out the CRUD calls, more specific, Update and Create.