The WebGrid In MVC

Something that new comers to MVC may wonder about, is how to create something like a GridView in MVC.  I know this was something I ran into, but quickly found the answer.  Meet the WebGrid.  The WebGrid is just that, it will create a grid of your tabular data to display nice and neatly on your view.

To make use of a WebGrid you have to perform two basic steps; new up a WebGrid object, and invoke that object’s GetHtml method.

When we new up a WebGrid we can provide some basic details for it.  Things like the source of the data, the columns you will display. how many rows per page, if it allows paging and if it allows sorting.  Lets provide an example,this example uses a model that contains: EmployeeName, SupervisorName, and Submitted.

@{
    var gridForm = new WebGrid(
        source: Model,
        columnNames: new[] { "EmployeeName", "SupervisorName", "Submitted" },
        defaultSort: "Submitted",
        rowsPerPage: 8,
        canPage: true,
        canSort: true);
}

You can see the columnNames are just an array, I set the default sort, rows, sorting and pagination. Pretty straight forward. These fields are two strings and a datetime.  Now that we have our gridForm object we will want to display it somewhere on our view.  I usually wrap this in a div that uses a class.  In fact, when we use the GetHtml method we can provide CSS classes for different parts of the webgrid.  This is also when we can get a little more specific on our header names.  I have also done something a little different with this that you will see.  The model also contains an EmployeeID field.  What I want to do is only allow an employee to edit or view details for their records.  I set this up in the GetHtml method.

<div class="<span class=" hiddenspellerror="" pre="">webGridWrapper"></div>
    @if (Model.Any())
    {
        @gridForm.GetHtml(tableStyle: "webGrid", headerStyle: "webGridHeader", alternatingRowStyle: "webGridAlt",
            columns: gridForm.Columns
            (
                gridForm.Column("EmployeeName", header: "Employee Name"),
                gridForm.Column("SupervisorName", header: "Supervisor Name"),
                gridForm.Column("Submitted", header: "Submitted"),
                gridForm.Column(null, "", format: (item) => (item.employeeID == User.Identity.Name) ?
                    MyProject.Helpers.CreateLink.EditDetails("FormEntry", item.ID.ToString())
                    :
                    "")
            )
        );
    }
</div>

That is pretty straight forward.  The column that does the Edit/Details might need some clarification, plus you are probably wondering what this CreateLink thing is about.  The CreateLink is a class I created to keep things cleaner. I will put that class below.  First, let me explain what is going on in that last column.  I use the item’s employeeID field to compare its value to that of the user’s logged in information; Page.User.Identity.Name.  If it is a match, then I output the links, otherwise I do not output anything.  I am not saying this is the best way to achieve this task, I put it in here merely to show you that you can do more than just the standard columns.

The CreateLink class, in a nutshell, outputs the HTML needed to create the Edit, Details or both links.  I put this class in a folder I call Helpers.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;

namespace MyProject.Helpers
{
    public static class CreateLink
    {
        //Create the Edit link for a given controller and id
        public static HtmlString Edit(string sController, string id)
        {
            string sLink = "";
            sLink = String.Format("<a href="{0}/Edit/{1}">Edit</a>", sController, id);
            HtmlString theLink = new HtmlString(sLink);
            return theLink;
        }

        //Create the Details link for a given controller and id
        public static HtmlString Details(string sController, string id)
        {
            string sLink = "";
            sLink = String.Format("<a href="{0}/Details/{1}">Details</a>", sController, id);
            HtmlString theLink = new HtmlString(sLink);
            return theLink;
        }

        //Create the Edit and Details links for a given controller and id
        public static HtmlString EditDetails(string sController, string id)
        {
            StringBuilder sbLink = new StringBuilder();
            sbLink.Append(Edit(sController, id));
            sbLink.Append(" | ");
            sbLink.Append(Details(sController, id));
            HtmlString theLink = new HtmlString(sbLink.ToString());
            return theLink;
        }
    }
}

So what does this render in the view?  Using my test data, here is what my view rendered for me.  I must apologize for using the same datetime value for each entry.

My rendered WebGrid

Finally I will put my WebGrid’s CSS sheet in this post.  Again, I do not claim this is the best way to do things, they are just examples of what you can do with the tools.

.webGrid
{
    margin: 4px;
    border-collapse: collapse;
}
.webGridWrapper
{
    min-width: 320px;
    max-width: 800px;
    overflow: auto;
}
.webGridHeader
{
    padding: 0.5em; /* add gradient */
    background-color: #808080;
    background-image: -moz-linear-gradient(top, #606060, #909090);
    background-image: -ms-linear-gradient(top, #606060, #909090);
    background-image: -o-linear-gradient(top, #606060, #909090);
    background-image: -webkit-gradient(linear, left top, left bottom, from(#606060), to(#909090));
    background-image: -webkit-linear-gradient(top, #606060, #909090);
    background-image: linear-gradient(top, #606060, #909090);
    color: #DADADA;
}
.webGrid th, .webGrid td
{
    border: 1px solid #C0C0C0;
    padding: 4px 6px 4px 6px;
}
.webGrid th a
{
    color: #DADADA;
}
.webGrid th a:hover
{
    color: #FFFFFF;
    -webkit-box-shadow:0 0 15px #FFFFFF;
    -moz-box-shadow: 0 0 15px #FFFFFF;
    box-shadow:0 0 15px #FFFFFF;
    background-color: #C0C0C0;
}
.webGrid td a
{
    color: #08088A;
}
.webGrid td a:hover
{
    color: #0000FF;
    -webkit-box-shadow:0 0 15px #00BFFF;
    -moz-box-shadow: 0 0 15px #00BFFF;
    box-shadow:0 0 15px #00BFFF;
    background-color: #58D3F7;
}
.webGrid tfoot
{
    line-height: .8em;
    text-align: center;
    color: #303030;
    text-shadow: 0 1px 1px rgba(255,255,255,0.3);
    letter-spacing: .25em;
    font-size: small;
}
.webGrid tfoot a
{
    color: #0000FF;
    text-decoration: none;
}
.webGrid tfoot a:hover
{
    color: #0000FF;
    font-weight: bold;
    text-decoration: underline;
    -webkit-box-shadow: none;
    -moz-box-shadow: none;
    box-shadow: none;
    background-color: transparent;
}
.webGridAlt
{
    background-color: #E8E8E8;
    color: #000;
}

For more information on using the WebGrid I highly recomend the MSDN Magazine article Get The Most Out of WebGrid in ASP.NET MVC, and WebGrid WebHelper in ASP.NET MVC 3 RC on DotNet Curry.

Advertisements

About SheldonS

Web developer for over 15 years mainly with Microsoft technologies from classic ASP to .NET 4. Husband, father, and aspiring amateur photographer.

Posted on November 21, 2012, in MVC and tagged , . Bookmark the permalink. 1 Comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: