65.9K
CodeProject is changing. Read more.
Home

Dynamic Number of Columns Generating at Runtime Using WebGrid

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3 votes)

Jul 14, 2016

CPOL

3 min read

viewsIcon

19447

To show a list of records without knowing number of columns using WebGrid

Introduction

This article is about showing a different kind of list in single view page. Basically, we know the structure. Based on that, we will design the HTML tables. But here, we don't know the structure of the list so we are creating everything in runtime using the WebGrid Html Helpers.

Using the Code

For an example, I have created two different classes and fill some data to display in an HTML Table. The two classes are StudentModelClass and EmployeeClass.

Creating Data To Display

The StudentModelClass contains the Student information - they are student id, name, age and phone number. FillData method is given list of StudentModelClass information.

    public class StudentModelClass
    {
        public int studentId { get; set; }
        public string studentName { get; set; }
        public int studentAge { get; set; }
        public string studentPhno { get; set; }

        //Filling The Records in Student List
        public static List<StudentModelClass> FillData()
        {
            List<StudentModelClass> stuList = new List<StudentModelClass>();
            stuList.Add(new StudentModelClass() { studentId = 1, 
            studentName = "Dinesh", studentPhno = "9884562624", studentAge = 23 });
            stuList.Add(new StudentModelClass() { studentId = 2, 
            studentName = "Kishor", studentPhno = "9262498845", studentAge = 23 });
            stuList.Add(new StudentModelClass() { studentId = 3, 
            studentName = "Aravind", studentPhno = "9262988454", studentAge = 23 });
            return stuList;
        }
    }

The EmployeeClass contains the Employee information. They are employee id, name and date of joining. FillData method is given list of EmployeeClass information.

    public class EmployeeClass
    {
        public int EmpId { get; set; }
        public string EmpName { get; set; }
        public DateTime Doj { get; set; }

        //Filling The Records in Employee List
        public static List<EmployeeClass> FillData()
        {
            List<EmployeeClass> stuList = new List<EmployeeClass>();
            stuList.Add(new EmployeeClass() { EmpId = 101, 
            EmpName= "Dinesh", Doj = Convert.ToDateTime("09/09/2016") });
            stuList.Add(new EmployeeClass() { EmpId = 102, 
            EmpName = "Maha", Doj = Convert.ToDateTime("02/01/2016") });
            stuList.Add(new EmployeeClass() { EmpId = 103, 
            EmpName = "Kishor", Doj = Convert.ToDateTime("01/02/2016") });
            stuList.Add(new EmployeeClass() { EmpId = 104, 
            EmpName = "Naveen", Doj = Convert.ToDateTime("08/01/2016") });           
            return stuList;
        }
    }

Model Class

Now, I have created the common model class named as WebGridClass for showing the list. This class contains:

  1. List<dynamic> GridData --> list of object which it supports to all the class.
  2. list of WebGridColumn --> this list of webgridcolumn shows columns.
  3. Title --> Title of the list, to display in webpage.
  4. KeyField --> It is the column name of object which contains unique value. To identify the records from list (For example: In StudentModelClass, we identify the records based on studentId and EmployeeClass, we identify the records based on EmployeeId).

It contains a method name as GetDetailsForGrid<T>(). This method is used to Get the list of column name, additionally create a column, converting a common List<dynamic> type and hold the data in static variables.

    public class WebGridClass 
    {
        public List<dynamic> GridData = new List<dynamic>();
        public List<WebGridColumn> ColNames = new List<WebGridColumn>();
        public string Title { get; set; }
        public string KeyField { get; set; }

        // Holding the data 
        public static WebGridClass HoldWebGridDetails = new WebGridClass();

        public static void GetDetailsForGrid<T>(List<T> list, string Title, string KeyField)
        {
            WebGridClass objWeb = new WebGridClass();

            //Get Properties
            var properties = typeof(T).GetProperties();
                            
            //Add New Column With A link
            objWeb.ColNames.Add(new WebGridColumn() { Header = "Action", 
            ColumnName = KeyField, Format = item => new MvcHtmlString
            ("<a href='Edit?id=" + item[KeyField] + "'>Edit</a>") });            
            objWeb.ColNames.AddRange(properties.Select(s => new WebGridColumn() 
            { Header = s.Name, ColumnName = s.Name, CanSort = true }).ToList());

            //Convert The data into the List<dynamic.
            objWeb.GridData = list.Cast<dynamic>().ToList();
            objWeb.Title = Title;

            //Holding The Values.???
            HoldWebGridDetails = objWeb;
        }
    }

