Dynamic Number of Columns Generating at Runtime Using WebGrid





5.00/5 (3 votes)
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:
List<dynamic> GridData
--> list of object which it supports to all the class.list of WebGridColumn
--> this list ofwebgridcolumn
shows columns.Title
--> Title of the list, to display in webpage.KeyField
--> It is the column name of object which contains unique value. To identify the records from list (For example: InStudentModelClass
, we identify the records based onstudentId
andEmployeeClass
, we identify the records based onEmployeeId
).
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:
- Read the
properties
from theT
object.var properties = typeof(T).GetProperties();
- Create a new column for action link with the
keyfield
value & add intoWedGridClass ColNames
property:objWeb.ColNames.Add(new WebGridColumn() { Header = "Action", ColumnName = KeyField, Format = item => new MvcHtmlString ("<a href='Edit?id=" + item[KeyField] + "'>Edit</a>") });
- Convert the column name into the
WebGridColumn
and make it asWebGridColumnList
& add intoWedGridClass ColNames
property.objWeb.ColNames.AddRange(properties.Select(s => new WebGridColumn() { Header = s.Name, ColumnName = s.Name, CanSort = true }).ToList());
- Convert the
List<T>
to dynamic list & add intoWedGridClass GridData
property.objWeb.GridData = list.Cast<dynamic>().ToList();
- Store the title in
webgrid
intoWedGridClass Title
property.objWeb.Title = Title;
- Store the
WebGridClass
into thestatic
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.