Introduction to WebGrid in MVC 3 Razor (with code samples)

Webgrid is used to display data on a web page using an HTML table element. It has built-in support for paging and sorting. You can style webgrid easily using the alternatingRowStyle,headerStyle or tableStyle attributes.

Here is a link to msdn for the WebGrid Class.

The GetHtml() method renders the grid. Now lets render a simple grid with no formatting using the following code.

1. Basic

Razor Code

@{  
var grid = new WebGrid(source: Model.Products);  
@grid.GetHtml()  
} 

Output

2. Formatting :

Now to make the grid more visually appealing, you can customize each column of the webgrid. This can be done using the optional argument called ‘Columns‘. In the code below for the last column I have used the optional ‘format‘ attribute to place a ‘$’ character after the price value.

Razor Code

@{  
var grid = new WebGrid(source: Model.Products);  
@grid.GetHtml(columns:grid.Columns(  
grid.Column(columnName:"ProductName", header:"Name of the Product"),  
grid.Column(columnName:"ProductCode", header:"Code"),  
grid.Column(columnName:"ProductPrice", header:"Price in $", format:@<text>@item.Price $</text>)))  
}  

Output

3. Sorting and Paging :

For sorting and paging, we can use the ‘rowsPerPage‘ attribute which specifies the maximum number of rows to be displayed per page, we can disable sorting on a specific columns using the ‘canPage‘ attribute on that column. (see Code column)

Razor Code

@{  
var grid = new WebGrid(source: Model.Products, rowsPerPage:4, canPage:true, canSort:true);  
@grid.GetHtml(columns:grid.Columns(  
grid.Column(columnName:"ProductName", header:"Name of the Product"),  
grid.Column(columnName:"ProductCode", header:"Code", canSort:false),  
grid.Column(columnName:"ProductPrice", header:"Price in $", format:@<text>@item.Price $</text>)))  
}  

Output

4. Styling

You can style your webgrid using the alternatingRowStyle,headerStyle or tableStyle attributes, see the code below…

Razor Code

@{  
var grid = new WebGrid(source: Model.Products, rowsPerPage:4, canPage:true, canSort:true);  
@grid.GetHtml(  
headerStyle: "headerStyle",  
tableStyle: "tableStyle",  
alternatingRowStyle: "alternateStyle",  
columns:grid.Columns(  
grid.Column(columnName:"ProductName", header:"Name of the Product"),  
grid.Column(columnName:"ProductCode", header:"Code", canSort:false),  
grid.Column(columnName:"ProductPrice", header:"Price in $", format:@<text>@item.Price $</text>)))  
}  

CSS Code

.headerStyle  
{  
background: #FFFFCC;  
}

.tableStyle  
{  
background: #CFFFCC;  
}

.alternateStyle  
{  
background: #FBFFCC;  
}  

Output

5. Custom Paging

http://yassershaikh.com/webgrid-paging-with-pager-method-in-razor-mvc/

5. How to include an action link in a webgrid

We can include ActionLinks in a webgrid column using the following code. We can also pass values from an ActionLink to a Action as seen in the code below.

grid.Column(format: (item) => Html.ActionLink("Edit", "ActionName", new { param1 = "hello", param2 = "bye" }))  

or

grid.Column(format:@<text>@Html.ActionLink("Edit", "ActionName", new { param1 = "hello", param2 = "bye" })</text>)  

In the code above I am passing two values to my action viz. param1, param2

Action in the Controller

public ActionResult ActionName(string param1, string param2)  
{}  

6. Displaying multiple ActionLink in a single column of a webgrid