Explanation Of GetDetailsForGrid<T> Method

The have created the one generic method named as GetDetailsForGrid<T>. The T stands for the class object. it used to:

  1. Read the properties from the T object.
    var properties = typeof(T).GetProperties();
  2. Create a new column for action link with the keyfield value & add into WedGridClass ColNames property:
    objWeb.ColNames.Add(new WebGridColumn() 
    { Header = "Action", ColumnName = KeyField, Format = item => new MvcHtmlString
    ("<a href='Edit?id=" + 
    item[KeyField] + "'>Edit</a>") });
  3. Convert the column name into the WebGridColumn and make it as WebGridColumnList & add into WedGridClass ColNames property.
    objWeb.ColNames.AddRange(properties.Select(s => new WebGridColumn() 
    { Header = s.Name, ColumnName = s.Name, CanSort = true }).ToList());
  4. Convert the List<T> to dynamic list & add into WedGridClass GridData property.
    objWeb.GridData = list.Cast<dynamic>().ToList();
  5. Store the title in webgrid into WedGridClass Title property.
    objWeb.Title = Title;
  6. Store the WebGridClass into the static variable for holding the data in memory.
    HoldWebGridDetails = objWeb;

Now whenever we call this method, it will store the information into the static variables.

Controller

Here, I have 3 action results the index() action result is common to display a data in view and other 2 action results is get the result and redirect into the Index() action result.

        public ActionResult Index()
        {
            var data = new WebGridClass();
            data = WebGridClass.HoldWebGridDetails;
            return View(data);
        }

        public ActionResult StudentDetails() 
        {
            //Retrieve Student List
            var data = new List<StudentModelClass>();
            data = StudentModelClass.FillData();

            //Passing The List<StudentModelClass> 
            //to List<Dynamic> and Fill the WebGridClass class
            WebGridClass.GetDetailsForGrid(data, "Student List", "studentId");
            return RedirectToAction("Index");               
        }

        public ActionResult EmployeeDetails() 
        {
            //Retrieve Employee List
            var data = new List<EmployeeClass>();
            data = EmployeeClass.FillData();
            
            //Passing The List<EmployeeClass> to List<Dynamic> and Fill the WebGridClass class
            WebGridClass.GetDetailsForGrid(data, "Employee List", "EmpId");
            return RedirectToAction("Index");               
        }

In the StudentDetails method, just fill and pass the records to WebGridClass.GetDetailsForGrid and redirect into the index ActionResult. The same thing happens in EmployeeDetails ActionResult. Now the Index ActionResult processes the data which is stored in static variable.

Index View Page

The View page is displaying the data:

@model MVCArchitecture.Models.WebGridClass
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@Model.Title</title>
</head>
<body>
    <h2>@Model.Title</h2>   
            @{
                var grid = new WebGrid(source: Model.GridData, 
                canSort: true, ajaxUpdateContainerId: "tableId", rowsPerPage: 3);
            }
            @grid.GetHtml(
                         htmlAttributes: new { id = "tableId" },
                tableStyle: "wGrid",
                headerStyle: "wGridHeader",
                alternatingRowStyle: "alt",
                selectedRowStyle: "select",
                columns: Model.ColNames
            )    
</body>
</html>

It just display the records, and title using WebGrid HTML Helpers.

Output

The below screenshots display the output:

Points of Interest

Usually, in many places, we show the list of records so each and every time we are creating a program for different kinds of data in views. In this case, we are able to reduce the size of the program and it's very easy to use.