New to Telerik UI for ASP.NET CoreStart a free 30-day trial

Implementing a Dynamic Grid

Environment

ProductGrid 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:

  1. Basic dynamic Grid binding to DataTable
  2. Dynamic name of column as per model value from backend
  3. Dynamic editing
  4. Bind to a DataTable in a Razor page

Solution

Basic Dynamic Binding

Razor
    @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 a Caption property that can be used to dynamically change the tile of the columns:
Razor
    .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:

Razor
    .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);
            }

        }
    })
  1. You can use IFormCollection to intercept the updated item.

    Inline_Popup
        public ActionResult Customers_Update([DataSourceRequest] DataSourceRequest request, IFormCollection data)
  2. 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:

Razor
    // 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

Razor
    @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

Index.cshtml
    @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.

More ASP.NET Core Grid Resources

See Also