How to implement paging & sorting in MVC 3 , Part 2– How to use it for Paging, Sorting

I have implemented a paging & sorting functions myself in mvc 3. It is extremely easy to integrate and extend, plus is required minimum codes in View & Action method. How cool is that. Let me show you how to use it with a simple example. Example can be downloaded here.

1. paging & sorting with postbacks (non-ajax)

I create a domain object People for demo purpose, it has 3 properties.

public class People
{
public int Id { get; set; }
public string Username { get; set; }
public int Age { get; set; }
}

View

: ( the model of the view returns a IPagedList<People>)

@model MvcPaging.IPagedList<PagingSorting.Web.Models.People>
@using MvcPaging
<table class="grid">
<thead>
<tr>
<th>@Html.ActionLink("Id", "Index", Model)</th>
<th>@Html.ActionLink("Username", "Index", Model)</th>
<th>@Html.ActionLink("Age", "Index", Model)</th>
</tr>
</thead>
<tbody>
@foreach (var i in Model) {
<tr>
<td>@i.Id</td>
<td>@i.Username</td>
<td>@i.Age</td>
</tr>
}
</tbody>
</table>

<div class="pager">
	@Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount, Model.SortBy, Model.SortDescending)
</div>

Controller Action:

a few things need to note here,

a. parameters need to be included for the method, page, sortBy, sortDescending

b. the pageIndex start with 0, if you pass null to “page”, it needs to be initiated as 0 for “PagingOption”

c. PeopleList is a IQueryable<People>, for your project you will get the list of items from repository.

d. convert the IQueryable<People> list to IPagedList by passing in the PagingOption.

[HttpGet]
public ActionResult Index(int? Page, string SortBy, bool? SortDescending)
{
int currentPageIndex = Page.HasValue ? Page.Value - 1 : 0;
var option = new PagingOption { Page = currentPageIndex, PageSize = PageSize, SortBy = SortBy, SortDescending = SortDescending };

var items = PeopleList.ToPagedList(option);
return View(items);
}

Styles:

style your div.pager, you can create styles for

.pager a (all the links in div.pager)

.pager .disabled (to display disabled link, eg. Previous or Next)

.pager .current (to display current page link)

.sort-off (sorting style for column header)

.sort-desc (descending style for column header)

.sort-asc (ascending style for column header)

.pager
{
	margin:8px 3px;
	padding:3px;
}

.pager .disabled
{
	border:1px solid #ddd;
	color:#999;
	margin-top:4px;
	padding:3px;
	text-align:center;
}

.pager .current
{
	background-color:#06c;
	border:1px solid #009;
	color:#fff;
	font-weight:bold;
	margin-top:4px;
	padding:3px 5px;
	text-align:center;
}

.pager span, .pager a
{
	margin: 4px 3px;
}

.pager a
{
	border:1px solid #c0c0c0;
	padding:3px 5px;
	text-align:center;
	text-decoration:none;
}

#loadingcontainer
{
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
background:#efefef url('./images/ajax-loader.gif') no-repeat center center;
z-index:100;
opacity:0.8;
filter:alpha(opacity=80);
display:none;
}

.grid
{
width:100%;
}

.sort-off
{
width:100%;
display:inline-block;
background:none;
}

.sort-desc
{
width:100%;
display:inline-block;
background:transparent url('./images/icon_down_sort_arrow.png') no-repeat right center;
}

.sort-asc
{
width:100%;
display:inline-block;
background:transparent url('./images/icon_up_sort_arrow.png') no-repeat right center;
}

Images

: (loading & sorting images)

2. paging & sorting with ajax

It is slightly different from the way we implemented for postbacks.

View:

Index.cshtml, it renders the partial view which is the grid itself

a. specify the target div with id “gridcontainer” and loading div id “loadingcontainer”

b. render the partial view and pass model to it

@model MvcPaging.IPagedList<PagingSorting.Web.Models.People>
<div id="gridcontainer">
@Html.Partial("PeopleGridPartial",Model)
</div>

<div id="loadingcontainer">
</div>

PeopleGridPartial.cshtml

a. using Ajax.ActionLink override method to create clickable column heading

b. UpdateTargetId & LoadingElementId must be same as the div IDs you defined in above view.

c. using Ajax.Pager override method to create the ajax paging links

@model MvcPaging.IPagedList<PagingSorting.Web.Models.People>
@using MvcPaging

<table class="grid">
<thead>
<tr>
<th>@Ajax.ActionLink("Id", "AjaxPeople", Model, new AjaxOptions { UpdateTargetId = "gridcontainer", LoadingElementId = "loadingcontainer" })</th>
<th>@Ajax.ActionLink("Username", "AjaxPeople", Model, new AjaxOptions { UpdateTargetId = "gridcontainer", LoadingElementId = "loadingcontainer" })</th>
<th>@Ajax.ActionLink("Age", "AjaxPeople", Model, new AjaxOptions { UpdateTargetId = "gridcontainer", LoadingElementId = "loadingcontainer" })</th>
</tr>
</thead>
<tbody>
@foreach (var i in Model) {
<tr>
<td>@i.Id</td>
<td>@i.Username</td>
<td>@i.Age</td>
</tr>
}
</tbody>
</table>

<div class="pager">
 @Ajax.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount, Model.SortBy, Model.SortDescending, "AjaxPeople", new AjaxOptions { UpdateTargetId = "gridcontainer", LoadingElementId = "loadingcontainer" })
</div>

Controller Action:

a. AjaxPeople is taken care of by unobtrusive-ajax, to refresh the UpdateTargetId div

b. I make the thread sleep for 500ms, so you can see the loading screen. (remove it in production)

[HttpGet]
public ActionResult Index()
{
var option = new PagingOption { Page = 0, PageSize = PageSize };
var items = PeopleList.ToPagedList(option);
return View(items);
}

[HttpGet]
public ActionResult AjaxPeople(int? Page, string SortBy, bool? SortDescending)
{
int currentPageIndex = Page.HasValue ? Page.Value - 1 : 0;
var option = new PagingOption { Page = currentPageIndex, PageSize = PageSize, SortBy = SortBy, SortDescending = SortDescending };
var items = PeopleList.ToPagedList(option);

System.Threading.Thread.Sleep(500);

return PartialView("PeopleGridPartial", items);
}

_Layout.cshtml

You need to reference the unobtrusive-ajax.min.js

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

—————————————–

You can download the example here: https://itsharp-mvc-pagingsorting.googlecode.com/svn/trunk/

Advertisements

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