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!
|