Implementing a Dynamic Grid
Environment
Product | Grid for Progress® Telerik® UI for ASP.NET Core |
Description
I am trying to bind a DataTable to a Telerik UI for ASP.NET Core Grid. The main reason for this is that the grid needs to be dynamic with a different number of columns etc. Although I've seen an example of this is MVC, I can't get this to work in ASP.NET Core. I need help with:
- Basic dynamic Grid binding to DataTable
- Dynamic name of column as per model value from backend
- Dynamic editing
- Bind to a DataTable in a Razor page
Solution
Basic Dynamic Binding
@model System.Data.DataTable
@(Html.Kendo().Grid<dynamic>()
.Name("Grid")
.Columns(columns =>
{
foreach (System.Data.DataColumn column in Model.Columns)
{
var c = columns.Bound(column.ColumnName);
}
})
.Pageable()
.Sortable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
foreach (System.Data.DataColumn column in Model.Columns)
{
var field = model.Field(column.ColumnName, column.DataType);
}
})
.Read(read => read.Action("Customers_Read", "Grid"))
)
)
Dynamic Column Titles
- The
System.Data.DataColumn
has aCaption
property that can be used to dynamically change the tile of the columns:
.Columns(columns =>
{
foreach (System.Data.DataColumn column in Model.Columns)
{
var c = columns.Bound(column.ColumnName).Title(column.Caption);
}
})
Dynamic Editing
Since the dynamic editing is not part of the official built-in options which utilized strongly typed models for ASP.NET Core, there are different solutions that can be applied. For a runnable example go to the examples repository. View.cshtml and Controller.
The first thing is to add the model Id - the primary key of the table and define the editors based on the column types:
.Model(model =>
{
var id = Model.PrimaryKey[0].ColumnName;
model.Id(id);
foreach (System.Data.DataColumn column in Model.Columns)
{
var field = model.Field(column.ColumnName, column.DataType);
if (column.ColumnName == id) {
field.Editable(false);
}
}
})
-
You can use
IFormCollection
to intercept the updated item.Inline_Popuppublic ActionResult Customers_Update([DataSourceRequest] DataSourceRequest request, IFormCollection data)
-
Alternatively, you can post the model and values to the controller in a preferred format for you, so that you can process them on the server and update the corresponding table accordingly.
For example in a grid with inline editing shared by another programmer with us:
// grid Save event and editable mode
.Events(events => events.Save("savePopUpChange"))
.Editable(ed=>ed.Mode(GridEditMode.PopUp))
// data source Update method with additional data sent
.Update(update => update.Action("Metadata_Update", "KendoGrid").Data("updateValuesData"))
<script>
var keyValueList = [];
function savePopUpChange(e) {
keyValueList.push(keyValuePair);
var inputs = e.container.find("input");
for (var i = 0; i < inputs.length; i++) {
var element = inputs[i];
var keyValuePair = element.name + ":" + element.value;
keyValueList.push(keyValuePair);
}
}
function updateValuesData(e) {
return { keyValueList: keyValueList.join("|") }
}
</script>
To define editors based on a condition, you can use a switch case as shown below
@model System.Data.DataTable
@(Html.Kendo().Grid<dynamic>()
.Name("gridMetadata")
.Columns(columns =>
{
foreach (System.Data.DataColumn dcolumn in Model.ViewDataTable.Columns)
{
switch (dcolumn.DataType.ToString())
{
case "System.Int16":
case "System.Int32":
case "System.Int64":
columns.Bound(dcolumn.ColumnName).Title(dcolumn.Caption).EditorTemplateName("Integer");
break;
case "System.Decimal":
case "System.Double":
case "System.Float":
columns.Bound(dcolumn.ColumnName).Title(dcolumn.Caption).EditorTemplateName("Number");
break;
case "System.String":
columns.Bound(dcolumn.ColumnName).Title(dcolumn.Caption).EditorTemplateName("String");
break;
case "System.Byte":
case "System.Boolean":
columns.Bound(dcolumn.ColumnName).Title(dcolumn.Caption).EditorTemplateName("Boolean");
break;
case "System.DateTime":
columns.Bound(dcolumn.ColumnName).Title(dcolumn.Caption).Format("{0:d}").EditorTemplateName("Date");
break;
default:
columns.Bound(dcolumn.ColumnName).Title(dcolumn.Caption).EditorTemplateName("String");
break;
}
}
columns.Command(command => {command.Edit();});
}).
Dynamic Grid In Razor Page
@Html.AntiForgeryToken()
<script>
function sendTokens() {
return kendo.antiForgeryTokens();
}
</script>
@(Html.Kendo().Grid<dynamic>()
.Name("Grid")
.Columns(columns =>
{
foreach (System.Data.DataColumn column in Model.DataTable.Columns)
{
var c = columns.Bound(column.ColumnName);
}
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
foreach (System.Data.DataColumn column in Model.DataTable.Columns)
{
var field = model.Field(column.ColumnName, column.DataType);
}
})
.Read(read => read.Url("/Customer?handler=Read").Data("sendTokens"))
)
)
For a runnable example of a dynamic Grid with editing, check the UI for ASP.NET Core Examples.