ASP.NET MVC Paging Helper Function


As we know ASP.NET MVC is built on top of asp.net but it doesn't support the asp.net controls. A valid statement about MVC is it don't support postback, viewstate concepts. This is one disadvantage of MVC after we have seen rich controls and its capabilities in ASP.NET. Developers have to write every Piece of code. This has led to write some custom generic methods to generate html which represents a control. In MVC we have some basic methods called HTML Helper functions. This has methods which generates html that corresponds to basic HTML controls. Over the time community has developed their own Html Helper methods.

MVCcontrib is an open source project to enhance the MVC framework by adding the rich features. This has UI helpers for Grid and Its Pagination. These Helpers will work on the Model classes. One disadvantage with them is complete data for the grid should be available beforehand. This is difficult to maintain if the data is more. It's always good to load the data that is required to render on the page.
I want something simple and work as loosely coupled control. I have created an html helper method. This method named PagingHelper is an extension method of HTMLHelper class. I have two versions of this one normal and other supports Ajax requests. The control looks like below images




How to integrate to your Solution
  1. Create a stored procedure with following parameters
    1. Input
      1. Output records criteria, which returns the records
      2. Total number of records to be displayed
      3. Current Page number
    2. output
      1. Total number of pages for the above criteria
      2. Select statement which return the records with the criteria for the sent page number
  2. Create a property in the controller
SetPageIndex proerty

private int SetPageIndex()
{
int page = 1;

if (Request.QueryString["page"] != null)
{
  if (Int32.TryParse(Request.QueryString["page"], out page))
{
     ViewData["IndexPage"] = Request.QueryString["page"];
   }
}
return page;

} 

  1. Create an action method in a controller
    1. Create a Action Method which handles the grid or paging
    2. ViewData["IndexPage"]=this.SetPageIndex(). Use this value in the view.
  2. Copy the below extension method to you application
    1. Copy the extension methods to a static class
  3. Use the helper method in the View page
    1. Import the namespace of the above static class in the view
    2. Use the blow code to call the view
    <%= Html.PagingHelper("Controllername", "actionMethodname", ViewData["TotalPages"], Convert.ToInt32(ViewData["IndexPage"]))%>
     
  4. Create Css paging styles
CSS Styles
a.paginglink:link
{
padding: 3px;

font-weight: bold;

text-decoration: none;

}

.pagingSelectedlink
{
border-style: solid;

border-width: thin;

border-color: black;

padding: 3px;

background-color: #C0C0C0;
text-decoration: none;

}

  1. URL Format generate
The URL that is generated is in the below format. The paging values goes as query strings because I believe non functional data like paging, sorting should go as querystrings
http://%3crootapplication%3e/PageAction?page=5

HtmlHelper Extension Method

public static string PagingHelper(this HtmlHelper hlp, string ActionName, string strControllerName, int intTotalPages, int intSelected, string pagelinkCssClass, string pagelinkCssClassSelected)
{

StringBuilder str = new StringBuilder();

str.Append("&nbsp;");

if (intTotalPages > 1)

{

int _rlow, _rhi;

int _prev, _next;

int _first = 1;

int _last = intTotalPages;


//low

if (intSelected < 5)

  _rlow = intSelected - (intSelected % 5) + 1;
else
if (intSelected % 5 == 0)

  _rlow = (intSelected - 5) + 1;
else

_rlow = intSelected - (intSelected % 5) + 1;

//this is previous

if (intSelected == 1)

{
_prev = 0; // no need to show prev link
_first = 0; //no need to show first link
}
else{  if (_rlow == 1){
    _prev = 1;
   }
  else
{
   _prev = _rlow - 1;
   }
str.Append(hlp.ActionLink("<<", ActionName, strControllerName,
                         new { page = _first }, new { @class = pagelinkCssClass }));

str.Append("&nbsp;");
str.Append(hlp.ActionLink("<", ActionName, strControllerName,
                         new { page = _prev }, new { @class = pagelinkCssClass }));

str.Append("&nbsp;");
str.Append("&nbsp;");
str.Append("&nbsp;");
}

 if (intSelected % 5 == 0)
{
_rhi = intSelected;
}
else

{
_rhi = intSelected + (5 - (intSelected % 5));
}
 
//high

if (_rhi > intTotalPages)

{
_rhi = intTotalPages;
}


for (int i = _rlow; i <= _rhi; i++)

{
object objAttrib = null;


if (i == intSelected)
{
objAttrib = new { @class = " pagelinkCssClassSelected" };
}
else
{
objAttrib = new { @class = " pagelinkCssClass" };
}
str.Append(hlp.ActionLink(i.ToString(), ActionName, strControllerName,
                          new { page = i }, objAttrib));str.Append("&nbsp;");
}

//this is next

if (intSelected == intTotalPages)
{_next = 0; //no need to show the next link
_last = 0; //no need to show the last link
}
else

{
_next = intSelected + 1;
str.Append("&nbsp;");
str.Append("&nbsp;");
str.Append("&nbsp;");
str.Append(hlp.ActionLink(">", ActionName, strControllerName,
                         new { page = _next }, new { @class = pagelinkCssClass }));

str.Append("&nbsp;");
str.Append(hlp.ActionLink(">>", ActionName, strControllerName,
                         new { page = _last }, new { @class = pagelinkCssClass }));

}
}
return str.ToString();

}

You can create an AJAX version of the same thing by changing HtmlHelper.ActionLink to AjaxHelper.ActionLink

Other recommendations
  1. Create a Pager HTML Helper by Stephen walther http://stephenwalther.com/blog/archive/2008/09/18/asp-net-mvc-tip-44-create-a-pager-html-helper.aspx
  2. Add Paging Functionality to your ASP.NET MVC Site http://www.devproconnections.com/article/aspnet/Add-Paging-Functionality-to-your-ASP-NET-MVC-Site.aspx

1 comment: