Click here to Skip to main content
15,881,882 members
Articles / Web Development / ASP.NET
Article

Pagination Class for ASP.NET MVC

Rate me:
Please Sign up or sign in to vote.
4.38/5 (17 votes)
15 Aug 2008CPOL3 min read 104.7K   6.4K   37   13
A class for creating different types of pagination link in ASP.NET MVC.
pagination.jpg

Introduction

I was looking for a pagination class to use in ASP.NET MVC. I found ASP.NET MVC: PagedList<T> and ASP.NET MVC - Pagination View User Control. But I wanted an easier and customizable pagination class. I have developed many projects using the CodeIgniter framework and that time I found their pagination class is better and easier to use. So, I have decided to prepare a pagination class like this for ASP.NET MVC.

Using the Code

Controller

In your controller, to get your current (i.e. selected) page number page put this code snippet.

C#
string pageString = "";

try
{
    pageString = Request.Url.Segments[3];
}
catch (Exception)
{
    pageString = null;
}

int page = (String.IsNullOrEmpty(pageString)) ? 1 : Int32.Parse(pageString);

Here 3 is the segment which holds the page number. It can vary as per your URL.

Then use the pagination class as shown in the following example.

C#
Pagination pagination = new Pagination();

pagination.BaseUrl      = "/Users/List/";
pagination.TotalRows    = totalRows;
pagination.CurPage      = page;
pagination.PerPage      = 10;

string pageLinks = pagination.GetPageLinks();

int start   = (page - 1) * pagination.PerPage;
int offset  = pagination.PerPage;

In BaseUrl you can write a full path like http://www.sitename.com/Controller/Action/ or relative path like /Controller/Action/. Here start is the number from which row should be counted and offset is the number of rows that should be returned. totalRows is the total number of rows.

Now you can use this pageLinks string which is the generated page link.

Next, set your data in the ViewData like the following.

C#
ViewData["title"]       = "Pagination in Asp.Net Mvc";
ViewData["totalRows"]   = totalRows;
ViewData["result"]      = result;
ViewData["pageLinks"]   = pageLinks;

Here, totalRows is the total number of rows and result is the desired resultset.

View

In view page, you can show the page link as follows:

C#
<% if ((string)ViewData["pageLinks"] != "")
   { %>

   <%= ViewData["pageLinks"] %>
   <br /><br />
<% } %>

Model

You can create a model and make two methods to get total rows and the data from table using LINQ, as shown in the following example.

public int GetTotalUsers()
{
    return new MyDataContext().Users.Count();
}

public List<User> GetUsers(int start, int offset)
{
    var users = new MyDataContext().Users.Skip(start)
                                         .Take(offset);

    return users.ToList();
}

Configuration Settings

General Properites
BaseUrlFull or relative URL to the controller/action (Mandatory).
TotalRowsTotal number of rows in your resultset (Mandatory).
CurPageCurrent page number, default 1 (Mandatory).
PerPageNumber of items you want to show per page (Optional).
NumLinksNumber of "digit" links before and after the current page number (Optional).
ItemTypeItem type enumeration value (Optional).
Link Properites
FirstLinkThe text to be shown in the "first" link on the left.
NextLinkThe text to be shown in the "next" page link.
PrevLinkThe text to be shown in the "previous" page link.
LastLinkThe text to be shown in the "last" link on the right.
Tag Properties
FullTagOpenThe opening tag placed on the left side of the entire result.
FullTagCloseThe closing tag placed on the right side of the entire result.
FirstTagOpenThe opening tag for the "first" link.
FirstTagCloseThe closing tag for the "first" link.
LastTagOpenThe opening tag for the "last" link.
LastTagCloseThe closing tag for the "last" link.
CurTagOpenThe opening tag for the "current" link.
CurTagCloseThe closing tag for the "current" link.
NextTagOpenThe opening tag for the "next" link.
NextTagCloseThe closing tag for the "next" link.
PrevTagOpenThe opening tag for the "previous" link.
PrevTagCloseThe closing tag for the "previous" link.
NumTagOpenThe opening tag for the "digit" link.
NumTagCloseThe closing tag for the "digit" link.
ItemTagOpenThe opening tag for the "Item".
ItemTagCloseThe closing tag for the "Item".

