Hello,
For a project I am working on I have a kendo grid that does server side paging. We have been able to get it to work with searching and sorting, but when we try to add in .Groupable() and drag a field to be grouped by, we just get a spinning circle with the javascript error message:
Cannot read property 'length' of undefined
We return the type DataSourceResult from the controller, which I have noticed does not have any fields for grouping information. Should we be returning a different data type? Or perhaps we need a different approach all together?
Here is my grid:
@(Html.Kendo().Grid<UserViewModel>()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Read", "Users").Data("getSearchData"))
.PageSize(20)
)
.Columns(columns =>
{
columns.Bound(o => o.UserName);
columns.Bound(o => o.Name);
columns.Bound(o => o.Email);
columns.Bound(o => o.Status);
columns.Bound(o => o.OrganizationRoles).Title("Roles");
columns.Bound(o => o.Href)
.ClientTemplate("<a href=\"/Users/Edit?href=${Href}&previousPage=/Users\" data-icon=\"e\" class=\"btn btn-icon\"></a>" +
"<a href=\"/Users/Delete?href=${Href}&previousPage=/Users\" data-icon=\"x\" data-Id=\"1\" class=\"btn btn-icon delete-role\"></a>")
.Title("Actions").Sortable(false);
})
.Pageable()
.Groupable()
.Sortable(sortable => sortable
.Enabled(true)
.AllowUnsort(false)
.SortMode(GridSortMode.SingleColumn))
.Deferred()
)
<script>
require(['/Content/js/config.js'], function () {
require(['jquery', 'lib/kendo/kendo.grid.min', 'lib/kendo/kendo.aspnetmvc.min'], function ($, kendogrid, kendomvc) {
@Html.Kendo().DeferredScriptsFor("grid", false)
$(".k-link").bind("click", function(e) {
$('#grid').data('kendoGrid').dataSource.page(1);
});
$('#SearchString').keyup(function(event) {
if (event.keyCode == 13) {
$('#SearchButton').click();
}
});
$("#SearchButton").click(
function () {
$('#grid').data('kendoGrid').dataSource.fetch();
$('#grid').data('kendoGrid').dataSource.page(1);
});
function getSearchData() {
// Reserved property names
// used by DataSourceRequest: sort, page, pageSize, group, filter
return {
SearchString: $("#SearchString").val(),
SearchTypeSelected: $("#SearchTypeSelected").val(),
//...
};
};
});
});
</script>
And here is the controller code:
public ActionResult Read([DataSourceRequest] DataSourceRequest request, TSearchViewModel queryModelInput)
{
var pagingLinks = (List<Link>)TempData["Links"];
if (pagingLinks != null && pagingLinks.FirstOrDefault() != null && !pagingLinks.FirstOrDefault().Href.StartsWith(ListHref))
{
TempData["PriorGridState"] = null;
TempData["Links"] = null;
}
var priorGridState = TempData["PriorGridState"] as GridState;
var gridState = new GridState(request, queryModelInput, TempData["Links"] as List<Link>, ListHref);
// figure out what api call needed based on how the grid has changed
var gridComparisonResult = gridState.CompareTo(priorGridState);
if (gridComparisonResult.GoToPageOne)
{
request.Page = 1;
}
var href = gridComparisonResult.NextHref;
var result = GetDataResult(href, request); // may need to use extension method .ToDataSourceResult()?
TempData["PriorGridState"] = gridState;
return Json(result, JsonRequestBehavior.AllowGet);
}
public virtual DataSourceResult GetDataResult(string href, DataSourceRequest request)
{
if (String.IsNullOrEmpty(href))
{
href = ListHref;
}
var representation = HalClient.Get<PagedHalListViewModel<TInfoViewModel, Links>>(href);
TempData["Links"] = representation.Links.ToList();
var result = new DataSourceResult();
try
{
result.Data = representation.ResourceList;
result.Total = representation.TotalResults;
result.Data.ToDataSourceResult(request);
} catch (Exception)
{
result.Total = 0;
}
return result;
}
Any recommendations of how I should proceed here? I am happy to provide any additional information you might require to answer the question. And remember, everything works except for the grouping.
Thanks,
Danny
For a project I am working on I have a kendo grid that does server side paging. We have been able to get it to work with searching and sorting, but when we try to add in .Groupable() and drag a field to be grouped by, we just get a spinning circle with the javascript error message:
Cannot read property 'length' of undefined
We return the type DataSourceResult from the controller, which I have noticed does not have any fields for grouping information. Should we be returning a different data type? Or perhaps we need a different approach all together?
Here is my grid:
@(Html.Kendo().Grid<UserViewModel>()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Read", "Users").Data("getSearchData"))
.PageSize(20)
)
.Columns(columns =>
{
columns.Bound(o => o.UserName);
columns.Bound(o => o.Name);
columns.Bound(o => o.Email);
columns.Bound(o => o.Status);
columns.Bound(o => o.OrganizationRoles).Title("Roles");
columns.Bound(o => o.Href)
.ClientTemplate("<a href=\"/Users/Edit?href=${Href}&previousPage=/Users\" data-icon=\"e\" class=\"btn btn-icon\"></a>" +
"<a href=\"/Users/Delete?href=${Href}&previousPage=/Users\" data-icon=\"x\" data-Id=\"1\" class=\"btn btn-icon delete-role\"></a>")
.Title("Actions").Sortable(false);
})
.Pageable()
.Groupable()
.Sortable(sortable => sortable
.Enabled(true)
.AllowUnsort(false)
.SortMode(GridSortMode.SingleColumn))
.Deferred()
)
<script>
require(['/Content/js/config.js'], function () {
require(['jquery', 'lib/kendo/kendo.grid.min', 'lib/kendo/kendo.aspnetmvc.min'], function ($, kendogrid, kendomvc) {
@Html.Kendo().DeferredScriptsFor("grid", false)
$(".k-link").bind("click", function(e) {
$('#grid').data('kendoGrid').dataSource.page(1);
});
$('#SearchString').keyup(function(event) {
if (event.keyCode == 13) {
$('#SearchButton').click();
}
});
$("#SearchButton").click(
function () {
$('#grid').data('kendoGrid').dataSource.fetch();
$('#grid').data('kendoGrid').dataSource.page(1);
});
function getSearchData() {
// Reserved property names
// used by DataSourceRequest: sort, page, pageSize, group, filter
return {
SearchString: $("#SearchString").val(),
SearchTypeSelected: $("#SearchTypeSelected").val(),
//...
};
};
});
});
</script>
And here is the controller code:
public ActionResult Read([DataSourceRequest] DataSourceRequest request, TSearchViewModel queryModelInput)
{
var pagingLinks = (List<Link>)TempData["Links"];
if (pagingLinks != null && pagingLinks.FirstOrDefault() != null && !pagingLinks.FirstOrDefault().Href.StartsWith(ListHref))
{
TempData["PriorGridState"] = null;
TempData["Links"] = null;
}
var priorGridState = TempData["PriorGridState"] as GridState;
var gridState = new GridState(request, queryModelInput, TempData["Links"] as List<Link>, ListHref);
// figure out what api call needed based on how the grid has changed
var gridComparisonResult = gridState.CompareTo(priorGridState);
if (gridComparisonResult.GoToPageOne)
{
request.Page = 1;
}
var href = gridComparisonResult.NextHref;
var result = GetDataResult(href, request); // may need to use extension method .ToDataSourceResult()?
TempData["PriorGridState"] = gridState;
return Json(result, JsonRequestBehavior.AllowGet);
}
public virtual DataSourceResult GetDataResult(string href, DataSourceRequest request)
{
if (String.IsNullOrEmpty(href))
{
href = ListHref;
}
var representation = HalClient.Get<PagedHalListViewModel<TInfoViewModel, Links>>(href);
TempData["Links"] = representation.Links.ToList();
var result = new DataSourceResult();
try
{
result.Data = representation.ResourceList;
result.Total = representation.TotalResults;
result.Data.ToDataSourceResult(request);
} catch (Exception)
{
result.Total = 0;
}
return result;
}
Any recommendations of how I should proceed here? I am happy to provide any additional information you might require to answer the question. And remember, everything works except for the grouping.
Thanks,
Danny