I made a kendo Grid in Razor with dynamic columns and grouping.The Controller successfully fetch records on every condition and pass it as Json Response to kendoGrid. On client side Kendo.all.min.js
gives an error saying Cannot read property 'length' of undefined
.The clue I have in mind is that some column have null record but this grid have more than 150 columns from which selected columns show up.So its quite time taking for me to add one by one each column and test it.
$(document).ready(function () {
@if (!string.IsNullOrEmpty(groupByCol))
{
<text>$("#@ViewData["ReportSection"]ProjectReportGrid").data("kendoGrid").dataSource.group({ field: "@groupByCol", dir: "@groupSort" })</text>
}
var reportName = '@Model.ReportName';
setGridSettings("#@ViewData["ReportSection"]ProjectReportGrid", "@ViewData["ReportSection"]ProjectReportGrid.@Model.ReportName.Replace(" ","")");
});
function @ViewData["ReportSection"]savemysettings() {
SaveGridSettings("#@ViewData["ReportSection"]ProjectReportGrid", "@ViewData["ReportSection"]ProjectReportGrid.@Model.ReportName.Replace(" ", "")");
}
/*No Custom style applied*/
@model ViewModels.ReportingToolPreviewModal
@using Kendo.Mvc.UI
@{
bool Isplanning = ViewData["ReportSection"].ToString() == "Planning";
string groupByCol = Model.SortAndGroup.Select(x => x.FieldLogicalName).FirstOrDefault();
string groupSort = Model.SortAndGroup.Select(x => x.IsDescending).FirstOrDefault() ? "desc" : "asc";
bool calculateTotal = false;
}
@(Html.Kendo().Grid(Model.Projects)
.Name(ViewData["ReportSection"] + "ProjectReportGrid")
.HtmlAttributes(new { @style = "display:inline-block; Width: 100%;" })
.Columns(columns =>
{
...
})
.DataSource(dataSource => dataSource.Ajax().Read(r => r.Action("GetDataForProjectReport", "ReportingTool").Data("{reportId:" + ViewBag.ReportId + ",IsPlanning:'" + Isplanning.ToString() + "'}")).PageSize(100)
.Aggregates(aggregates =>
{
if (calculateTotal)
{
aggregates.Add(p => p.BillCredit).Sum();
aggregates.Add(p => p.BillItemTotalCost).Sum();
aggregates.Add(p => p.TotalBillBudgetItem).Sum();
aggregates.Add(p => p.CangeOrderBudget).Sum();
aggregates.Add(p => p.BudgetCurrentCostBudgetItem).Sum();
aggregates.Add(p => p.BudgetOriginalBudget).Sum();
aggregates.Add(p => p.BudgetTotalBudget).Sum();
//aggregates.Add(p => p.BudgetTotalCostBudgetItem).Sum();
aggregates.Add(p => p.BillItemUnitCost).Sum();
aggregates.Add(p => p.BudgetItemVariance).Sum();
aggregates.Add(p => p.COChangeOrderAmount).Sum();
aggregates.Add(p => p.FinRemainingProfit).Sum();
aggregates.Add(p => p.FinChangeOrderBudgetItem).Sum();
aggregates.Add(p => p.FinChangeOrderAmount).Sum();
aggregates.Add(p => p.FinContractBalance).Sum();
aggregates.Add(p => p.FinDrawsTaken).Sum();
aggregates.Add(p => p.FinEstimatedBudgetItem).Sum();
aggregates.Add(p => p.FinProjectContractAmount).Sum();
aggregates.Add(p => p.FinPaymentReceived).Sum();
aggregates.Add(p => p.FinProjectBankAccount).Sum();
aggregates.Add(p => p.FinRemainingCost).Sum();
aggregates.Add(p => p.FinTotalBudget).Sum();
aggregates.Add(p => p.FinContractAmountTotal).Sum();
aggregates.Add(p => p.FinTotalCost).Sum();
aggregates.Add(p => p.FinProfitTotal).Sum();
aggregates.Add(p => p.FinVariance).Sum();
aggregates.Add(p => p.ProjectContractAmount).Sum();
aggregates.Add(p => p.ProjectContractedAmount).Sum();
aggregates.Add(p => p.ReceivableAmountDue).Sum();
aggregates.Add(p => p.ReceivableAmountPaid).Sum();
aggregates.Add(p => p.ReceivableBalance).Sum();
}
})
)
.Events(x => x.DataBound("AdjustGrid").ColumnShow(ViewData["ReportSection"] + "savemysettings").ColumnResize(ViewData["ReportSection"] + "savemysettings").ColumnLock(ViewData["ReportSection"] + "savemysettings").ColumnUnlock(ViewData["ReportSection"] + "savemysettings").ColumnHide(ViewData["ReportSection"] + "savemysettings"))
.NoRecords(n => n.Template("<B >No records to display</B>"))
.Filterable(ftb => ftb.Mode(GridFilterMode.Row))
.ToolBar(tools => tools.Excel()).Excel(excel => excel.FileName(Model.ReportName + ".xlsx").Filterable(true))
.Sortable()
.Scrollable()
.ColumnMenu(x => x.Filterable(true))
.Reorderable(x => x.Columns(true))
.Resizable(x => x.Columns(true)).Pageable(x => x.PageSizes(new string[] { "25", "50", "100", "All" }).PreviousNext(true).Refresh(true).Numeric(true).Messages(m => m.Display("Total {2} record(s) found!"))))
The problem was that groupByCol
get name of grouping column from model but within the grid that column is not selected.
e.g I made a report which does not include createdDate
column and I select the same column for grouping then Kendo will be unable to get it and throw the exception.
So when I check if groupByCol
is not in selected column I appended the hidden column so that kendo can group the data.
Scenario explained with comments
@if (!string.IsNullOrEmpty(groupByCol)) //here groupByCol='ColumnA'
{
<text>$("#@ViewData["ReportSection"]ProjectReportGrid").data("kendoGrid").dataSource.group({ field: "@groupByCol", dir: "@groupSort" }); //this line causes error as ColumnA is not in the grid</text>
}