You can set configuration settings in three ways.

  1. Set as regular property is set. Example:
    objPagination.PerPage  = 10;
    objPagination.PrevLink = "Prev";
    objPagination.NextLink = "Next";
  2. Put a Pagination.xml file in Content folder and create object of Pagination class as:
    C#
    Pagination objPagination = new Pagination(true);

    Pagination.xml file should be as following pattern as example.

    XML
    <?xml version="1.0" encoding="utf-8" ?>
    <Pagination>
        <NumLinks><![CDATA[5]]></NumLinks>
        <FullTagOpen><![CDATA[<p class='pagination'>]]></FullTagOpen>
    
        <FullTagClose><![CDATA[</p>]]></FullTagClose>
        <CurTagOpen><![CDATA[<span class='current'>]]></CurTagOpen>
        <CurTagClose><![CDATA[</span>]]></CurTagClose>
    
    </Pagination>
  3. Create any XML file like the above Pagination.xml file and call the method LoadPaginationXml with the file full path as argument. Example:
    C#
    objPagination.LoadPaginationXml("C:\\MyProject\\MyPagination.xml");

Different Types of Pagination

By this pagination class you can build different types of page links for your page. Just call the method GetPageLinks with your desired PaginationType as an argument. Example:

C#
objPagination.GetPageLinks(PaginationType.FirstPreviousNextLastItemRight);

You can display item set or item type as follows:

C#
objPagination.ItemType = ItemTypes.Page;

Conclusion

I think thats enough to use this pagination class easily. Bye for this time.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Bangladesh Bangladesh
Software Engineer, Bangladesh.

Comments and Discussions

 
QuestionThis is a good article to know how to do pagination class for ASP.NET mvc Pin
Member 1040443918-Nov-13 9:02
Member 1040443918-Nov-13 9:02 
QuestionEdit compoment pageLink? Pin
cuonghd1-Aug-13 4:51
cuonghd1-Aug-13 4:51 
QuestionI need to Hide Next and Prev Button. How can i do that Pin
Trung Dũng9-Jul-13 0:15
Trung Dũng9-Jul-13 0:15 
GeneralMy vote of 5 Pin
Member 776842615-Jan-13 22:04
Member 776842615-Jan-13 22:04 
GeneralMy vote of 4 Pin
congnthc14-Sep-12 5:19
congnthc14-Sep-12 5:19 
QuestionError in Example Pin
Ragesh S9-Feb-12 18:20
Ragesh S9-Feb-12 18:20 
Generalhey, where is the db of the sample project? Pin
PatoOrange13-May-11 5:42
PatoOrange13-May-11 5:42 
GeneralDatabase error Pin
DeepakRohilla1317-Sep-10 0:30
professionalDeepakRohilla1317-Sep-10 0:30 
GeneralMvcPager is another choice Pin
Webdiyer23-Feb-10 19:49
Webdiyer23-Feb-10 19:49 
GeneralModified your class for post action Pin
PikesvillePaesano24-Jun-09 3:50
PikesvillePaesano24-Jun-09 3:50 
Hello, I made some changes to my customization to support form posts the original pagination uses GET which won't help page a filtered list (unless I missed something), so I added pagination for form posts.

1. Alter the class to support post types
2. Add ajax to post the form
3. Call the class with PaginationActionMethod.Post

Step 1: replace the pagination.cs file
// ********************************************************************
// Document     : Pagination.cs
// Version      : 1.0
// Category     : Libraries
// Description  : This is a pagination class for creating different types 
//                of page links.
// Author       : Mohammad Jahedur Rahman
// Contributors : 
//              : James Fleming: Form Post method of Pagination  6/24/2009
//              :
// Date         : 08/03/2008
// Copyright    : Copyright (c) Valentica. All rights reserved.
// ********************************************************************

using System;
using System.IO;
using System.Text;
using System.Xml.Linq;

namespace Valentica.Libraries
{
    /// <summary>
    /// Pagination type enumeration
    /// </summary>
    public enum PaginationType
    {
        /// <summary>
        /// Default page link
        /// </summary>
        Default,

        /// <summary>
        /// Default page link with item on the right 
        /// </summary>
        DefaultWithItemRight,

        /// <summary>
        /// Default page link with item on the left
        /// </summary>
        DefaultWithItemLeft,

        /// <summary>
        /// Previous, next page link
        /// </summary>
        PreviousNext,

        /// <summary>
        /// Previous, next page link with item on the right
        /// </summary>
        PreviousNextItemRight,

        /// <summary>
        /// Previous, next page link with item on the left
        /// </summary>
        PreviousNextItemLeft,

        /// <summary>
        /// Previous, next page link with item on the center
        /// </summary>
        PreviousNextItemCenter,

        /// <summary>
        /// First, previous, next, last page link
        /// </summary>
        FirstPreviousNextLast,

        /// <summary>
        /// First, previous, next, last page link with item on the right
        /// </summary>
        FirstPreviousNextLastItemRight,

        /// <summary>
        /// First, previous, next, last page link with item on the left
        /// </summary>
        FirstPreviousNextLastItemLeft,

