Creating a Responsive WebGrid in ASP.NET MVC
WebGrids are fantastic when coding for a desktop layout, but what do you do when you need it mobile? Today, I analyze the WebGrid and use CSS to make the WebGrid bend to our will and make it more responsive on a mobile device.
It's amazing how one reader's email can send me down the proverbial rabbit hole.
A reader asked if I knew of a way to integrate a responsive layout into a WebGrid using Bootstrap.
At first, I thought, "Hey, this would make a great post to continue on with my WebGrid series. This should be easy."
Uh-huh.
I thought I could inherit from the WebGrid and override some methods to make the WebGrid a little more flexible for my needs.
As I mentioned before, nothing is ever simple or easy.
Examining The WebGrid
To make the WebGrid responsive (specifically on a mobile device), I wanted to add a custom attribute to each <td> cell.
I know that you can have custom HTML attributes, but those are specific to the table itself. Yet, if I want a custom attribute (<td data-label="column1">) attached to a table cell (td) or table row (tr), there isn't a way to achieve that with the current WebGrid.
After examining the WebGrid source code on GitHub, I was even more startled.
I noticed a WebGridRenderer cs and cshtml file. After looking through these two files, I realized they were compiled into the assembly.
Hmm.
The only time the WebGridRenderer was used was at the end of two HtmlHelper methods: One called Pager and the other called Table.
The interesting part is that the WebGridRenderer.cshtml is like a partial along with a long list of functions and helpers included in the file.
There's another issue I noticed with the WebGrid "Partial." When rendering the <td> element (or <tr> element for that matter), it's assuming that you are only going to add CSS classes to the element (Line 123).
<td@CssClass(style)>
THIS is kind of an issue.
I thought I would be able to squeeze additional attributes into that TD, but unfortunately with this architecture, I won't be able to achieve it.
Rewrite the WebGrid?
We can attack this problem one of three ways. Refactor the code:
- Programmatically - write code to create the table.
- Declaratively - Use HTML and pass in the data/model.
- Not at all - Use CSS to work around the issue.
Personally, I think option 2 is a better way because it allows more flexibility with the code. Also, if you have to make a change, you always have to compile. I would rather update the HTML and deploy that without compiling the entire project.
I understand why the WebGrid was created that way. They wanted to include the HTML programmatically when you requested the WebGrid assembly by using NuGet. I get it. It has to be portable and NuGet-able.
A quick approach is to use CSS to make it responsive and worry about the WebGrid another day.
The Simple Approach
Instead of writing a whole new WebGrid (not yet, folks, hold on), the best approach is to use CSS to make our WebGrid responsive.
We'll use the WebGrid from our WebGrid series. Applying the CSS to the WebGrid is very simple.
@@media screen and (max-width: 600px) { .nav li { float: left } table, tbody, td, tr { display: block; border: none;} .table-bordered > tbody > tr> td { border: none;} tr { border-bottom: 1px solid #777}
thead, th { display: none }
table td:before { float: left; text-transform: uppercase; font-weight: bold; border: none; }
td:nth-of-type(2):before { width: 200px; content: "User Name";} td:nth-of-type(3):before { width: 200px; content: "First Name"; } td:nth-of-type(4):before { width: 200px; content: "Last Name"; } td:nth-of-type(5):before { width: 200px; content: "Last Login"; } }
The first line makes the toolbar a little aesthetically pleasing.
The next set of CSS classes makes the table body, table cell, and table row a block element with no borders.
Since we are making our own headlines, let's remove them by "display: none"-ing them.
With every table cell in the table, we want it pulled to the left, bold type, and no border around it.
Finally, we pick the nth column of a table cell and make the width 200 pixels and place the heading inside the cell.
Once applied, we get this result.
Our WebGrid looks great on a mobile device now.
Conclusion
Today, we focused on making a responsive WebGrid using CSS. This made the WebGrid easier to work with by changing the presentation of grid instead of reworking the implementation of the WebGrid.
Looking for more WebGrid goodness? Check out the WebGrid Series.
Did anyone make changes to the WebGrid source code to use attributes on table cells or table rows?
Post your comments below to discuss further.