Note that there are some explanatory texts on larger screens.

plurals
  1. POWriting a HtmlHelper 'Table' method, which uses the model DisplayName's
    primarykey
    data
    text
    <p>I have recently decided to write a generic Table html helper to generate tables for my models and other objects, I have used reflection to make it more generic by taking an IEnumerable argument as the table data and a Dictionary for the .</p> <p>I want to use reflection or some other method to get the properties [DisplayName()] attribute from the models MetaData so that it does not need to be specified in a dictionary. However all methods I have tried seem to return null, so I have removed them from my code.</p> <pre><code>public static MvcHtmlString Table(this HtmlHelper htmlHelper, Dictionary&lt;string, string&gt; boundColumns, IEnumerable&lt;object&gt; objectData, string tagId, string className, string controllerName, string idProperty) { bool hasAction = !String.IsNullOrEmpty(idProperty); bool hasData = objectData.Count() &gt; 0; UrlHelper urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext); Type objectDataType = hasData ? objectData.First().GetType() : null; IEnumerable&lt;PropertyInfo&gt; objectDataProperties = hasData ? from propInfo in objectDataType.GetProperties() where boundColumns.ContainsKey(propInfo.Name) select propInfo : null; // Thead TagBuilder theadtr = new TagBuilder("tr"); foreach (string col in boundColumns.Values) theadtr.InnerHtml = String.Format("{0}\n{1}", theadtr.InnerHtml, (new TagBuilder("th") { InnerHtml = col }).ToString()); if (hasAction) theadtr.InnerHtml = String.Format("{0}\n{1}", theadtr.InnerHtml, new TagBuilder("th") { InnerHtml = "Action" }); TagBuilder thead = new TagBuilder("thead") { InnerHtml = theadtr.ToString() }; // Tfoot TagBuilder tfoot = new TagBuilder("tfoot"); if (!hasData) // Warn that there was no data to be displayed. { TagBuilder tfoottd = new TagBuilder("td") { InnerHtml = "There is currently nothing to display." }; tfoottd.MergeAttribute("colspan", (hasAction ? (boundColumns.Count + 1) : boundColumns.Count).ToString()); tfoottd.MergeAttribute("style", "text-align:center"); tfoot.InnerHtml = (new TagBuilder("tr") { InnerHtml = tfoottd.ToString() }).ToString(); } else // Display a pager &amp; filter for navigating through large amounts of data. { // The button for navigating to the first page. TagBuilder pagefirst = new TagBuilder("img"); pagefirst.MergeAttribute("id", String.Format("{0}-page-first", tagId)); pagefirst.MergeAttribute("class", "first"); pagefirst.MergeAttribute("alt", "First Page"); pagefirst.MergeAttribute("src", urlHelper.Content("~/Content/Style/Tables/Themes/Blue/resultset_first.png")); pagefirst.MergeAttribute("style", "cursor:pointer; vertical-align:middle;"); // The button for navigating to the previous page. TagBuilder pageprev = new TagBuilder("img"); pageprev.MergeAttribute("id", String.Format("{0}-page-prev", tagId)); pageprev.MergeAttribute("class", "prev"); pageprev.MergeAttribute("alt", "Previous Page"); pageprev.MergeAttribute("src", urlHelper.Content("~/Content/Style/Tables/Themes/Blue/resultset_previous.png")); pageprev.MergeAttribute("style", "cursor:pointer; vertical-align:middle;"); // The button for navigating to the next page. TagBuilder pagenext = new TagBuilder("img"); pagenext.MergeAttribute("id", String.Format("{0}-page-next", tagId)); pagenext.MergeAttribute("class", "next"); pagenext.MergeAttribute("alt", "Next Page"); pagenext.MergeAttribute("src", urlHelper.Content("~/Content/Style/Tables/Themes/Blue/resultset_next.png")); pagenext.MergeAttribute("style", "cursor:pointer; vertical-align:middle;"); // The button for navigating to the last page. TagBuilder pagelast = new TagBuilder("img"); pagelast.MergeAttribute("id", String.Format("{0}-page-last", tagId)); pagelast.MergeAttribute("class", "last"); pagelast.MergeAttribute("alt", "Last Page"); pagelast.MergeAttribute("src", urlHelper.Content("~/Content/Style/Tables/Themes/Blue/resultset_last.png")); pagelast.MergeAttribute("style", "cursor:pointer; vertical-align:middle;"); // The display field for the pager status. TagBuilder pagedisplay = new TagBuilder("input"); pagedisplay.MergeAttribute("id", String.Format("{0}-page-display", tagId)); pagedisplay.MergeAttribute("type", "text"); pagedisplay.MergeAttribute("class", "pagedisplay"); pagedisplay.MergeAttribute("disabled", "disabled"); pagedisplay.MergeAttribute("style", "width:12%;"); // The select for changing page size. TagBuilder pagesize = new TagBuilder("select"); pagesize.MergeAttribute("id", String.Format("{0}-page-size", tagId)); pagesize.MergeAttribute("class", "pagesize"); pagesize.MergeAttribute("style", "width:12%;"); for (int i = 10; i &lt;= 100; i += 10) { TagBuilder option = new TagBuilder("option") { InnerHtml = i.ToString() }; if (i == 10) option.MergeAttribute("selected", "selected"); option.MergeAttribute("value", i.ToString()); pagesize.InnerHtml = String.Format("{0}\n{1}", pagesize.InnerHtml, option.ToString()); } // The pager container. TagBuilder pagediv = new TagBuilder("div") { InnerHtml = (new TagBuilder("form") { InnerHtml = String.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}", pagefirst.ToString(), pageprev.ToString(), pagenext.ToString(), pagelast.ToString(), pagedisplay.ToString(), pagesize.ToString()) }).ToString() }; pagediv.MergeAttribute("id", String.Format("{0}-pager", tagId)); pagediv.MergeAttribute("style", "float:left; width:50%;"); // Filter Text Field TagBuilder filterfield = new TagBuilder("input"); filterfield.MergeAttribute("id", String.Format("{0}-filter-field", tagId)); filterfield.MergeAttribute("type", "text"); filterfield.MergeAttribute("style", "width:30%;"); // The filter container. TagBuilder filterdiv = new TagBuilder("div") { InnerHtml = (new TagBuilder("form") {InnerHtml = String.Format("Search: {0}", filterfield.ToString())}).ToString() }; filterdiv.MergeAttribute("id", String.Format("{0}-filter", tagId)); filterdiv.MergeAttribute("style", "float:right; width:50%;"); TagBuilder tfoottd = new TagBuilder("td") { InnerHtml = String.Format("{0}\n{1}", pagediv.ToString(), filterdiv.ToString()) }; tfoottd.MergeAttribute("colspan", (hasAction ? (boundColumns.Count + 1) : boundColumns.Count).ToString()); tfoottd.MergeAttribute("style", "text-align:center"); tfoot.InnerHtml = (new TagBuilder("tr") { InnerHtml = tfoottd.ToString() }).ToString(); } // Tbody TagBuilder tbody = new TagBuilder("tbody"); foreach (object o in objectData) { TagBuilder tbodytr = new TagBuilder("tr"); foreach (PropertyInfo p in objectDataProperties) { string val = "N/A"; object pval = p.GetValue(o, null); if (pval != null) val = pval.ToString(); tbodytr.InnerHtml = String.Format("{0}\n{1}", tbodytr.InnerHtml, (new TagBuilder("td") { InnerHtml = val }).ToString()); } if (hasAction) { string id = objectDataType.GetProperty(idProperty).GetValue(o, null).ToString(); tbodytr.InnerHtml = String.Format( "{0}\n{1}", tbodytr.InnerHtml, (new TagBuilder("td") { InnerHtml = Table_ActionLinks(htmlHelper, controllerName, id) }). ToString()); } tbody.InnerHtml = String.Format("{0}\n{1}", tbody.InnerHtml, tbodytr.ToString()); } // Table TagBuilder table = new TagBuilder("table") { InnerHtml = String.Format("{0}\n{1}\n{2}", thead.ToString(), tfoot.ToString(), tbody.ToString()) }; table.MergeAttribute("id", string.IsNullOrEmpty(tagId) ? String.Format("table-{0}", boundColumns.Count.ToString()) : tagId); table.MergeAttribute("summary", "Generic data list"); if (!String.IsNullOrEmpty(className)) table.MergeAttribute("class", String.Format("{0} {1}", className, "tablesorter")); else table.MergeAttribute("class", "tablesorter"); // Enable Sorting/Searching if (hasData) { TagBuilder sortscript = new TagBuilder("script") { InnerHtml = String.Format("$(document).ready(function(){{$(\"#{0}\").tablesorter().tablesorterPager({{container:$(\"#{1}\")}});}});", tagId, String.Format("{0}-pager", tagId)) }; TagBuilder searchscript = new TagBuilder("script") { InnerHtml = String.Format("$(document).ready(function(){{$(\"#{0}\").keyup(function(){{$.uiTableFilter($(\"#{1}\"), this.value);}})}});", String.Format("{0}-filter-field", tagId), tagId) }; sortscript.MergeAttribute("type", "text/javascript"); return new MvcHtmlString(String.Format("{0}\n{1}\n{2}", table.ToString(), sortscript.ToString(), searchscript.ToString())); } return new MvcHtmlString(table.ToString()); } </code></pre> <p>So basically I am looking to use as much reflection as possible to eliminate as many arguments to this method as possible.</p> <p>Thanks, Alex.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload