Paging code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@model EPiServer.Templates.Alloy.IPaging | |
@if (Model.NumberOfPages < 2) | |
{ | |
return; | |
} | |
<nav class="paging" role="navigation" aria-label="Paging"> | |
@if (Model.HasPreviousPage) | |
{ | |
<a href="@Model.PreviousItem.Url" class="paging-prev" rel="prev">@Model.PreviousItem.Text</a> | |
} | |
<ol class="paging-list"> | |
@foreach (var pagingItem in Model.PagingItems) | |
{ | |
<li class="paging-list-item @(Model.PageNumber == pagingItem.Index ? "active" : string.Empty)"> | |
@if (Model.PageNumber != pagingItem.Index) | |
{ | |
<a href="@pagingItem.Url">@pagingItem.Text</a> | |
} | |
else | |
{ | |
<p><span aria-label="You are currently viewing page @pagingItem.Index">@pagingItem.Text</span></p> | |
} | |
</li> | |
} | |
</ol> | |
@if (Model.HasNextPage) | |
{ | |
<a href="@Model.NextItem.Url" class="paging-next" rel="next">@Model.NextItem.Text</a> | |
} | |
</nav> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
namespace EPiServer.Templates.Alloy.Collections | |
{ | |
public interface IPagedEnumerable<out T> : IEnumerable<T>, IPaging | |
{ | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using EPiServer.Templates.Alloy.Models; | |
namespace EPiServer.Templates.Alloy | |
{ | |
public interface IPaging | |
{ | |
int NumberOfPages { get; } | |
int PageNumber { get; } | |
int PageSize { get; } | |
bool HasPreviousPage { get; } | |
bool HasNextPage { get; } | |
PagingItem FirstItem { get; } | |
PagingItem PreviousItem { get; } | |
PagingItem NextItem { get; } | |
PagingItem LastItem { get; } | |
IEnumerable<PagingItem> PagingItems { get; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Globalization; | |
using System.Linq; | |
using System.Web; | |
using EPiServer; | |
using EPiServer.Templates.Alloy.Models; | |
namespace EPiServer.Templates.Alloy.Collections | |
{ | |
public class PagedList<T> : IPagedEnumerable<T> | |
{ | |
private bool _prepared; | |
protected readonly IEnumerable<T> Subset; | |
protected readonly HttpContextBase Context; | |
protected readonly string CurrentUrl; | |
protected int StepsBefore; | |
protected int StartIndex; | |
protected int EndIndex; | |
public string QueryParamName = "page"; | |
public string PreviousItemText = "<"; | |
public string NextItemText = ">"; | |
public int MaxVisibleItems = 10; | |
public int NumberOfPages { get; protected set; } | |
public int PageNumber { get; protected set; } | |
public int PageSize { get; protected set; } | |
public int TotalItemCount { get; protected set; } | |
public bool HasPreviousPage { get { return PageNumber > 1; } } | |
public bool HasNextPage { get { return PageNumber < NumberOfPages; } } | |
public PagingItem FirstItem | |
{ | |
get | |
{ | |
PreparePaging(); | |
if (HasPreviousIndication) | |
{ | |
return new PagingItem | |
{ | |
Index = 1, | |
Text = "1", | |
Url = CreateUrl(1) | |
}; | |
} | |
return null; | |
} | |
} | |
public PagingItem PreviousItem | |
{ | |
get | |
{ | |
if (HasPreviousPage) | |
{ | |
var index = PageNumber - 1; | |
return new PagingItem | |
{ | |
Index = index, | |
Text = PreviousItemText, | |
Url = CreateUrl(index) | |
}; | |
} | |
return null; | |
} | |
} | |
public PagingItem NextItem | |
{ | |
get | |
{ | |
if (HasNextPage) | |
{ | |
var index = PageNumber + 1; | |
return new PagingItem | |
{ | |
Index = index, | |
Text = NextItemText, | |
Url = CreateUrl(index) | |
}; | |
} | |
return null; | |
} | |
} | |
public PagingItem LastItem | |
{ | |
get | |
{ | |
PreparePaging(); | |
if (HasNextIndication) | |
{ | |
return new PagingItem() | |
{ | |
Index = NumberOfPages, | |
Text = NumberOfPages.ToString(), | |
Url = CreateUrl(NumberOfPages) | |
}; | |
} | |
return null; | |
} | |
} | |
public IEnumerable<PagingItem> PagingItems | |
{ | |
get | |
{ | |
PreparePaging(); | |
var items = new List<PagingItem>(); | |
for (int idx = StartIndex + 1; idx <= EndIndex; idx++) | |
{ | |
items.Add(new PagingItem | |
{ | |
Index = idx, | |
Text = idx.ToString(CultureInfo.InvariantCulture), | |
Selected = idx == PageNumber, | |
Url = CreateUrl(idx) | |
}); | |
} | |
return items; | |
} | |
} | |
public PagedList(HttpContextBase context, IEnumerable<T> superset, int page, int pageSize) : this(context, superset != null ? superset.Count() : 0, page, pageSize) | |
{ | |
Subset = page == 1 ? superset.Take(pageSize) : superset.Skip((page - 1) * pageSize).Take(pageSize); | |
} | |
public PagedList(HttpContextBase context, IEnumerable<T> pagedSuperset, int totalItemCount, int page, int pageSize) : this(context, totalItemCount, page, pageSize) | |
{ | |
Subset = pagedSuperset; | |
} | |
protected PagedList(HttpContextBase context, int totalItemCount, int page, int pageSize) | |
{ | |
Context = context; | |
TotalItemCount = totalItemCount; | |
PageNumber = page; | |
PageSize = pageSize; | |
NumberOfPages = (int)Math.Ceiling(TotalItemCount / (double)pageSize); | |
CurrentUrl = Context.Request.RawUrl; | |
} | |
protected virtual string CreateUrl(int page) | |
{ | |
var currUrl = UrlEncode(CurrentUrl); | |
if (page != 1) | |
currUrl.QueryCollection[QueryParamName] = page.ToString(); | |
else | |
currUrl.QueryCollection.Remove(QueryParamName); | |
return currUrl.ToString(); | |
} | |
private static UrlBuilder UrlEncode(string url) | |
{ | |
var urlBuilder = new UrlBuilder(url); | |
for (var idx = urlBuilder.QueryCollection.Keys.Count - 1; idx >= 0; idx--) | |
{ | |
var key = urlBuilder.QueryCollection.Keys[idx]; | |
urlBuilder.QueryCollection[key] = HttpUtility.UrlEncode(HttpUtility.UrlDecode(urlBuilder.QueryCollection[key])); | |
} | |
return urlBuilder; | |
} | |
protected void PreparePaging() | |
{ | |
if (_prepared) | |
return; | |
StepsBefore = (int)Math.Ceiling(MaxVisibleItems / 2.0) - 1; | |
var stepsAfter = MaxVisibleItems - StepsBefore - 1; | |
var steps = StepsBefore + stepsAfter; | |
if (NumberOfPages > MaxVisibleItems) | |
{ | |
var startIndex = Math.Max(0, PageNumber - 1 - StepsBefore); | |
if (PageNumber - 1 > NumberOfPages - steps) | |
startIndex = Math.Max(NumberOfPages - steps - 1, 0); | |
var endIndex = Math.Min(NumberOfPages, startIndex + steps + 1); | |
StartIndex = startIndex; | |
EndIndex = endIndex; | |
} | |
else | |
{ | |
StartIndex = 0; | |
EndIndex = NumberOfPages; | |
} | |
_prepared = true; | |
} | |
public IEnumerator<T> GetEnumerator() | |
{ | |
return Subset.GetEnumerator(); | |
} | |
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() | |
{ | |
return this.GetEnumerator(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace EPiServer.Templates.Alloy.Models | |
{ | |
public class PagingItem | |
{ | |
public int Index { get; set; } | |
public string Text { get; set; } | |
public string Url { get; set; } | |
public bool Selected { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment