The Ultimate Cookbook for the ASP.NET MVC WebGrid
Most developers new to ASP.NET MVC think they need to use a table tag for their grid capabilities. Today, we cover a number of ASP.NET MVC WebGrid questions to create an ultimate WebGrid resource.
If you've been reading the site recently, you may have noticed I've provided a lot of WebGrid features in past posts for advanced users. Yet, I haven't discussed the basics of the WebGrid.
This post will be a post that will constantly be updated. It will contain the proverbial "cookbook" for developers looking for answers to WebGrid solutions.
What is the namespace for an ASP.NET MVC WebGrid?
The WebGrid is located in the System.Web.Helpers
namespace.
How do you create a WebGrid?
The simplest way to create a WebGrid is by defining it on your View and calling it from the View.
For example,
@using WebGridExample.Helpers.Html @using WebGridExample.Models @model IEnumerable<User> @{ var grid = new WebGrid(Model); } . . @MvcHtmlString.Create( grid.GetHtml().ToHtmlString() )
The WebGrid has a huge number of parameters to pass into the constructor.
Name | Type | Notes |
---|---|---|
source | IEnumerable<dynamic> | The data to render. |
columnNames | IEnumerable<string> | Filters the columns that are rendered. |
defaultSort | string | Specifies the default column to sort by. |
rowsPerPage | int | Controls how many rows are rendered per page (default is 10). |
canPage | bool | Enables or disables paging of data. |
canSort | bool | Enables or disables sorting of data. |
ajaxUpdateContainerId | string | The ID of the grid’s containing element, which enables AJAX support. |
ajaxUpdateCallback | string | The client-side function to call when the AJAX update is complete. |
fieldNamePrefix | string | Prefix for query string fields to support multiple grids. |
pageFieldName | string | Query string field name for page number. |
selectionFieldName | string | Query string field name for selected row number. |
sortFieldName | string | Query string field name for sort column. |
sortDirectionFieldName | string | Query string field name for sort direction. |
For the method GetHtml(), there are a ton of parameters for that as well.
Name | Type | Notes |
---|---|---|
tableStyle | string | Table class for styling. |
headerStyle | string | Header row class for styling. |
footerStyle | string | Footer row class for styling. |
rowStyle | string | Row class for styling (odd rows only). |
alternatingRowStyle | string | Row class for styling (even rows only). |
selectedRowStyle | string | Selected row class for styling. |
caption | string | The string displayed as the table caption. |
displayHeader | bool | Indicates whether the header row should be displayed. |
fillEmptyRows | bool | Indicates whether the table can add empty rows to ensure the rowsPerPage row count. |
emptyRowCellValue | string | Value used to populate empty rows; only used when fillEmptyRows is set. |
columns | IEnumerable<WebGridColumn> | Column model for customizing column rendering. |
exclusions | IEnumerable<string> | Columns to exclude when auto-populating columns. |
mode | WebGridPagerModes | Modes for pager rendering (default is NextPrevious and Numeric). |
firstText | string | Text for a link to the first page. |
previousText | string | Text for a link to the previous page. |
nextText | string | Text for a link to the next page. |
lastText | string | Text for a link to the last page. |
numericLinksCount | int | Number of numeric links to display (default is 5). |
htmlAttributes | object | Contains the HTML attributes to set for the element. |
I will be covering a number of these parameters, but not all of them. If you want to examine them further, please refer to the MSDN WebGrid docs.
How do you add attributes to a WebGrid?
The best way to add your styles to the WebGrid is to use the htmlAttributes parameter.
@MvcHtmlString.Create( grid.GetHtml( htmlAttributes: new { id = "grid", @class = "table table-bordered table-striped table-condensed" } ).ToHtmlString() )
However, for the class attribute, you can remove the @class line and move the classes into the tableStyle property.
@MvcHtmlString.Create( grid.GetHtml( tableStyle: "table table-bordered table-striped table-condensed", htmlAttributes: new { id = "grid" } ).ToHtmlString() )
How do you build WebGrid columns?
The parameters passed into a WebGrid can get lengthy. Pass in the columns using the columns parameter and use the WebGrid's Columns method to define your list of WebGridColumn.
@MvcHtmlString.Create( grid.GetHtml( tableStyle: "table table-bordered table-striped table-condensed", htmlAttributes: new { id = "grid" }, columns: grid.Columns( grid.Column("UserName" , "User Name"), grid.Column("FirstName", "First Name"), grid.Column("LastName" ,"Last Name"), grid.Column("LastLogin", "LastLogin") ) ).ToHtmlString() )
The first parameter in the Column constructor is the column name and the second parameter is the heading.
Ok, how do you build custom columns?
As I've mentioned before, you don't want to add a ton of code into your views, but you need to render custom data somehow.
By using HtmlHelpers.
In one example of the WebGrid series, I added an Options column for record specific functions and used an HtmlHelper by passing in the User object.
@MvcHtmlString.Create( grid.GetHtml( tableStyle: "table table-bordered table-striped table-condensed", htmlAttributes: new { id = "grid" }, columns: grid.Columns( grid.Column("UserName" , "User Name", canSort: false), grid.Column("FirstName", "First Name"), grid.Column("LastName" ,"Last Name"), grid.Column("Full Name", format: @<text>item.FirstName+" "+item.LastName</text>), grid.Column("LastLogin", format: item => item.LastLogin.ToString("d")), grid.Column("Options", format: item => Html.DisplayRecordOptions(item.Value as User), canSort: false) ) ).ToHtmlString() )
When using custom columns, you want to use the format parameter to make your custom column data. Depending on your ViewModel, you could very easily create an HtmlHelper to display anything you wanted in a column (i.e. image, buttons, PDF, etc).
Of course, you don't want the column sorted either, so you can turn sorting off using the canSort property.
Notice the @<text></text> tags? Anything inside of text will be taken literally. So in the FullName column, you'll see:
item.FirstName+" "+item.LastName
As you can see, I included a number of examples of how to format your columns.
If you want an example of the DisplayRecordOptions HtmlHelper, I'll refer you to the ASP.NET MVC: Enhancing the WebGrid - Inline Editing using SignalR post.
If you need a refresher on how to create an HtmlHelper, refer to the ASP.NET MVC HtmlHelpers: Clean up Your Views With HtmlHelpers post.
How can I apply paging to WebGrid?
Paging is defined through the WebGrid constructor.
@{ var grid = new WebGrid(Model, canPage: true, rowsPerPage: 20); }
It provides the basic paging mechanism, but I would refrain from using it because it provides paging at the client level as opposed to the server side/database level of paging.
You want the minimal amount of data returned to display a complete View.
If you want to modify the text on the paging, add the First, Previous, Next, and Last properties with the text for each appropriate function.
@MvcHtmlString.Create( grid.GetHtml( tableStyle: "table table-bordered table-striped table-condensed", mode: WebGridPagerModes.All, firstText: "First", previousText: "Prev", nextText: "Next", lastText: "Last", htmlAttributes: new { id = "grid" }, columns: grid.Columns( grid.Column("UserName" , "User Name", canSort: false), grid.Column("FirstName", "First Name"), grid.Column("LastName" ,"Last Name"), grid.Column("LastLogin", format: item => item.LastLogin.ToString("d")), grid.Column("Options", format: item => Html.DisplayRecordOptions(item.Value as User), canSort: false) ) ).ToHtmlString() )
How do I sort a WebGrid?
By default, a WebGrid defines every column as sortable.
To turn off sorting at the column level, pass in canSort: false (in bold).
@MvcHtmlString.Create( grid.GetHtml( tableStyle: "table table-bordered table-striped table-condensed", htmlAttributes: new { id = "grid" }, columns: grid.Columns( grid.Column("UserName" , "User Name", canSort: false), grid.Column("FirstName", "First Name"), grid.Column("LastName" ,"Last Name"), grid.Column("LastLogin", "Last Login"), grid.Column("Options", format: item => Html.DisplayRecordOptions(item.Value as User), canSort: false) ) ).ToHtmlString() )
How can I nest another WebGrid inside another WebGrid?
Remember when I said you can build anything into a WebGrid Column?
If each user belonged to a group, you could add a column displaying their groups in a table.
Here is the nested WebGrid:
@MvcHtmlString.Create( grid.GetHtml( tableStyle: "table table-bordered table-striped table-condensed", htmlAttributes: new { id = "grid" }, columns: grid.Columns( grid.Column("UserName" , "User Name", canSort: false), grid.Column("FirstName", "First Name"), grid.Column("LastName" ,"Last Name"), grid.Column("LastLogin", "Last Login"), grid.Column("SubGrid", format: (item) => { var subGrid = new WebGrid((item.Value as User).Groups); return subGrid.GetHtml( tableStyle: "table table-bordered table-condensed", htmlAttributes: new { id="subGrid"}, columns: subGrid.Columns( subGrid.Column("Groups", format: (groupString) => groupString, canSort: false) ) ); }, canSort: false) ) ).ToHtmlString() )
How can I use AJAX/SignalR with a WebGrid?
If you want a modern web application, learning Ajax and SignalR should be one of your top priorities. SignalR is one of my favorite libraries for performing real-time transactions over the web.
Instead of going over a huge post of how to integrate Ajax or SignalR into your WebGrid, I will refer you to some techniques I covered in my WebGrid Series:
- ASP.NET MVC: Enhancing the WebGrid - Lazy Loading with WebAPI
- ASP.NET MVC: Enhancing the WebGrid - Lazy Loading with SignalR
- ASP.NET MVC: Enhancing the WebGrid - Inline Editing with SignalR
Conclusion
This post will be a living, breathing, document as I continue to use the WebGrid throughout my travels. I will always be expanding this post because of ASP.NET MVC 6 arriving soon.
If anyone is looking for a specific WebGrid topic or technique, please let me know or post a comment below.