Adding simple dropdown to grid?

1 Answer 64 Views
DropDownList Grid
Kevin
Top achievements
Rank 2
Iron
Iron
Iron
Kevin asked on 17 Feb 2022, 05:41 PM

I've read the examples, and I've followed along as best as I can, but I'm still having an issue getting a simple dropdown into my grid (ASP.NET MVC)

I have a model called Supplier, and a model called VehicleType

    

public class Supplier { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Display(Name = "Id")] public int SupplierId { get; set; } [Display(Name = "Supplier Number")] public int SupplierNumber { get; set; } [Display(Name = "Name")] public string SupplierName { get; set; } [Display(Name = "Vehicle Type Id")] public int VehicleTypeId { get; set; } [Display(Name = "Status Id")] public int StatusId { get; set; }

// I added this [NotMapped] [UIHint("VehicleType")] public VehicleType VehicleType { get; set; } } public class VehicleType { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int VehicleTypeId { get; set; } public string VehicleTypeName { get; set; } }

My Grid is as follows:

@(Html.Kendo().Grid<MyProject.Models.Schedule.Supplier>
    ()
    .Name("grid")
    .Columns(columns =>
    {
        columns.Select().Width(50);
        columns.Bound(p => p.SupplierNumber).Filterable(ftb => ftb.Multi(true));
        columns.Bound(p => p.SupplierName).Groupable(true).Filterable(ftb => ftb.Multi(true));
        //columns.Bound(p => p.VehicleTypeId).Filterable(ftb => ftb.Multi(true));
        columns.Bound(p => p.VehicleType).ClientTemplate("#=VehicleType.VehicleTypeName#").Sortable(false);

    })
    .Pageable()
    .Sortable()
    .ToolBar(toolBar =>
    {
        toolBar.Create();
        toolBar.Save();
    })
    .Editable(editable => editable.Mode(GridEditMode.InCell))
    .PersistSelection()
    .Scrollable()
    .Groupable()
    .Filterable()
    .HtmlAttributes(new { style = "height:600px;" })
    .Resizable(r => r.Columns(true))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model => model.Id(p => p.SupplierId))
        .PageSize(100)
        .Events(events => events.Error("error_handler"))
        .Read(read => read.Action("GetSuppliers", "Schedule"))
        .Update(update => update.Action("EditSupplier", "Schedule"))
        .Create(create => create.Action("CreateSupplier", "Schedule"))
    )
    )

