Skip to content

Instantly share code, notes, and snippets.

@bernos
Created October 21, 2013 08:35
Show Gist options
  • Save bernos/7080517 to your computer and use it in GitHub Desktop.
Save bernos/7080517 to your computer and use it in GitHub Desktop.
ASP.net MVC4 paginated lists
public virtual ActionResult Index(int page = 1, int pageSize = 10)
{
var work = UnitOfWork();
int total;
if (pageSize > MaxPageSize)
{
pageSize = MaxPageSize;
}
var models = work.Repository<TModel, TKey>()
.Query()
.OrderBy(Sort)
.GetPage(page, pageSize, out total);
return View(IndexView, new PaginatedList(Mapper.MapList(models).To<TListViewModel>())
{
CurrentPage = page,
ItemsPerPage = pageSize,
TotalItems = total
});
}
using System;
using System.Collections;
using System.Collections.Generic;
namespace TPTemplate.Web.ViewModels
{
public interface IPaginatedList
{
int TotalItems { get; set; }
int ItemsPerPage { get; set; }
int CurrentPage { get; set; }
int TotalPages { get; }
int? NextPage { get; }
int? PreviousPage { get; }
}
}
using System;
using System.Collections;
using System.Collections.Generic;
namespace TPTemplate.Web.ViewModels
{
public abstract class BasePaginatedList : IPaginatedList
{
public int TotalItems { get; set; }
public int ItemsPerPage { get; set; }
public int CurrentPage { get; set; }
public int TotalPages
{
get
{
return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage);
}
}
public int? NextPage
{
get
{
return (CurrentPage < TotalPages) ? CurrentPage + 1 : (int?)null;
}
}
public int? PreviousPage
{
get
{
return (CurrentPage > 1) ? CurrentPage - 1 : (int?)null;
}
}
}
public class PaginatedList : BasePaginatedList
{
public IEnumerable Items { get; set; }
public PaginatedList(IEnumerable items)
{
Items = items;
}
}
public class PaginatedList<T> : BasePaginatedList where T:class
{
public IEnumerable<T> Items { get; set; }
public PaginatedList(IEnumerable<T> items)
{
Items = items;
}
}
}
using System;
using System.Text;
using System.Web.Mvc;
using TPTemplate.Web.ViewModels;
namespace TPTemplate.Web.Extensions
{
public static class PaginationExtensions
{
public static MvcHtmlString PaginationLinksFor(this HtmlHelper html, IPaginatedList paginatedList,
Func<int, string> pageUrl, bool showFirstAndLast = true, bool showNextAndPrevious = true, int maxVisiblePages = 10)
{
var result = new StringBuilder();
var ul = new TagBuilder("ul");
ul.AddCssClass("pagination");
result.Append(ul.ToString(TagRenderMode.StartTag));
if (showFirstAndLast)
{
var firstPageLi = new TagBuilder("li");
var firstPageA = new TagBuilder("a");
firstPageA.MergeAttribute("href", pageUrl(1));
firstPageA.InnerHtml = "&laquo;";
if (paginatedList.CurrentPage == 1)
{
firstPageLi.AddCssClass("disabled");
}
result.Append(firstPageLi.ToString(TagRenderMode.StartTag));
result.Append(firstPageA.ToString(TagRenderMode.Normal));
result.Append(firstPageLi.ToString(TagRenderMode.EndTag));
}
if (showNextAndPrevious)
{
var previousPageLi = new TagBuilder("li");
var previousPageA = new TagBuilder("a");
previousPageA.MergeAttribute("href", pageUrl(paginatedList.CurrentPage > 1 ? paginatedList.CurrentPage - 1 : 1));
previousPageA.InnerHtml = "&lt;";
if (paginatedList.CurrentPage == 1)
{
previousPageLi.AddCssClass("disabled");
}
result.Append(previousPageLi.ToString(TagRenderMode.StartTag));
result.Append(previousPageA.ToString(TagRenderMode.Normal));
result.Append(previousPageLi.ToString(TagRenderMode.EndTag));
}
var start = 1;
if (paginatedList.TotalPages > maxVisiblePages)
{
start = paginatedList.CurrentPage - (maxVisiblePages/2);
if (start < 1)
{
start = 1;
}
if (start > (paginatedList.TotalPages - maxVisiblePages))
{
start = paginatedList.TotalPages - maxVisiblePages + 1;
}
}
if (start > 1)
{
var lessLi = new TagBuilder("li");
var lessA = new TagBuilder("a");
lessA.MergeAttribute("href", pageUrl(paginatedList.CurrentPage > maxVisiblePages ? paginatedList.CurrentPage - maxVisiblePages : 1));
lessA.InnerHtml = "...";
result.Append(lessLi.ToString(TagRenderMode.StartTag));
result.Append(lessA.ToString(TagRenderMode.Normal));
result.Append(lessLi.ToString(TagRenderMode.EndTag));
}
for (var i = start; i <= paginatedList.TotalPages && i < start + maxVisiblePages; i++)
{
var li = new TagBuilder("li");
var tag = new TagBuilder("a");
tag.MergeAttribute("href", pageUrl(i));
tag.InnerHtml = i.ToString();
if (i == paginatedList.CurrentPage)
{
li.AddCssClass("active");
}
result.Append(li.ToString(TagRenderMode.StartTag));
result.Append(tag.ToString(TagRenderMode.Normal));
result.Append(li.ToString(TagRenderMode.EndTag));
}
if (start + maxVisiblePages <= paginatedList.TotalPages)
{
var moreLi = new TagBuilder("li");
var moreA = new TagBuilder("a");
moreA.MergeAttribute("href", pageUrl(paginatedList.CurrentPage + maxVisiblePages > paginatedList.TotalPages ? paginatedList.TotalPages : paginatedList.CurrentPage + maxVisiblePages));
moreA.InnerHtml = "...";
result.Append(moreLi.ToString(TagRenderMode.StartTag));
result.Append(moreA.ToString(TagRenderMode.Normal));
result.Append(moreLi.ToString(TagRenderMode.EndTag));
}
if (showNextAndPrevious)
{
var nextPageLi = new TagBuilder("li");
var nextPageA = new TagBuilder("a");
nextPageA.MergeAttribute("href", pageUrl(paginatedList.CurrentPage < paginatedList.TotalPages ? paginatedList.CurrentPage + 1 : paginatedList.CurrentPage));
nextPageA.InnerHtml = "&gt;";
if (paginatedList.CurrentPage == paginatedList.TotalPages)
{
nextPageLi.AddCssClass("disabled");
}
result.Append(nextPageLi.ToString(TagRenderMode.StartTag));
result.Append(nextPageA.ToString(TagRenderMode.Normal));
result.Append(nextPageLi.ToString(TagRenderMode.EndTag));
}
if (showFirstAndLast)
{
var lastPageLi = new TagBuilder("li");
var lastPageA = new TagBuilder("a");
lastPageA.MergeAttribute("href", pageUrl(paginatedList.TotalPages));
lastPageA.InnerHtml = "&raquo;";
if (paginatedList.CurrentPage == paginatedList.TotalPages)
{
lastPageLi.AddCssClass("disabled");
}
result.Append(lastPageLi.ToString(TagRenderMode.StartTag));
result.Append(lastPageA.ToString(TagRenderMode.Normal));
result.Append(lastPageLi.ToString(TagRenderMode.EndTag));
}
result.Append(ul.ToString(TagRenderMode.EndTag));
return MvcHtmlString.Create(result.ToString());
}
}
}
@model TPTemplate.Web.ViewModels.PaginatedList
@using TPTemplate.Web.Extensions
@Html.PaginationLinksFor(Model, p => Url.Action("Index", new { page = p }))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment