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
using System; using System.IO; using System.Text; using System.Xml.Linq;
namespace Valentica.Libraries { public enum PaginationType { Default,
DefaultWithItemRight,
DefaultWithItemLeft,
PreviousNext,
PreviousNextItemRight,
PreviousNextItemLeft,
PreviousNextItemCenter,
FirstPreviousNextLast,
FirstPreviousNextLastItemRight,
FirstPreviousNextLastItemLeft,
FirstPreviousNextLastItemCenter,
Number,
NumberWithItemRight,
NumberWithItemLeft }
public enum PaginationActionMethod { Get, Post }
public enum ItemTypes { Item,
Page,
Digit }
public class Pagination { #region Private Properties
#region General Properties
private int _perPage = 10; private int _numLinks = 2; #endregion
#region Link Properties
private string _firstLink = "‹ First"; private string _nextLink = ">"; private string _prevLink = "<"; private string _lastLink = "Last ›";
#endregion
#region Tag Properties
private string _fullTagOpen = ""; private string _fullTagClose = ""; private string _firstTagOpen = ""; private string _firstTagClose = " "; private string _lastTagOpen = " "; private string _lastTagClose = ""; private string _curTagOpen = " <b>"; private string _curTagClose = "</b>"; private string _nextTagOpen = " "; private string _nextTagClose = " "; private string _prevTagOpen = " "; private string _prevTagClose = ""; private string _numTagOpen = " "; private string _numTagClose = ""; private string _itemTagOpen = "<strong> "; private string _itemTagClose = "</strong> ";
private static bool _useFormPost = false; #endregion
private ItemTypes _itemType = ItemTypes.Item;
#endregion
#region Public Property Accessors
#region General Property Accessors public string BaseUrl { get; set; }
public int TotalRows { get; set; }
public int PerPage { get { return _perPage; } set { _perPage = value; } }
public int NumLinks { get { return _numLinks; } set { _numLinks = value; } }
public int CurPage { get; set; }
#endregion
#region Link Property Accessors
public string FirstLink { get { return _firstLink; } set { _firstLink = value; } }
public string NextLink { get { return _nextLink; } set { _nextLink = value; } }
public string PrevLink { get { return _prevLink; } set { _prevLink = value; } }
public string LastLink { get { return _lastLink; } set { _lastLink = value; } }
#endregion
#region Tag Property Accessors
public string FullTagOpen { get { return _fullTagOpen; } set { _fullTagOpen = value; } }
public string FullTagClose { get { return _fullTagClose; } set { _fullTagClose = value; } }
public string FirstTagOpen { get { return _firstTagOpen; } set { _firstTagOpen = value; } }
public string FirstTagClose { get { return _firstTagClose; } set { _firstTagClose = value; } }
public string LastTagOpen { get { return _lastTagOpen; } set { _lastTagOpen = value; } }
public string LastTagClose { get { return _lastTagClose; } set { _lastTagClose = value; } }
public string CurTagOpen { get { return _curTagOpen; } set { _curTagOpen = value; } }
public string CurTagClose { get { return _curTagClose; } set { _curTagClose = value; } }
public string NextTagOpen { get { return _nextTagOpen; } set { _nextTagOpen = value; } }
public string NextTagClose { get { return _nextTagClose; } set { _nextTagClose = value; } }
public string PrevTagOpen { get { return _prevTagOpen; } set { _prevTagOpen = value; } }
public string PrevTagClose { get { return _prevTagClose; } set { _prevTagClose = value; } }
public string NumTagOpen { get { return _numTagOpen; } set { _numTagOpen = value; } }
public string NumTagClose { get { return _numTagClose; } set { _numTagClose = value; } }
public string ItemTagOpen { get { return _itemTagOpen; } set { _itemTagOpen = value; } }
public string ItemTagClose { get { return _itemTagClose; } set { _itemTagClose = value; } }
#endregion
public ItemTypes ItemType { get { return _itemType; } set { _itemType = value; } }
#endregion
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); }
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
public string GetPageLinks() { return this.GetPageLinks(PaginationType.Default); }
public bool UseFormPost { get { return _useFormPost; } set { _useFormPost = value;} }
public string GetPageLinks(PaginationType pageType) { if (!this.IsValidSettings()) return "";
if (!this.BaseUrl.Trim().EndsWith("/") && !_useFormPost) this.BaseUrl = this.BaseUrl + "/";
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(); }
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); }
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;
}
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); } 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
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; } }
private bool IsValidSettings() { if (this.TotalRows == 0 && this.PerPage == 0) return false;
this.NumPages = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(this.TotalRows) / Convert.ToDouble(this.PerPage)));
if (NumPages == 1) return false;
if (this.CurPage == 0) return false;
if (((this.CurPage - 1) * this.PerPage) > this.TotalRows) return false;
return true; }
private void BuildFirstLink(StringBuilder pageLink, bool isDefault) { if (isDefault) { if (this.CurPage > this.NumLinks) { pageLink.Append(this.FirstTagOpen); if (_useFormPost) { 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) { 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); } }
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) { 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) { 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); } }
private void BuildDigitLink(StringBuilder pageLink) { 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) { if (this.CurPage == loop) { pageLink.Append(this.CurTagOpen); pageLink.Append(loop); pageLink.Append(this.CurTagClose); } else { pageLink.Append(this.NumTagOpen); if (_useFormPost) { 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); } } } }
private void BuildNextLink(StringBuilder pageLink, bool isDefault) { if (isDefault) { if (this.CurPage < NumPages) { pageLink.Append(this.NextTagOpen); if (_useFormPost) { 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) { 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); } }
private void BuildLastLink(StringBuilder pageLink, bool isDefault) { if (isDefault) { if ((this.CurPage + this.NumLinks) < NumPages) { pageLink.Append(this.LastTagOpen); if (_useFormPost) { 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) { 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); } }
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); }
private void BuildDefaultLink(StringBuilder pageLink) { this.BuildFirstLink(pageLink, true); this.BuildPreviousLink(pageLink, true); this.BuildDigitLink(pageLink); this.BuildNextLink(pageLink, true); this.BuildLastLink(pageLink, true); }
private void BuildPreviousNextLink(StringBuilder pageLink) { this.BuildPreviousLink(pageLink, false); this.BuildNextLink(pageLink, false); }
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); document.getElementById("GridPage").innerHTML = domElement.find("#GridPage").html(); }, 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!
|