        /// <summary>
        /// First, previous, next, last page link with item on the center
        /// </summary>
        FirstPreviousNextLastItemCenter,

        /// <summary>
        /// Number page link
        /// </summary>
        Number,

        /// <summary>
        /// Number page link with item on the right
        /// </summary>
        NumberWithItemRight,

        /// <summary>
        /// Number page link with item on the left
        /// </summary>
        NumberWithItemLeft
    }

    // James Fleming added: 6/24/2009
    public enum PaginationActionMethod 
    {
        Get,
        Post        
    }

    /// <summary>
    /// Item type enumeration
    /// </summary>
    public enum ItemTypes
    {
        /// <summary>
        /// Displaying (n) to (n) of (n) Items
        /// </summary>
        Item,

        /// <summary>
        /// Page (n) of (n)
        /// </summary>
        Page,

        /// <summary>
        /// (n)/(n)
        /// </summary>
        Digit
    }

    /// <summary>
    /// Pagination class
    /// </summary>
    public class Pagination
    {
        #region Private Properties

        #region General Properties

        private int     _perPage         = 10;   // Max number of items you want shown per page
        private int     _numLinks        = 2;    // Number of "digit" links to show before/after the currently viewed page

        #endregion

        #region Link Properties

        private string  _firstLink       = "&lsaquo; First";
        private string  _nextLink        = "&gt;";
        private string  _prevLink        = "&lt;";
        private string  _lastLink        = "Last &rsaquo;";

        #endregion

        #region Tag Properties

        private string  _fullTagOpen     = "";
        private string  _fullTagClose    = "";
        private string  _firstTagOpen    = "";
        private string  _firstTagClose   = "&nbsp;";
        private string  _lastTagOpen     = "&nbsp;";
        private string  _lastTagClose    = "";
        private string  _curTagOpen      = "&nbsp;<b>";
        private string  _curTagClose     = "</b>";
        private string  _nextTagOpen     = "&nbsp;";
        private string  _nextTagClose    = "&nbsp;";
        private string  _prevTagOpen     = "&nbsp;";
        private string  _prevTagClose    = "";
        private string  _numTagOpen      = "&nbsp;";
        private string  _numTagClose     = "";
        private string  _itemTagOpen     = "<strong>&nbsp;&nbsp;";
        private string  _itemTagClose    = "</strong>&nbsp;&nbsp;";

        private static bool _useFormPost = false;     // James Fleming added: 6/24/2009
        #endregion

        private ItemTypes _itemType = ItemTypes.Item;

        #endregion

        #region Public Property Accessors

        #region General Property Accessors
    
        /// <summary>
        /// Gets or sets url to controller/action.
        /// </summary>
        public string BaseUrl { get; set; }

        /// <summary>
        /// Gets or sets the total rows in the result set.
        /// </summary>
        public int TotalRows { get; set; }

        /// <summary>
        /// Gets or sets the number item per page.
        /// </summary>
        public int PerPage
        {
            get { return _perPage; }
            set { _perPage = value; }
        }

        /// <summary>
        /// Gets or sets the number of "digit" links before and after the selected page number.
        /// </summary>
        public int NumLinks
        {
            get { return _numLinks; }
            set { _numLinks = value; }
        }

        /// <summary>
        /// Gets or sets the current selected page.
        /// </summary>
        public int CurPage { get; set; }

        #endregion

        #region Link Property Accessors

        /// <summary>
        /// Gets or sets the text to be shown in the "first" link on the left.
        /// </summary>
        public string FirstLink
        {
            get { return _firstLink; }
            set { _firstLink = value; }
        }

        /// <summary>
        /// Gets or sets the text to be shown in the "next" page link.
        /// </summary>
        public string NextLink
        {
            get { return _nextLink; }
            set { _nextLink = value; }
        }

        /// <summary>
        /// Gets or sets the text to be shown in the "previous" page link.
        /// </summary>
        public string PrevLink
        {
            get { return _prevLink; }
            set { _prevLink = value; }
        }

        /// <summary>
        /// Gets or sets the text to be shown in the "last" link on the right.
        /// </summary>
        public string LastLink
        {
            get { return _lastLink; }
            set { _lastLink = value; }
        }

        #endregion

        #region Tag Property Accessors