grid.Column(header: "Actions", format: (item) =>  
new HtmlString(  
Html.ActionLink("Edit", "Edit", new { id = item.id } ).ToString() +  
Html.ActionLink("Delete", "Delete", new { id = item.id } ) .ToString()  
) 

Custom / Efficient Paging in ASP.NET MVC 3 using Skip() and Take() LINQ methods

Recently, I was required to create custom paging in an MVC 3 application after posting a question at at http://stackoverflow.com/q/11662772/1182982 I was asked to use Skip() and Take() LINQ methods.

So keeping that in mind, below is what I had tried and it worked !

You can download the code from here and run/debug/see for yourself.. http://yassershaikh.com/wp-content/uploads/2012/07/CustomPagingDemo.rar

Product.cs

public class Product
{
    public string ProductName;
    public string CompanyName;
}

Model -> IndexModel

public class IndexModel
{
    public List<Product> Products { get; set; }
}

Controller

public class HomeController : Controller
{

    List<Product> products = new List<Product>()
    {
        // 12 products
        new Product(){CompanyName = "Samsung", ProductName = "Galaxy S III"},
        new Product(){CompanyName = "Samsung", ProductName = "Galaxy S III"},
        new Product(){CompanyName = "Apple", ProductName = "Ipad 3"},
        new Product(){CompanyName = "Karbon", ProductName = "Kaamaal"},
        new Product(){CompanyName = "Warren", ProductName = "Jistern"},
        new Product(){CompanyName = "Kolles", ProductName = "Avenski"},
        new Product(){CompanyName = "lll", ProductName = "bbb7"},
        new Product(){CompanyName = "nnn", ProductName = "bbb8"},
        new Product(){CompanyName = "mmm", ProductName = "bbb9"},
        new Product(){CompanyName = "ttt", ProductName = "bbb10"},
        new Product(){CompanyName = "uuu", ProductName = "bbb11"},
        new Product(){CompanyName = "yyy", ProductName = "bbb13"},
        new Product(){CompanyName = "ooo", ProductName = "bbb12"},
    };

    private const int PageSize = 3;

    public ActionResult Index(int page = 1)
    {
        var productlist = products.Skip((page – 1) * PageSize).Take(PageSize).ToList();
        var model = new IndexModel();
        model.Products = productlist;

        ViewBag.CurrentPage = page;
        ViewBag.PageSize = PageSize;
        ViewBag.TotalPages = Math.Ceiling((double)products.Count() / PageSize);

        return View(model);
    }

    public ActionResult About()
    {
        return View();
    }
}

View – Index View

@model CustomPagingDemo.Models.IndexModel

@{
    ViewBag.Title = "Home Page";
}

<p>
    @foreach (var product in Model.Products)
    {
        <table width="500px">
        <tr>
        <td width="50%">@product.CompanyName</td>
        <td width="50%">@product.ProductName</td>
        </tr>
        </table>
    }
</p>

<!– Page links below -–>
<p>
    @for(int i= 1; i<=ViewBag.TotalPages; i++)
    {
        <a href="@Url.Action("Index","Home", new { page = i } )">@i</a>
    }
</p>

How to change width / style for a column of a webgrid in MVC 3 Razor

In webgrid, using the style attribute we can specify a style for a column.

Please do not confuse yourself, by directly putting style=”width:10px” …

Webgrid’s style attribute is more like className !!!

The style attribute needs to have a class name which you may have defined in your css file.

@grid.GetHtml(columns: grid.Columns(
grid.Column("Username", "Username", canSort: true, style: "user"),
grid.Column("Password", "Password", canSort: true, style: "pass")
));

I have defined two seperate CSS classes : user and pass and have given some css property to it, say if you want to change the width of a column you can use the width property.

.user{
width:150px;
font-size:12px;
}

.pass {
width: 100px;
font-weight:bold;
}

Incase of any queries or suggestions, please feel free to write in using the comment section.

Check Box in Webgrid MVC 3

Below is a simple demonstration on how to use checkbox inside a  webgrid column in MVC 3.

I had a field called ‘HasPassport‘ in my model which was of type **boolean **for which I required a checkbox column, to show a checked checkbox for every true value and an unchecked checkbox otherwise.

Using the WebGrid.Column’s format parameter below is how I have used…

grid.Column(  
header: "HasPassport ?",  
format:  
(col) => @Html.Raw(

"<input type='checkbox' checked='" +

((col.HasPassport) ? "checked" : "") +

"' disabled='true' />")  
)  

So for every true value for the ‘hasPassport’ field the following HTML code is generated :

<input type='checkbox' checked='checked' disabled='true' />  

Hope this helps ! Cheers !

Sorting / Paging two webgrid in MVC 3 Razor

When using two webgrids, you often must have come across a problem where sorting/paging on one webgrid will affect the sorting and paging on the other grid. Now lets assume you have already set canPage: true, canSort: true

Below is a simple example of how you should use multiple webgrids to avoid this problem.

string fieldNamePrefix = null  
//The value which prefixes the default querystring fields

string pageFieldName = null  
//A value that replaces the default querystring page field 

var grid1 = new WebGrid(ajaxUpdateContainerId: "grid1", fieldNamePrefix:"g1",pageFieldName: "p1");

var grid2 = new WebGrid(ajaxUpdateContainerId: "grid2", fieldNamePrefix:"g2",pageFieldName: "p2");

CHEERS !

MVC 3 Web grid sorting not working

I recently was working a lot with Web Grids, and there was this was one problem that kept coming up again n again, so I have decided to write an article for this.

Lets first see what my web grid code looked like when my sorting was NOT WORKING,

var myGrid = new WebGrid(source: Model.ABC);

@myGrid .GetHtml(

    columns: myGrid .Columns(  
    myGrid .Column("User Name", format: @<text>@item.Username</text>),  
    myGrid .Column("Password", format: @<text>@item.Password</text>),

))

While testing I found that sorting on Password column worked but when I tried sorting on Username column it just didn’t work !

SOLUTION:

After a little googling and going over stackOverflow QA I finally found the actual problem.

This happens because the grid column names must correspond to your fields or db columns. The Method which generates URL in grid header compares “sort” from url query string with bounded columns and with grid column name. These must be exactly the same.

So because I had used “User Name” and not “Username”, sorting on my username column did not work.

Corrected code : Use **columnName:, **to specify column names and **header: **to specify table header

var myGrid = new WebGrid(source: Model.ABC);

    @myGrid .GetHtml(

    columns: myGrid .Columns(  
    myGrid .Column(header: "User Name", columnName: "Username" , format: @<text>@item.Username</text>),  
    myGrid .Column(header: "Password", columnName: "Password" ,format: @<text>@item.Password</text>),

))

Hope this helps you too !

WebGrid Paging with pager method in Razor MVC

I needed to add a paging option to my webGrid control, after doing a lot of googling I still could’nt find a proper written article for this. So I decided to write an article on this myslef.

MVC Razor provides a pager method, details of which can be read at WebGrid.Pager Method

Below is the code I had used,


@{

var grid = new WebGrid(source: Model.GetMydata,
rowsPerPage: 10, canPage:true);

// The above line says that is shall get data from the GetMydata() method, the
// number of rows that will be displayed on one page shall be 10, and most
// important I have enabled the paging option by setting the canPage to true

@grid.GetHtml(

columns: grid.Columns(

grid.Column("Name", format: @<text>@item.Name</text>, header: "Name"),
grid.Column("Age", format: @<text>@item.Age</text>, header: "Age"),
grid.Column("Phone", format: @<text>@item.Phone</text>, header: "Phone")
))

// Below is the magical code

@grid.Pager(
mode: WebGridPagerModes.All,
numericLinksCount: 15,
firstText: "<<",
lastText: ">>;",
previousText: "<",
nextText: ">")

// Check the above given MSDN link to get a detailed explanation on each of the
// parameters used above.

}