I'm developing a project with ASP MVC 5, Kendo UI, and some layers, but I'm struggling with how to display the drop-down list inside of an editable Grid, I followed this example:
However, I'm having serious issues because the drop-down list never appears, it's displaying two text boxes.
Also, if I run the Foreign Key column example:
I have a different result with a numeric up-down:
Besides, I tested this example from StackOverflow and the result is either two textboxes or the numeric up-down (it depends if I bound the column or I use the foreign key column):
dropdownlist in kendo grid not working
This is my code, in the Business Layer, I have these classes in order to return the Categories from the database:
using Test.DB.Operations;
using System.Collections.Generic;
using System.Linq;
namespace Test.Business
{
public class Category
{
public int ID { get; set; }
public string Name { get; set; }
}
public class CategoryData
{
public static List<Category> GetCategories()
{
var catData = DatabaseService.GetEntities<DB.Category>().ToList();
return (from cData in catData select new Category() { ID = cData.ID, Name = cData.Name }).ToList();
}
}
}
Later, in my MVC Layer, the Controller populates the view with some methods like these ones:
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using Test.Business;
using Test.Classes;
using Test.MVC.Classes;
using Test.MVC.Models;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
namespace Test.MVC.Controllers
{
public class OrganizationDetailsController : Controller
{
public ActionResult Index(string ID)
{
PopulateCategories();
if (!string.IsNullOrEmpty(ID))
{
var model = new OrganizationsModel();
try
{
model.hasError = false;
model.messageBox = null;
}
catch (Exception ex)
{
model.hasError = true;
model.messageBox = new Tuple<string, string>("Error", "Please report it to the team");
}
return View(model);
}
else
{
return View();
}
}
public ActionResult OrganizationDetails_Read([DataSourceRequest]DataSourceRequest request, string ID)
{
try
{
var data = OrganizationDetailsData.GetOrganizationDetails(ID);
DataSourceResult result = data.ToDataSourceResult(request);
return Json(result);
}
catch (Exception ex)
{
return null;
}
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult OrganizationDetails_Update([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]<OrganizationDetails> oDetails)
{
return null;
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult OrganizationDetails_Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<OrganizationDetails> oDetails)
{
return null;
}
private void PopulateCategories()
{
var dataContext = CategoryData.GetCategories();
ViewData["categories"] = dataContext;
ViewData["defaultCategory"] = dataContext[0];
}
}
}
The Model looks like this:
using Test.Business;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Test.MVC.Models
{
public class OrganizationsModel
{
public Tuple<string, string> messageBox;
public bool hasError;
}
}
Finally, in the View, I have this code for the Kendo Grid:
@(Html.Kendo().Grid<Test.Business.OrganizationDetails>()
.Name("gridDetails")
.Columns(columns =>
{
columns.Bound(b => b.Name);
columns.Bound(b => b.NumberOfEmployees);
//columns.ForeignKey(p => p.CategoryID, (System.Collections.IEnumerable)ViewData["categories"], "ID", "Name").Title("Categories").EditorTemplateName("dropdownTemplate");
columns.Bound(b => b.Category).ClientTemplate("#=Category.Name#");
columns.Bound(p => p.Telephone);
columns.Bound(p => p.Address);
})
.ToolBar(toolBar =>
{
toolBar.Create();
toolBar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Sortable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Events(events => events.Error("error_handler"))
.Model(model =>
{
model.Id(p => p.ID);
model.Field(p => p.ID).Editable(false);
model.Field(p => p.Category).DefaultValue(ViewData["defaultCategory"] as Test.Business.Category);
})
.PageSize(20)
.Read(read => read.Action("OrganizationDetails_Read", "OrganizationDetails").Data("LoadParams"))
.Create(create => create.Action("OrganizationDetails_Create", "Grid"))
.Update(update => update.Action("Organization_Update", "Grid"))
)
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
)
<input type="hidden" id="orgID" value="1" />
<script id="dropdownTemplate" type="text/x-kendo-template">
@(Html.Kendo().DropDownListFor(m => m)
.Name("myDropDown")
.DataValueField("ID")
.DataTextField("Name")
.BindTo((System.Collections.IEnumerable)ViewData["categories"])
)
</script>
<script type="text/javascript">
function error_handler(e) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
}
function LoadParams() {
var id = $("#orgID").val();
return { ID: id }
}
</script>
However, it's never working as it should be. Does anyone have experience this issue? And how did you manage it? Thanks for your ideas.
For the ForeignKey() implementation:
you have to put the "dropdownTemplate" in a cshtml file in Views/Shared/EditorTemplates. You cannot use a x-kendo-template because you are not using javascript initialization...you are using the razor helpers. What is likely happening to your is that you are specifying an non-existent EditorTemplate(no cshtml in Shared/EditorTemplates) so it just breaks.
Or, you can leave off the EditorTemplateName() altogether and Kendo will automatically use the EditorTemplate in Views/Shared/EditorTemplates/GridForeignKey.cshtml.
For the "ClientTemplate" implementation:
If you take a look at the full source code for the "Grid Editing / custom editor" example(in the examples that get installed with Kendo MVC), the EditorTemplate is specified using a UIHint on the model. i.e. (using your classnames)
public class OrganizationDetails
{
...
[UIHint("ClientCategory")]
public CategoryViewModel Category {get; set;}
}
Then there must be a ClientCategory.cshtml file in Views/Shared/EditorTemplates that contains the razor for your editor implementation.
In the Kendo examples, ClientCategory.cshtml contains:
@model Kendo.Mvc.Examples.Models.CategoryViewModel
@(Html.Kendo().DropDownListFor(m => m)
.DataValueField("CategoryID")
.DataTextField("CategoryName")
.BindTo((System.Collections.IEnumerable)ViewData["categories"])
)