        /// <summary>
        /// Gets or sets the opening tag placed on the left side of the entire result.
        /// </summary>
        public string FullTagOpen
        {
            get { return _fullTagOpen; }
            set { _fullTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag placed on the right side of the entire result.
        /// </summary>
        public string FullTagClose
        {
            get { return _fullTagClose; }
            set { _fullTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "first" link.
        /// </summary>
        public string FirstTagOpen
        {
            get { return _firstTagOpen; }
            set { _firstTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "first" link.
        /// </summary>
        public string FirstTagClose
        {
            get { return _firstTagClose; }
            set { _firstTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "last" link.
        /// </summary>
        public string LastTagOpen
        {
            get { return _lastTagOpen; }
            set { _lastTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "last" link.
        /// </summary>
        public string LastTagClose
        {
            get { return _lastTagClose; }
            set { _lastTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "current" link.
        /// </summary>
        public string CurTagOpen
        {
            get { return _curTagOpen; }
            set { _curTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "current" link.
        /// </summary>
        public string CurTagClose
        {
            get { return _curTagClose; }
            set { _curTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "next" link.
        /// </summary>
        public string NextTagOpen
        {
            get { return _nextTagOpen; }
            set { _nextTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "next" link.
        /// </summary>
        public string NextTagClose
        {
            get { return _nextTagClose; }
            set { _nextTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "previous" link.
        /// </summary>
        public string PrevTagOpen
        {
            get { return _prevTagOpen; }
            set { _prevTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "previous" link.
        /// </summary>
        public string PrevTagClose
        {
            get { return _prevTagClose; }
            set { _prevTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "digit" link.
        /// </summary>
        public string NumTagOpen
        {
            get { return _numTagOpen; }
            set { _numTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "digit" link.
        /// </summary>
        public string NumTagClose
        {
            get { return _numTagClose; }
            set { _numTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "Item".
        /// </summary>
        public string ItemTagOpen
        {
            get { return _itemTagOpen; }
            set { _itemTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "Item".
        /// </summary>
        public string ItemTagClose
        {
            get { return _itemTagClose; }
            set { _itemTagClose = value; }
        }

        #endregion

        /// <summary>
        /// Gets or sets the item type.
        /// </summary>
        public ItemTypes ItemType
        {
            get { return _itemType; }
            set { _itemType = value; }
        }

        #endregion

        /// <summary>
        /// Gets or sets the total number of pages
        /// </summary>
        private int NumPages { get; set; }

        #region Public Constructors

        public Pagination()
        {
        }

        public Pagination(bool loadFromXml)
        {
            if (!loadFromXml)
            {
                return;
            }
  
            string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Content\Pagination.xml");

            this.LoadPaginationXml(file);                
        }

        /// <summary>
        /// Load the Pagination Configuration from Xml
        /// </summary>
        /// <param name="xmlFile">string, Pagination.xml File Path</param>
        public void LoadPaginationXml(string xmlFile)
        {
            XElement element;

            try
            {
                element = XElement.Load(xmlFile);

                var properties = element.Elements();

                foreach (var property in properties)
                {
                    SetPaginationSettings(property.Name.ToString(), property.Value);
                }
            }
            catch (FileNotFoundException)
            {

            }
            catch (Exception)
            {

            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Get the page links
        /// </summary>
        /// <returns>Page link string</returns>
        public string GetPageLinks()
        {
            return this.GetPageLinks(PaginationType.Default);
        }

        public bool UseFormPost
        {
            get { return _useFormPost; }
            set { _useFormPost = value;}
        }

        /// <summary>
        /// Get the page links
        /// </summary>
        /// <param name="pageType">Pagination type</param>
        /// <returns>Page link string</returns>
        public string GetPageLinks(PaginationType pageType)
        {
            // If anything invalid
            if (!this.IsValidSettings())
                return "";

            // Add a trailing slash to the base URL if needed
            if (!this.BaseUrl.Trim().EndsWith("/") && !_useFormPost)
                this.BaseUrl = this.BaseUrl + "/";

            // And here we go...
            StringBuilder pageLink = new StringBuilder();

            switch (pageType)
            {
                case PaginationType.Default:
                    this.BuildDefaultLink(pageLink);
                    break;

                case PaginationType.DefaultWithItemRight:
                    this.BuildDefaultLink(pageLink);
                    this.BuildItemLink(pageLink);
                    break;

                case PaginationType.DefaultWithItemLeft:
                    this.BuildItemLink(pageLink);
                    this.BuildDefaultLink(pageLink);
                    break;

                case PaginationType.PreviousNext:
                    this.BuildPreviousNextLink(pageLink);
                    break;

                case PaginationType.PreviousNextItemRight:
                    this.BuildPreviousNextLink(pageLink);
                    this.BuildItemLink(pageLink);
                    break;

                case PaginationType.PreviousNextItemLeft:
                    this.BuildItemLink(pageLink);
                    this.BuildPreviousNextLink(pageLink);
                    break;

                case PaginationType.PreviousNextItemCenter:
                    this.BuildPreviousLink(pageLink, false);
                    this.BuildItemLink(pageLink);
                    this.BuildNextLink(pageLink, false);
                    break;

                case PaginationType.FirstPreviousNextLast:
                    this.BuildFirstPreviousNextLastLink(pageLink);
                    break;

                case PaginationType.FirstPreviousNextLastItemRight:
                    this.BuildFirstPreviousNextLastLink(pageLink);
                    this.BuildItemLink(pageLink);
                    break;

                case PaginationType.FirstPreviousNextLastItemLeft:
                    this.BuildItemLink(pageLink);
                    this.BuildFirstPreviousNextLastLink(pageLink);
                    break;

                case PaginationType.FirstPreviousNextLastItemCenter:
                    this.BuildFirstLink(pageLink, false);
                    this.BuildPreviousLink(pageLink, false);
                    this.BuildItemLink(pageLink);
                    this.BuildNextLink(pageLink, false);
                    this.BuildLastLink(pageLink, false);
                    break;

                case PaginationType.Number:
                    this.BuildDigitLink(pageLink);
                    break;

                case PaginationType.NumberWithItemRight:
                    this.BuildDigitLink(pageLink);
                    this.BuildItemLink(pageLink);
                    break;

                case PaginationType.NumberWithItemLeft:
                    this.BuildItemLink(pageLink);
                    this.BuildDigitLink(pageLink);
                    break;

                default:
                    this.GetPageLinks(PaginationType.Default);
                    break;
            }

            pageLink.Insert(0, this.FullTagOpen);
            pageLink.Append(this.FullTagClose);

            return pageLink.ToString();
        }

        // James Fleming added: 6/24/2009
        public static string Paging(string baseUrl,  String[] segments, int totalRows, out int skip, out int take)
        {
            //*******************************

            string pageString = "";
            try
            {
                pageString = segments[3];
            }
            catch (Exception)
            {
                pageString = null;                
            }

            int page = (String.IsNullOrEmpty(pageString)) ? 1 : Int32.Parse(pageString);

            return Paging(baseUrl,page, totalRows, out skip, out take);
        }

        /// <summary>
        /// James Fleming added: 6/24/2009
        /// </summary>
        /// <param name="baseUrl"></param>
        /// <param name="page"></param>
        /// <param name="totalRows"></param>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <returns></returns>
        public static string Paging(string baseUrl, int page, int totalRows, out int skip, out int take)
        {
            //*******************************

            Pagination pagination = new Pagination(true);
            pagination.BaseUrl = baseUrl;
            pagination.TotalRows = totalRows;
            pagination.CurPage = page;
            pagination.PerPage = 10;
            pagination.PrevLink = "Prev";
            pagination.NextLink = "Next";
            string pageLinks = pagination.GetPageLinks();

            skip = (page - 1) * pagination.PerPage;
            take = pagination.PerPage;

            return pageLinks;

        }

       /// <summary>
        /// James Fleming added: 6/24/2009
       /// </summary>
       /// <param name="baseUrl"></param>
       /// <param name="page"></param>
       /// <param name="totalRows"></param>
       /// <param name="skip"></param>
       /// <param name="take"></param>
       /// <param name="method"></param>
       /// <returns></returns>
        public static string Paging(string baseUrl, int page, int totalRows, out int skip, out int take, PaginationActionMethod method)
        {
            switch (method)
            {
                case PaginationActionMethod.Post:
                    _useFormPost = true;
                    break;
                default:
                    _useFormPost = false;
                    break;
            }
            return Paging(baseUrl, page, totalRows, out skip, out take);
        }
        /// <summary>
        /// James Fleming added: 6/24/2009
        /// </summary>
        /// <param name="baseUrl"></param>
        /// <param name="segments"></param>
        /// <param name="totalRows"></param>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <param name="method"></param>
        /// <returns></returns>
        public static string Paging(string baseUrl, String[] segments, int totalRows, out int skip, out int take,  PaginationActionMethod method)
        {
            switch (method)
            {
                case PaginationActionMethod.Post:
                    _useFormPost = true;
                    break;
                default:
                    _useFormPost = false;
                    break;
            }
            return Paging(baseUrl, segments, totalRows, out skip, out take);
        }
        #endregion

        #region Private Methods

        /// <summary>
        /// Set the Pagination Configuration Settings
        /// </summary>
        /// <param name="propertyName">Configuration Property Name</param>
        /// <param name="propertyValue">Configuration Property Value</param>
        private void SetPaginationSettings(string propertyName, string propertyValue)
        {
            switch (propertyName)
            {
                #region Set General Properties

                case "BaseUrl":
                    this.BaseUrl = propertyValue;
                    break;

                case "TotalRows":
                    this.TotalRows = Convert.ToInt32(propertyValue);
                    break;

                case "PerPage":
                    this.PerPage = Convert.ToInt32(propertyValue);
                    break;

                case "NumLinks":
                    this.NumLinks = Convert.ToInt32(propertyValue);
                    break;

                case "CurPage":
                    this.CurPage = Convert.ToInt32(propertyValue);
                    break;

                #endregion

                #region Set Link Properties

                case "FirstLink":
                    this.FirstLink = propertyValue;
                    break;

                case "NextLink":
                    this.NextLink = propertyValue;
                    break;

                case "PrevLink":
                    this.PrevLink = propertyValue;
                    break;

                case "LastLink":
                    this.LastLink = propertyValue;
                    break;

                #endregion

                #region Set Tag Properties

                case "FullTagOpen":
                    this.FullTagOpen = propertyValue;
                    break;

                case "FullTagClose":
                    this.FullTagClose = propertyValue;
                    break;

                case "FirstTagOpen":
                    this.FirstTagOpen = propertyValue;
                    break;

                case "FirstTagClose":
                    this.FirstTagClose = propertyValue;
                    break;

                case "LastTagOpen":
                    this.LastTagOpen = propertyValue;
                    break;

                case "LastTagClose":
                    this.LastTagClose = propertyValue;
                    break;

                case "CurTagOpen":
                    this.CurTagOpen = propertyValue;
                    break;

                case "CurTagClose":
                    this.CurTagClose = propertyValue;
                    break;

                case "NextTagOpen":
                    this.NextTagOpen = propertyValue;
                    break;

                case "NextTagClose":
                    this.NextTagClose = propertyValue;
                    break;

                case "PrevTagOpen":
                    this.PrevTagOpen = propertyValue;
                    break;

                case "PrevTagClose":
                    this.PrevTagClose = propertyValue;
                    break;

                case "NumTagOpen":
                    this.NumTagOpen = propertyValue;
                    break;

                case "NumTagClose":
                    this.NumTagClose = propertyValue;
                    break;

                #endregion

                default:
                    break;
            }
        }

        /// <summary>
        /// Check if everythings are ok
        /// </summary>
        /// <returns>Boolean</returns>
        private bool IsValidSettings()
        {
            // If our item count or per page total is zero there is no need to continue.
            if (this.TotalRows == 0 && this.PerPage == 0)
                return false;

            // Calculate the total number of pages
            this.NumPages = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(this.TotalRows) / Convert.ToDouble(this.PerPage)));

            // Is there only one page? Hm... nothing more to do here then.
            if (NumPages == 1)
                return false;

            // Is the current page equals to 0 then return
            if (this.CurPage == 0)
                return false;

            // Is the current page beyond the result range then return
            if (((this.CurPage - 1) * this.PerPage) > this.TotalRows)
                return false;

            return true;
        }

        /// <summary>
        /// Build the "First" link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        /// <param name="isDefault">bool, isDefault</param>
        private void BuildFirstLink(StringBuilder pageLink, bool isDefault)
        {
            if (isDefault)
            {
                if (this.CurPage > this.NumLinks)
                {
                    pageLink.Append(this.FirstTagOpen);
                    if (_useFormPost) // James Fleming added: 6/24/2009
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + "(1)" + "'>");
                    }
                    else
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + "1" + "'>");
                    }
                    pageLink.Append(this.FirstLink);
                    pageLink.Append("</a>");
                    pageLink.Append(this.FirstTagClose);
                }
            }
            else
            {
                pageLink.Append(this.FirstTagOpen);

                if (this.CurPage != 1)
                {
                    if (_useFormPost)// James Fleming added: 6/24/2009
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + "(1)" + "'>");
                    }
                    else
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + "1" + "'>");
                    }
                    pageLink.Append(this.FirstLink);
                    pageLink.Append("</a>");
                }
                else
                {
                    pageLink.Append(this.FirstLink);
                }

                pageLink.Append(this.FirstTagClose);
            }
        }

        /// <summary>
        /// Build the "Previous" link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        /// <param name="isDefault">bool, isDefault</param>
        private void BuildPreviousLink(StringBuilder pageLink, bool isDefault)
        {
            if (isDefault)
            {
                if ((this.CurPage - this.NumLinks) >= 0)
                {
                    int i = this.CurPage - 1;

                    if (i == 0) i = 1;

                    pageLink.Append(this.PrevTagOpen);
                    if (_useFormPost)// James Fleming added: 6/24/2009
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + "(" + Convert.ToString(i) + ")'>");
                    }
                    else
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(i) + "'>");
                    }
                    pageLink.Append(this.PrevLink);
                    pageLink.Append("</a>");
                    pageLink.Append(this.PrevTagClose);
                }
            }
            else
            {
                int i = this.CurPage - 1;

                pageLink.Append(this.PrevTagOpen);

                if (i > 0)
                {
                    if (_useFormPost)// James Fleming added: 6/24/2009
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + "(" + Convert.ToString(i) + ")'>");
                    }
                    else
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(i) + "'>");
                    }
                    pageLink.Append(this.PrevLink);
                    pageLink.Append("</a>");
                }
                else
                {
                    pageLink.Append(this.PrevLink);
                }

                pageLink.Append(this.PrevTagClose);
            }
        }

        /// <summary>
        /// Build the "Digits" link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        private void BuildDigitLink(StringBuilder pageLink)
        {
            // Calculate the start and end numbers. These determine
            // which number to start and end the digit links with
            int start = ((this.CurPage - this.NumLinks) > 0) ? this.CurPage - (this.NumLinks - 1) : 1;
            int end = ((this.CurPage + this.NumLinks) < NumPages) ? this.CurPage + this.NumLinks : NumPages;

            for (int loop = start - 1; loop <= end; loop++)
            {
                int i = (loop * this.PerPage) - this.PerPage;

                if (i >= 0)
                {
                    // Current page
                    if (this.CurPage == loop)
                    {
                        pageLink.Append(this.CurTagOpen);
                        pageLink.Append(loop);
                        pageLink.Append(this.CurTagClose);
                    }
                    else
                    {
                        pageLink.Append(this.NumTagOpen);
                        if (_useFormPost)// James Fleming added: 6/24/2009
                        {
                            pageLink.Append("<a href='" + this.BaseUrl + "(" + Convert.ToString(loop) + ")'>");
                        }
                        else
                        {
                            pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(loop) + "'>");
                        }
                        
                        pageLink.Append(loop);
                        pageLink.Append("</a>");
                        pageLink.Append(this.NumTagClose);
                    }
                }
            }
        }

        /// <summary>
        /// Build the "Next" Link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        /// <param name="isDefault">bool, isDefault</param>
        private void BuildNextLink(StringBuilder pageLink, bool isDefault)
        {
            if (isDefault)
            {
                if (this.CurPage < NumPages)
                {
                    pageLink.Append(this.NextTagOpen);
                    if (_useFormPost)// James Fleming added: 6/24/2009
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + "(" + Convert.ToString(this.CurPage + 1) + ")'>");
                    }
                    else
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(this.CurPage + 1) + "'>");
                    }
                    
                    pageLink.Append(this.NextLink);
                    pageLink.Append("</a>");
                    pageLink.Append(this.NextTagClose);
                }
            }
            else
            {
                int i = this.CurPage + 1;

                pageLink.Append(this.NextTagOpen);

                if (i <= NumPages)
                {
                    if (_useFormPost)// James Fleming added: 6/24/2009
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + "(" + Convert.ToString(i) + ")'>");
                    }
                    else
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(i) + "'>");
                    }
                    pageLink.Append(this.NextLink);
                    pageLink.Append("</a>");
                }
                else
                {
                    pageLink.Append(this.NextLink);
                }

                pageLink.Append(this.NextTagClose);
            }
        }

        /// <summary>
        /// Build the "Last" link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        /// <param name="isDefault">bool, isDefault</param>
        private void BuildLastLink(StringBuilder pageLink, bool isDefault)
        {
            if (isDefault)
            {
                if ((this.CurPage + this.NumLinks) < NumPages)
                {
                    pageLink.Append(this.LastTagOpen);
                    if (_useFormPost)// James Fleming added: 6/24/2009
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + "(" + Convert.ToString(NumPages) + ")'>");
                    }
                    else
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(NumPages) + "'>");
                    }
                    pageLink.Append(this.LastLink);
                    pageLink.Append("</a>");
                    pageLink.Append(this.LastTagClose);
                }
            }
            else
            {
                pageLink.Append(this.LastTagOpen);

                if (this.CurPage != NumPages)
                {
                    if (_useFormPost)// James Fleming added: 6/24/2009
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + "(" + Convert.ToString(NumPages) + ")'>");
                    }
                    else
                    {
                        pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(NumPages) + "'>");
                    }
                    pageLink.Append(this.LastLink);
                    pageLink.Append("</a>");
                }
                else
                {
                    pageLink.Append(this.LastLink);
                }

