Creating a Dynamic Grid with Popup Editing
Environment
Product | Grid for Progress® Telerik® UI for ASP.NET Core |
Description
How can I create a dynamic Telerik UI Grid in ASP.NET Core that uses a custom popup editor template?
Solution
The suggested approach demonstrates how to bind a DataTable
to a Telerik UI Grid and enable the Popup editing.
- Populate the Grid columns based on the available
Model.Columns
.Model.Columns
is the collection of columns of the createdDataTable
. - Set the column title by using the
Caption
property of theDataColumn
. - Activate the Popup editing and specify the name of the custom Popup template:
.Editable(ed => ed.Mode(GridEditMode.PopUp).TemplateName("DynamicPopupEditor"))
. - Define the
Model
in theDataSource
configuration by using theColumnName
andDataType
properties of theDataColumns
. Also, it is important to set the ModelId
to match theDataTable
PrimaryKey
. - Store the
DataTable
Columns
inViewData["modelData"]
to initialize the editors in the Popup form. For more information, refer to theController
in the GitHub project. - Create a View for the editor template in the
~/Views/Shared/EditorTemplates
folder. Ensure that the name of the View matches theTemplateName
specified in the.Editable()
option. - Define an editor for each data type in the editor template and bind the editor to the
Model
property by using thedata-bind
attribute, that is,.HtmlAttributes(new { data_bind= $"value: {dcolumn.ColumnName}" })
.
@model System.Data.DataTable
@(Html.Kendo().Grid<dynamic>()
.Name("Grid")
.Columns(columns =>
{
foreach (System.Data.DataColumn dcolumn in Model.Columns) //Loop through the DataColumns.
{
switch (dcolumn.DataType.ToString())
{
case "System.DateTime":
columns.Bound(dcolumn.ColumnName).Title(dcolumn.Caption).Format("{0:d}"); //If the column DataType is "DateTime", format the date by using the Format() method.
break;
default:
columns.Bound(dcolumn.ColumnName).Title(dcolumn.Caption);
break;
}
}
columns.Command(com => com.Edit());
})
.Pageable()
.Sortable()
.Editable(ed => ed.Mode(GridEditMode.PopUp).TemplateName("DynamicPopupEditor")) //Specify the name of the custom Popup template ("~/Views/Shared/EditorTemplates/DynamicPopupEditor.cshtml").
.Filterable()
.Groupable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
var id = Model.PrimaryKey[0].ColumnName;
model.Id(id); //Set the Model Id
foreach (System.Data.DataColumn column in Model.Columns)
{
var field = model.Field(column.ColumnName, column.DataType);
if (column.ColumnName == id) {
field.Editable(false);
}
}
})
.Read(read => read.Action("Customers_Read", "DynamicPopupEditing"))
.Update(read => read.Action("Customers_Update", "DynamicPopupEditing"))
)
)
public class DynamicPopupEditingController : Controller
{
public static DataTable db = new DataTable();
public ActionResult DynamicPopupEditing()
{
db = GetDataTable(50);
List<System.Data.DataColumn> columnData = new List<System.Data.DataColumn>();
foreach(System.Data.DataColumn colData in db.Columns)
{
columnData.Add(colData);
}
ViewData["modelData"] = columnData;
return View(db);
}
public ActionResult Customers_Read([DataSourceRequest] DataSourceRequest request)
{
return Json(db.ToDataSourceResult(request));
}
}
<div class="k-edit-form-container">
@{ foreach (System.Data.DataColumn dcolumn in ViewData["modelData"] as IList<System.Data.DataColumn>) //Loop through the DataColumns and create the editors based on the column DataType.
{
<div class="k-edit-label">
<label for="@dcolumn.ColumnName">@dcolumn.ColumnName</label>
</div>
switch (dcolumn.DataType.ToString())
{
case "System.Int16":
case "System.Int32":
case "System.Int64":
bool eidtor_enabled = true;
if(dcolumn.ColumnName == "OrderID")
{
eidtor_enabled = false;
}
<div class="k-edit-field">
@(Html.Kendo().IntegerTextBox()
.Name($"{dcolumn.ColumnName}")
.HtmlAttributes(new { data_bind= $"value: {dcolumn.ColumnName}" })
.Min(int.MinValue)
.Max(int.MaxValue)
.Enable(eidtor_enabled)
)
</div>
break;
case "System.Decimal":
case "System.Double":
case "System.Float":
<div class="k-edit-field">
@(Html.Kendo().NumericTextBox()
.Name($"{dcolumn.ColumnName}")
.HtmlAttributes(new { style = "width:100%", data_bind = $"value: {dcolumn.ColumnName}" })
)
</div>
break;
case "System.String":
<div class="k-edit-field">
@(Html.Kendo().TextBox()
.Name($"{dcolumn.ColumnName}")
.HtmlAttributes(new { style = "width:100%", data_bind = $"value: {dcolumn.ColumnName}" })
)
</div>
break;
case "System.Byte":
case "System.Boolean":
<div class="k-edit-field">
@(Html.Kendo().CheckBox()
.Name($"{dcolumn.ColumnName}")
.HtmlAttributes(new { style = "width:100%", data_bind = $"checked: {dcolumn.ColumnName}" })
)
</div>
break;
case "System.DateTime":
<div class="k-edit-field">
@(Html.Kendo().DateTimePicker()
.Name($"{dcolumn.ColumnName}")
.HtmlAttributes(new { style = "width:100%", data_bind = $"value: {dcolumn.ColumnName}" })
)
</div>
break;
default:
<div class="k-edit-field">
@(Html.Kendo().TextBox()
.Name($"{dcolumn.ColumnName}")
.HtmlAttributes(new { style = "width:100%", data_bind = $"value: {dcolumn.ColumnName}" })
)
</div>
break;
}
}
}
</div>
For the complete implementation of the suggested approach, refer to this GitHub project.