Create Custom Table For HTML Helper in MVC

Here's how to create a custom table for HTML helper in MVC.

Step 1

Create database and new project in Visual Studio.

Step 2

In Solution Explorer select Model and add a new Item.

Step 3

Select ADO.NET Entity Data model, then press Add.

Step 4

Select Generate from database and press Next.

Step 5

Select Yes from Drop down and press Next.

Step 6

Select the table you need and press Finish.

Step 7

Model1.edmx is created in the model. Now we can use this model in the View and the Controller to perform the Insert, Update and Delete operation. Here's Model1.edmx, save and close it.

table design

Step 8

For more details on insert, update and delete you can visit my previous blog.

Step 9

Now in Solution Explorer, right-click on the project, then add new folder named "HtmlHelpers" and create one class file named "MvcHtmlExtensions".

MvcHtmlExtensions

Step 10

The following is the code for the class MvcHtmlExtensions.cs.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Linq.Expressions;  
  5. using System.Text;  
  6. using System.Text.RegularExpressions;  
  7. using System.Web;  
  8. using System.Xml;  
  9.   
  10. namespace System.Web.Mvc.Html {#region TableColumn  
  11.   
  12.     /// <summary>    
  13.     /// Properties and methods used within the TableBuilder class.    
  14.     /// </summary>    
  15.     public interface ITableColumnInternal < TModel > where TModel: class {  
  16.         string ColumnTitle {  
  17.             get;  
  18.             set;  
  19.         }  
  20.         string Evaluate(TModel model);  
  21.     }  
  22.   
  23.     /// <summary>    
  24.     /// Properties and methods used by the consumer to configure the TableColumn.    
  25.     /// </summary>    
  26.     public interface ITableColumn {  
  27.         ITableColumn Title(string title);  
  28.     }  
  29.   
  30.     /// <summary>    
  31.     /// Represents a column in a table.    
  32.     /// </summary>    
  33.     /// <typeparam name="TModel">Class that is rendered in a table.</typeparam>    
  34.     /// <typeparam name="TProperty">Class property that is rendered in the column.</typeparam>    
  35.     public class TableColumn < TModel,  
  36.     TProperty > : ITableColumn,  
  37.     ITableColumnInternal < TModel > where TModel: class {  
  38.         /// <summary>    
  39.         /// Column title to display in the table.    
  40.         /// </summary>    
  41.         public string ColumnTitle {  
  42.             get;  
  43.             set;  
  44.         }  
  45.   
  46.         /// <summary>    
  47.         /// Compiled lambda expression to get the property value from a model object.    
  48.         /// </summary>    
  49.         public Func < TModel, TProperty > CompiledExpression {  
  50.             get;  
  51.             set;  
  52.         }  
  53.   
  54.         /// <summary>    
  55.         /// Constructor.    
  56.         /// </summary>    
  57.         /// <param name="expression">Lambda expression identifying a property to be rendered.</param>    
  58.         public TableColumn(Expression < Func < TModel, TProperty >> expression) {  
  59.             string propertyName = (expression.Body as MemberExpression).Member.Name;  
  60.             this.ColumnTitle = Regex.Replace(propertyName, "([a-z])([A-Z])""$1 $2");  
  61.             this.CompiledExpression = expression.Compile();  
  62.         }  
  63.   
  64.         /// <summary>    
  65.         /// Set the title for the column.    
  66.         /// </summary>    
  67.         /// <param name="title">Title for the column.</param>    
  68.         /// <returns>Instance of a TableColumn.</returns>    
  69.         public ITableColumn Title(string title) {  
  70.             this.ColumnTitle = title;  
  71.             return this;  
  72.         }  
  73.   
  74.         /// <summary>    
  75.         /// Get the property value from a model object.    
  76.         /// </summary>    
  77.         /// <param name="model">Model to get the property value from.</param>    
  78.         /// <returns>Property value from the model.</returns>    
  79.         public string Evaluate(TModel model) {  
  80.             var result = this.CompiledExpression(model);  
  81.             return result == null ? string.Empty : result.ToString();  
  82.         }  
  83.     }  
  84.  
  85.     #endregion TableColumn  
  86.  
  87.     #region ColumnBuilder  
  88.   
  89.     /// <summary>    
  90.     /// Create instances of TableColumns.    
  91.     /// </summary>    
  92.     /// <typeparam name="TModel">Type of model to render in the table.</typeparam>    
  93.     public class ColumnBuilder < TModel > where TModel: class {  
  94.         public TableBuilder < TModel > TableBuilder {  
  95.             get;  
  96.             set;  
  97.         }  
  98.   
  99.         /// <summary>    
  100.         /// Constructor.    
  101.         /// </summary>    
  102.         /// <param name="tableBuilder">Instance of a TableBuilder.</param>    
  103.         public ColumnBuilder(TableBuilder < TModel > tableBuilder) {  
  104.             TableBuilder = tableBuilder;  
  105.         }  
  106.   
  107.         /// <summary>    
  108.         /// Add lambda expressions to the TableBuilder.    
  109.         /// </summary>    
  110.         /// <typeparam name="TProperty">Class property that is rendered in the column.</typeparam>    
  111.         /// <param name="expression">Lambda expression identifying a property to be rendered.</param>    
  112.         /// <returns>An instance of TableColumn.</returns>    
  113.         public ITableColumn Expression < TProperty > (Expression < Func < TModel, TProperty >> expression) {  
  114.             return TableBuilder.AddColumn(expression);  
  115.         }  
  116.     }  
  117.  
  118.     #endregion ColumnBuilder  
  119.  
  120.     #region TableBuilder  
  121.   
  122.     /// <summary>    
  123.     /// Properties and methods used by the consumer to configure the TableBuilder.    
  124.     /// </summary>    
  125.     public interface ITableBuilder < TModel > where TModel: class {  
  126.         TableBuilder < TModel > DataSource(IEnumerable < TModel > dataSource);  
  127.         TableBuilder < TModel > Columns(Action < ColumnBuilder < TModel >> columnBuilder);  
  128.     }  
  129.   
  130.     /// <summary>    
  131.     /// Build a table based on an enumerable list of model objects.    
  132.     /// </summary>    
  133.     /// <typeparam name="TModel">Type of model to render in the table.</typeparam>    
  134.     public class TableBuilder < TModel > : ITableBuilder < TModel > where TModel: class {  
  135.         private HtmlHelper HtmlHelper {  
  136.             get;  
  137.             set;  
  138.         }  
  139.         private IEnumerable < TModel > Data {  
  140.             get;  
  141.             set;  
  142.         }  
  143.   
  144.         /// <summary>    
  145.         /// Default constructor.    
  146.         /// </summary>    
  147.         private TableBuilder() {}  
  148.   
  149.         /// <summary>    
  150.         /// Constructor.    
  151.         /// </summary>    
  152.         internal TableBuilder(HtmlHelper helper) {  
  153.             this.HtmlHelper = helper;  
  154.   
  155.             this.TableColumns = new List < ITableColumnInternal < TModel >> ();  
  156.         }  
  157.   
  158.         /// <summary>    
  159.         /// Set the enumerable list of model objects.    
  160.         /// </summary>    
  161.         /// <param name="dataSource">Enumerable list of model objects.</param>    
  162.         /// <returns>Reference to the TableBuilder object.</returns>    
  163.         public TableBuilder < TModel > DataSource(IEnumerable < TModel > dataSource) {  
  164.             this.Data = dataSource;  
  165.             return this;  
  166.         }  
  167.   
  168.         /// <summary>    
  169.         /// List of table columns to be rendered in the table.    
  170.         /// </summary>    
  171.         internal IList < ITableColumnInternal < TModel >> TableColumns {  
  172.             get;  
  173.             set;  
  174.         }  
  175.   
  176.         /// <summary>    
  177.         /// Add an lambda expression as a TableColumn.    
  178.         /// </summary>    
  179.         /// <typeparam name="TProperty">Model class property to be added as a column.</typeparam>    
  180.         /// <param name="expression">Lambda expression identifying a property to be rendered.</param>    
  181.         /// <returns>An instance of TableColumn.</returns>    
  182.         internal ITableColumn AddColumn < TProperty > (Expression < Func < TModel, TProperty >> expression) {  
  183.             TableColumn < TModel, TProperty > column = new TableColumn < TModel, TProperty > (expression);  
  184.             this.TableColumns.Add(column);  
  185.             return column;  
  186.         }  
  187.   
  188.         /// <summary>    
  189.         /// Create an instance of the ColumnBuilder to add columns to the table.    
  190.         /// </summary>    
  191.         /// <param name="columnBuilder">Delegate to create an instance of ColumnBuilder.</param>    
  192.         /// <returns>An instance of TableBuilder.</returns>    
  193.         public TableBuilder < TModel > Columns(Action < ColumnBuilder < TModel >> columnBuilder) {  
  194.             ColumnBuilder < TModel > builder = new ColumnBuilder < TModel > (this);  
  195.             columnBuilder(builder);  
  196.             return this;  
  197.         }  
  198.   
  199.         /// <summary>    
  200.         /// Convert the TableBuilder to HTML.    
  201.         /// </summary>    
  202.         public MvcHtmlString ToHtml(string id, string CssClass, string EditPath, string DeletePath) {  
  203.   
  204.             var table = new TagBuilder("table");  
  205.             table.GenerateId(id);  
  206.             table.AddCssClass(CssClass);  
  207.   
  208.             //For Declaration Of All Require Tag...!!!    
  209.             TagBuilder thead = new TagBuilder("thead");  
  210.             TagBuilder tr = new TagBuilder("tr");  
  211.             TagBuilder td = null;  
  212.             //TagBuilder th = new TagBuilder("th");    
  213.             TagBuilder th = null;  
  214.             TagBuilder tbody = new TagBuilder("tbody");  
  215.   
  216.             //Inner html Of Table...!!!    
  217.             StringBuilder sb = new StringBuilder();  
  218.             //Add Headers...!!!    
  219.             int i = 0;  
  220.             foreach(ITableColumnInternal < TModel > tc in this.TableColumns) {  
  221.                 th = new TagBuilder("th");  
  222.                 if (i == 0) {  
  223.                     th.InnerHtml = tc.ColumnTitle;  
  224.                     th.MergeAttribute("style""display:none;");  
  225.                 } else {  
  226.                     th.InnerHtml = tc.ColumnTitle;  
  227.   
  228.                 }  
  229.                 i++;  
  230.                 tr.InnerHtml += th.ToString();  
  231.             }  
  232.             th.InnerHtml = "Action";  
  233.             tr.InnerHtml += th.ToString();  
  234.             thead.InnerHtml = tr.ToString();  
  235.             sb.Append(thead.ToString());  
  236.   
  237.             //For Row Data and Coloumn...!!!    
  238.             if (this.Data != null) {  
  239.                 //var data in RowDetail    
  240.                 int row = 0;  
  241.                 foreach(TModel model in this.Data) {  
  242.                     if (model != null) {  
  243.                         tr.InnerHtml = "";  
  244.                         //var header in Headernames    
  245.                         int j = 0;  
  246.                         string ID = "";  
  247.                         foreach(ITableColumnInternal < TModel > tc in this.TableColumns) {  
  248.                             td = new TagBuilder("td");  
  249.                             if (j == 0) {  
  250.                                 ID = tc.Evaluate(model);  
  251.                                 td.InnerHtml = tc.Evaluate(model);  
  252.                                 td.MergeAttribute("style""display:none;");  
  253.                             } else {  
  254.                                 td.InnerHtml = tc.Evaluate(model);  
  255.                             }  
  256.                             tr.InnerHtml += td.ToString();  
  257.                             j++;  
  258.                         }  
  259.                         td.InnerHtml = "<a href='" + EditPath + ID + "'>edit</a> <a href='" + DeletePath + ID + "'>delete</a>";  
  260.                         tr.InnerHtml += td.ToString();  
  261.                         tbody.InnerHtml += tr.ToString();  
  262.                         row++;  
  263.                     }  
  264.                 }  
  265.   
  266.                 sb.Append(tbody.ToString());  
  267.                 table.InnerHtml = sb.ToString();  
  268.             }  
  269.             return new MvcHtmlString(table.ToString());  
  270.   
  271.         }  
  272.     }  
  273.  
  274.     #endregion TableBuilder  
  275.  
  276.     #region MvcHtmlTableExtensions  
  277.   
  278.     public static class MvcHtmlTableExtensions {  
  279.         /// <summary>    
  280.         /// Return an instance of a TableBuilder.    
  281.         /// </summary>    
  282.         /// <typeparam name="TModel">Type of model to render in the table.</typeparam>    
  283.         /// <returns>Instance of a TableBuilder.</returns>    
  284.         public static ITableBuilder < TModel > TableFor < TModel > (this HtmlHelper helper) where TModel: class {  
  285.             return new TableBuilder < TModel > (helper);  
  286.         }  
  287.     }  
  288.  
  289.     #endregion MvcHtmlTableExtensions  
  290. }  