                pageLink.Append(this.LastTagClose);
            }
        }

        /// <summary>
        /// Build the "Item" link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        private void BuildItemLink(StringBuilder pageLink)
        {
            pageLink.Append(this.ItemTagOpen);

            if (this.ItemType == ItemTypes.Item)
            {
                int start   = (this.CurPage - 1) * this.PerPage + 1;
                int end     = this.CurPage * this.PerPage;
                
                end     = (end > this.TotalRows)? this.TotalRows : end; 

                pageLink.Append("Displaying " + start.ToString() + 
                                " to " + end.ToString() +
                                " of " + this.TotalRows.ToString() + " Items");
            }
            else if (this.ItemType == ItemTypes.Page)
                pageLink.Append("Page " + this.CurPage.ToString() + " of " + this.NumPages.ToString());
            else if (this.ItemType == ItemTypes.Digit)
                pageLink.Append(this.CurPage.ToString() + "/" + this.NumPages.ToString());

            pageLink.Append(this.ItemTagClose);
        }

        /// <summary>
        /// Build the Default link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        private void BuildDefaultLink(StringBuilder pageLink)
        {
            this.BuildFirstLink(pageLink, true);
            this.BuildPreviousLink(pageLink, true);
            this.BuildDigitLink(pageLink);
            this.BuildNextLink(pageLink, true);
            this.BuildLastLink(pageLink, true);
        }

        /// <summary>
        /// Build the PreviousNext link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        private void BuildPreviousNextLink(StringBuilder pageLink)
        {
            this.BuildPreviousLink(pageLink, false);
            this.BuildNextLink(pageLink, false);
        }

        /// <summary>
        /// Build the FirstPreviousNextLast link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        private void BuildFirstPreviousNextLastLink(StringBuilder pageLink)
        {
            this.BuildFirstLink(pageLink, false);
            this.BuildPreviousLink(pageLink, false);
            this.BuildNextLink(pageLink, false);
            this.BuildLastLink(pageLink, false);
        }
        #endregion
    }
}


