2

I am implementing Kendo Ui for web with ASP.NET MVC. Below is the code for Kendo UI Grid.

 <div id="grid"></div>

<script>
    $(function () {
        $("#grid").kendoGrid({
            height: 400,
            columns: [
                "Name",
                { field: "Address" },
                { field: "Latitude", width: "150px" },
                { field: "Longitude", width: "150px" },
                { field: "UserId", editor: UserDropDownEditor, title: "User", template: "#=UserName#" },
                { command: "destroy", title: "Delete", width: "110px" }
            ],
            editable: true, // enable editing
            pageable: true,
            sortable: true,
            filterable: true,
            toolbar: ["create", "save", "cancel"], // specify toolbar commands
            dataSource: {
                serverPaging: true,
                serverFiltering: true,
                serverSorting: true,
                pageSize: 10,
                schema: {
                    data: "Data",
                    total: "Total",
                    model: { // define the model of the data source. Required for validation and property types.
                        id: "Id",
                        fields: {
                            Id: { editable: false, nullable: true },
                            Name: { validation: { required: true } },
                            Address: { validation: { required: true } },
                            Latitude: { validation: { required: true } },
                            Longitude: { validation: { required: true } },
                            UserId: { validation: { required: true } }
                        }
                    }
                },
                batch: true, // enable batch editing - changes will be saved when the user clicks the "Save changes" button
                transport: {
                    create: {
                        url: "/Admin/Sites/Create", //specify the URL which should create new records. This is the Create method of the HomeController.
                        type: "POST" //use HTTP POST request as the default GET is not allowed for ASMX
                    },
                    read: {
                        url: "/Admin/Sites/Read", //specify the URL which should return the records. This is the Read method of the HomeController.
                        contentType: "application/json",
                        type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC
                    },
                    update: {
                        url: "/Admin/Sites/Update", //specify the URL which should update the records. This is the Update method of the HomeController.
                        type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC
                    },
                    destroy: {
                        url: "/Admin/Sites/Destroy", //specify the URL which should destroy the records. This is the Destroy method of the HomeController.
                        type: "POST" //use HTTP POST request as by default GET is not allowed by ASP.NET MVC
                    },
                    parameterMap: function (data, operation) {
                        if (operation != "read") {
                            // post the products so the ASP.NET DefaultModelBinder will understand them:

                            // products[0].Name="name"
                            // products[0].ProductID =1
                            // products[1].Name="name"
                            // products[1].ProductID =1

                            var result = {};

                            for (var i = 0; i < data.models.length; i++) {
                                var site = data.models[i];

                                for (var member in site) {
                                    result["sites[" + i + "]." + member] = site[member];
                                }
                            }

                            return result;
                        } else {
                            return JSON.stringify(data)
                        }
                    }
                }
            }
        });

        function UserDropDownEditor(container, options) {
            $('<input required data-text-field="Name" data-value-field="Id" data-bind="value:' + options.field + '"/>')
                .appendTo(container)
                .kendoDropDownList({
                    autoBind: false,
                    dataSource: {
                        transport: {
                            read: "/Admin/Sites/GetUsersList"
                        }
                    }
                });
        }


    });
</script>

This displays the drop down in the grid correctly. But when i update any row by selecting value in dropdown i am not getting the selected value in controller.

[HttpPost]
        public ActionResult Update(IEnumerable<Site> sites)
        {
            try
            {

                //Iterate all updated products which are posted by the Kendo Grid
                foreach (var siteModel in sites)
                {
                    // Create a new Product entity and set its properties from productViewModel
                    var site = db.Sites.Find((int)siteModel.Id);
                    site.Name = siteModel.Name;
                    site.Address = siteModel.Address;
                    site.Latitude = siteModel.Latitude;
                    site.Longitude = siteModel.Longitude;
                    site.UserId = siteModel.UserId;
                    site.ModifiedBy = User.Identity.GetUserId();
                    site.ModifiedOn = DateTime.Now;

                }

                // Save all updated products to the database
                db.SaveChanges();

            }
            catch (DbEntityValidationException e)
            {
                foreach (var eve in e.EntityValidationErrors)
                {
                    Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                        eve.Entry.Entity.GetType().Name, eve.Entry.State);
                    foreach (var ve in eve.ValidationErrors)
                    {
                        Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                            ve.PropertyName, ve.ErrorMessage);
                    }
                }
            }
            //Return emtpy result
            return Json(null);
        }

site.UserId = siteModel.UserId;

This is always null. Can any one point out what is going wrong here.

UPDATE enter image description here

This shows that id is getting passed. but when i try to watch it on server side it is not available.

enter image description here

Sachin Trivedi
  • 2,033
  • 4
  • 28
  • 57

2 Answers2

4

Add the data value primitive attribute:

$('<input required data-text-field="Name" data-value-field="Id" data-value-primitive="true" data-bind="value:' + options.field + '"/>')

See https://medium.com/falafel-software/kendo-ui-mvvm-and-the-primitive-type-value-7d81b4cc31ce

David Clarke
  • 12,888
  • 9
  • 86
  • 116
Steve Greene
  • 12,029
  • 1
  • 33
  • 54
  • One more thing if you can help with. After updating the records the grid is not getting refreshed. The red flag stays in grid even after database is updated correctly. Any suggestion on how to resolve it. ? – Sachin Trivedi Oct 12 '15 at 05:29
  • 1
    See here http://www.telerik.com/forums/refresh-grid-after-datasource-sync or here http://stackoverflow.com/questions/21668018/need-to-refersh-the-kendoui-grid-after-a-ajax-post-callback – Steve Greene Oct 12 '15 at 14:40
  • I found another way. I am returning data from server which were updated successfully. and that works perfectly. Thanks for all your help :) – Sachin Trivedi Oct 13 '15 at 09:39
  • Right, that's what we do for individual updates, but wasn't sure if it would work with a collection. – Steve Greene Oct 13 '15 at 13:41
0

What happens if you give your input a name attribute

$('<input name="UserId" id="UserId" required data-text-field="Name" data-value-field="Id" data-bind="value:' + options.field + '"/>')
JamieD77
  • 13,796
  • 1
  • 17
  • 27
  • tried using something like Fiddler to monitor the traffic and see if UserId is being included in the post? – JamieD77 Oct 07 '15 at 15:32
  • it's treating userid as an object instead of just a guid.. does your `Site` have a User property? – JamieD77 Oct 07 '15 at 16:31
  • i don't have much experience with using just the javascript library in mvc since i just used the mvc extensions instead.. if you look at their demo for custom editor they are using Category object to post back to and not just an Id.. you may need to add a User property to your Site class http://demos.telerik.com/kendo-ui/grid/editing-custom – JamieD77 Oct 07 '15 at 16:36