Step 11

Now write code in the View like the following:
  1. @model IEnumerable  
  2. <logindemo.Models.demoregistartion>    
  3. @{    
  4.     ViewBag.Title = "RegistrationDetailList";    
  5.     Layout = "~/Views/Shared/_Layout.cshtml";    
  6. }    
  7. @using (Html.BeginForm("RegistrationDetailList""Registration", FormMethod.Post))    
  8. {     
  9.    
  10.     <div class="panel-body">  
  11.         <div>  
  12.             <a href="/Registration/RegistrationDetail">Add Detail</a>  
  13.         </div>    
  14.         @(Html.TableFor  
  15.         <logindemo.Models.demoregistartion>()    
  16.         .Columns(column =>    
  17.         {    
  18.             column.Expression(p => p.UserID).Title("User ID");    
  19.             column.Expression(p => p.FirstName).Title("First Name");    
  20.             column.Expression(p => p.LastName).Title("Last Name");    
  21.             column.Expression(p => p.EmailID).Title("Email ID");    
  22.             column.Expression(p => p.City).Title("City");    
  23.     
  24.         })    
  25.         .DataSource(this.Model)    
  26.         .ToHtml("basicTable""table-bordered table-responsive""/Registration/EditRegistrationDetail?UserID=""/Registration/DeleteRegistrationDetail?UserID=")    
  27.         )    
  28.    
  29.     </div>  
  30. }  
Step 12

The following is the display form created using HTML helper.

output