Step 2: Create an AJAX form to post the form for you...
The code below assumes a strongly typed view page of type 'Client' with a SSN, FirstName, LastName textboxes in the form and results being displayed in a div with ID of 'GridPage' that contains the filtered grid & pagination control.

 <script type="text/javascript" language="javascript">
     function PageClient(pageNum) {
         var ssn = $("#SSN").attr("value");
         var fname = $("#FirstName").attr("value");
         var lname = $("#LastName").attr("value");
         $.ajax(
        {
            type: "POST",
            url: "/Client",
            data: "name=" + ssn + "&FirstName=" + fname + "&LastName=" + lname + "&PageNum=" + pageNum,
            dataType: "html",
            success: function(result) {
                var domElement = $(result); // create element from html
                document.getElementById("GridPage").innerHTML = domElement.find("#GridPage").html(); //domElement[60].children[2].childNodes[3].lastChild.outerHTML;

            },
            error: function(error) {
                alert(error);
            }
        });
    }
</script>


Step 3: process the input with the overloaded method.
 [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Index(Client client, string PageNum)
        {
            List<Client> model;
            int skip, take;
            int pageNumber;
            
            if (!string.IsNullOrEmpty(client.SSN) || !string.IsNullOrEmpty(client.FirstName) || !string.IsNullOrEmpty(client.LastName))
            {
                int count = _clientSvc.GetClientCollection().WithSSN(client.SSN).WithFirstName(client.FirstName).WithLastName(client.LastName).Count();
                if (!Int32.TryParse(PageNum, out pageNumber))
                {
                    ViewData["pageLinks"] = Pagination.Paging("#' onclick='return PageClient", Request.Url.Segments, count, out skip, out take, PaginationActionMethod.Post);
                }
                else
                {
                    ViewData["pageLinks"] = Pagination.Paging("#' onclick='return PageClient", pageNumber, count, out skip, out take, PaginationActionMethod.Post);
                }
                model = _clientSvc.GetClientCollection().WithSSN(client.SSN).WithFirstName(client.FirstName).WithLastName(client.LastName).Skip(skip).Take(take).ToList();
            }
            else
            {
                model = _clientSvc.GetClientCollection().ToList();
            }
.....
return View(model);
            }



I hope this helps others. Sorry if I can't offer more insight on the AJAX - it's my first attempt at using it.

Note: if you want to just use the parts I've changed, just do a search on 'James Fleming' in the code
Good Luck!
GeneralRe: Modified your class for post action Pin
Jahedur Rahman Chowdhury24-Jun-09 18:44
Jahedur Rahman Chowdhury24-Jun-09 18:44 
GeneralWell Done! You saved me tons of time. I put my own spin on it by creating a static method for calling the paging method. Pin
Pikesville Paesano11-Jun-09 17:19
Pikesville Paesano11-Jun-09 17:19 
GeneralRe: Well Done! You saved me tons of time. I put my own spin on it by creating a static method for calling the paging method. Pin
Jahedur Rahman Chowdhury11-Jun-09 20:54
Jahedur Rahman Chowdhury11-Jun-09 20:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.