My controller looks like this:

        // View for the page
        public ActionResult Supplier()
        {
            ViewData["vehicleTypes"] = new Models.MyContext()
                .vehicleTypes
                .Select(v => new VehicleType
                {
                    VehicleTypeId = v.VehicleTypeId,
                    VehicleTypeName = v.VehicleTypeName
                })
                .OrderBy(v => v.VehicleTypeName);

            return View();
        }

        // Using this to get the data for the grid
        public ActionResult GetSuppliers([DataSourceRequest] DataSourceRequest request)
        {
            List<Models.Schedule.Supplier> result = MyLogic.suppliers();
            return Json(result.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
        }

And finally I created an EditorTemplate called VehicleType.cshtml

@(Html.Kendo().DropDownList()
        .Name("VehicleType") 
        .DataValueField("VehicleTypeId")
        .DataTextField("VehicleTypeName")
        .BindTo((System.Collections.IEnumerable)ViewData["vehicleTypes"])
    )

When I try to view the grid I get this error:

The entity or complex type 'MyProject.Models.VehicleType' cannot be constructed in a LINQ to Entities query.

After some googling, I changed my ViewData lookup in my controller to this:

Which displays my grid (empty though there should be 31 rows) and the console has the following error:

Uncaught TypeError: Cannot read properties of null (reading 'VehicleTypeName')
    at eval (eval at compile (kendo.all.js:241:30), <anonymous>:3:3673)
    at init._rowsHtml (kendo.all.js:74650:37)
    at init._renderContent (kendo.all.js:75513:34)
    at init.refresh (kendo.all.js:75329:22)
    at init.d (jquery.min.js:2:3873)
    at init.trigger (kendo.all.js:171:37)
    at init._process (kendo.all.js:8341:22)
    at init.success (kendo.all.js:8037:22)
    at success (kendo.all.js:7928:42)
    at Object.n.success (kendo.all.js:6762:25)

Can someone point me in the right direction here? 

Without trying to add the dropdown, it all works as expected, but I'd rather not have to type in the id values when editing/creating a row

I've been bashing my head against the wall for it for a couple of hours now, so any kind of help would be greatly appreciated.

Thanks

 

1 Answer, 1 is accepted

Sort by
1
Accepted
Anton Mironov
Telerik team
answered on 22 Feb 2022, 01:22 PM

Hello Kevin,

Thank you for the code snippets and details provided.

I tried to replicate the behavior locally and found what is causing the issue. Your implementation is perfect except for one little thing. 

You are binding the values of the DropDownLists with the ViewBag out of the box. The question is if you are populating the dataItemswith "VehicleType" when binding the Grid. If no - then the currently edited dataItem has VehicleType = null and a JavaScipt error when trying to find the "VehicleTypeName" of a null for the ClientTemplate.

Here is an example of populating the values for the DropDown:

        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            List<VehicleType> vehicleTypes = new List<VehicleType>();

            for (int i = 1; i < 11; i++)
            {
                vehicleTypes.Add(new VehicleType { VehicleTypeId = i, VehicleTypeName = "VehicleName " + i });

            }

            ViewData["vehicleTypes"] = vehicleTypes;

            return View();
        }
The following snippet demonstrates the populating of the dataItems for the Grid:
		public ActionResult Orders_Read([DataSourceRequest]DataSourceRequest request)
		{

			var result = Enumerable.Range(1, 11).Select(i => new OrderViewModel
			{
				OrderID = i,
				Freight = i * 10,
				OrderDate = DateTime.Now.AddDays(i),
				ShipName = "ShipName " + i,
				ShipCity = "ShipCity " + i,
				VehicleType = new VehicleType { VehicleTypeId = i, VehicleTypeName = "VehicleName " + i}
			});

			return Json(result.ToDataSourceResult(request));
		}
Attached is a sample project that I prepared for the case. It implements the approach above.

Make the needed tests locally with the project attached and let me know if further assistance is needed.

Looking forward to hearing back from you.

Kind Regards,
Anton Mironov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Kevin
Top achievements
Rank 2
Iron
Iron
Iron
commented on 22 Feb 2022, 01:52 PM

Thanks Anton,

I was thinking the VehicleTypeId would be able to link across to it, but if I populate VehicleType in my data then it works

 

Appreciate the help!

Kevin
Top achievements
Rank 2
Iron
Iron
Iron
commented on 22 Feb 2022, 02:10 PM

One quick follow-up.

In your project here, if I add a toolbar with a Create new record button, I get the following when I try to use it.

 

Only change I made was this:


            .ToolBar(toolBar =>
            {
                toolBar.Create();
                toolBar.Save();
            })

 

Anton Mironov
Telerik team
commented on 25 Feb 2022, 12:28 PM

H Kevin,

Thank you for the details provided.

The pointed issue is caused by the missing default option for the "VehicleType" as this text is pointing in the following demo:

"Specify a default value that will be used initially when creating an item:

model.Field(p => p.Category).DefaultValue(ViewData["defaultCategory"] as Kendo.Mvc.Examples.Models.CategoryViewModel);"

Give a try at the approach from the demo above and let me know if further assistance is needed.

Looking forward to hearing back from you.

Best Regards,
Anton Mironov

Tags
DropDownList Grid
Asked by
Kevin
Top achievements
Rank 2
Iron
Iron
Iron
Answers by
Anton Mironov
Telerik team
Share this question
or