Render MVCContrib Grid with No Header Row
- by Ben Griswold
The MVCContrib Grid allows for the easy construction of HTML tables for displaying data from a collection of Model objects. I add this component to all of my ASP.NET MVC projects. If you aren’t familiar with what the grid has to offer, it’s worth the looking into.
What you may notice in the busy example below is the fact that I render my column headers independent of the grid contents. This allows me to keep my headers fixed while the user searches through the table content which is displayed in a scrollable div*. Thus, I needed a way to render my grid without headers. That’s where Grid Renderers come into play.
<table border="0" cellspacing="0" cellpadding="0" class="projectHeaderTable">
<tr>
<td class="memberTableMemberHeader">
<%= Html.GridColumnHeader("Member", "Index", "MemberFullName")%>
</td>
<td class="memberTableRoleHeader">
<%= Html.GridColumnHeader("Role", "Index", "ProjectRoleTypeName")%>
</td>
<td class="memberTableActionHeader">
Action
</td>
</tr>
</table>
<div class="scrollContentWrapper">
<% Html.Grid(Model)
.Columns(column =>
{
column.For(c => c.MemberFullName).Attributes(@class => "memberTableMemberCol");
column.For(c => c.ProjectRoleTypeName).Attributes(@class => "memberTableRoleCol");
column.For(x => Html.ActionLink("View", "Details", new { Id = x.ProjectMemberId }) + " | " +
Html.ActionLink("Edit", "Edit", new { Id = x.ProjectMemberId }) + " | " +
Html.ActionLink("Remove", "Delete", new { Id = x.ProjectMemberId }))
.Attributes(@class => "memberTableActionCol").DoNotEncode();
})
.Empty("There are no members associated with this project.")
.Attributes(@class => "lbContent")
.RenderUsing(new GridNoHeaderRenderer<ProjectMemberDetailsViewModel>())
.Render();
%>
</div>
<div class="scrollContentBottom">
<!– –>
</div>
<%=Html.Pager(Model) %>
Maybe you noticed the reference to the GridNoHeaderRenderer class above? Yep, rendering the grid with no header is straightforward.
public class GridNoHeaderRenderer<T> :
HtmlTableGridRenderer<T> where T: class
{
protected override bool RenderHeader()
{
// Explicitly returning true would suppress the header
// just fine, however, Render() will always assume that
// items exist in collection and RenderEmpty() will
// never be called.
// In other words, return ShouldRenderHeader() if you
// want to maintain the Empty text when no items exist.
return ShouldRenderHeader();
}
}
Well, if you read through the comments, there is one catch. You might be tempted to have the RenderHeader method always return true. This would work just fine but you should return the result of ShouldRenderHeader() instead so the Empty text will continue to display if there are no items in the collection.
The GridRenderer feature found in the MVCContrib Grid is so well put together, I just had to share.
* Though you can find countless alternatives to the fixed headers problem online, this is the only solution that I’ve ever found to reliably work across browsers. If you know something I don’t, please share.