I mounted a paging control for a blog that I'm putting together, but I'm not sure if I did it the best way, I tried to copy the paging control of Stack Exchange sites. Could you guys take a look and tell me what you think?
A screenshot of how it stayed when the total of pages was equal to 10:
Theviewcodesnippetforthenavigationcontrol(IusedBootstrap):
<nav><ulclass="pagination">
@{
var totalPages = Model.TotalPostsCount / Model.PostsPerPage;
var urlPreviousPage = Url.Action("Page", new { arg = Model.CurrentPage - 1, postsPerPage = Model.PostsPerPage });
var urlNextPage = Url.Action("Page", new { arg = Model.CurrentPage + 1, postsPerPage = Model.PostsPerPage });
}
@* Navigation button << *@
<li class="@(Model.CurrentPage == 1 ? "disabled" : null)">
<a href="@(Model.CurrentPage != 1 ? urlPreviousPage : null)">
<span>«</span>
</a>
</li>
@* Navigation button 1 *@
<li class="@(Model.CurrentPage == 1 ? "active" : null)"><a href="@Url.Action("Page", new { arg = 1, postsPerPage = Model.PostsPerPage })">1</a></li>
@* Navigation buttons from 2 to 5 *@
@if (Model.CurrentPage >= 1 && Model.CurrentPage < 5)
{
for (int page = 2; page <= 5; page++)
{
if (totalPages >= page)
{
var pageUrl = Url.Action("Page", new { arg = page, postsPerPage = Model.PostsPerPage });
<li class="@(Model.CurrentPage == page ? "active" : null)"><a href="@pageUrl">@page</a></li>
}
}
}
<li><a>...</a></li>
@* Middle navigation buttons *@
@if (Model.CurrentPage >= 5 && Model.CurrentPage <= totalPages - 4)
{
<li><a href="@Url.Action("Page", new { arg = Model.CurrentPage - 2 })">@(Model.CurrentPage - 2)</a></li>
<li><a href="@Url.Action("Page", new { arg = Model.CurrentPage - 1 })">@(Model.CurrentPage - 1)</a></li>
<li class="active"><a href="@Url.Action("Page", new { arg = Model.CurrentPage })">@(Model.CurrentPage)</a></li>
<li><a href="@Url.Action("Page", new { arg = Model.CurrentPage + 1 })">@(Model.CurrentPage + 1)</a></li>
<li><a href="@Url.Action("Page", new { arg = Model.CurrentPage + 2 })">@(Model.CurrentPage + 2)</a></li>
<li><a>...</a></li>
}
@* Navigation buttons from (totalPages - 4) to (totalPages) *@
@if (Model.CurrentPage > totalPages - 4)
{
<li><a href="@Url.Action("Page", new { arg = totalPages - 4, postsPerPage = Model.PostsPerPage })">@(totalPages - 4)</a></li>
<li class="@(Model.CurrentPage == totalPages - 3 ? "active" : null)"><a href="@Url.Action("Page", new { arg = totalPages - 3, postsPerPage = Model.PostsPerPage })">@(totalPages - 3)</a></li>
<li class="@(Model.CurrentPage == totalPages - 2 ? "active" : null)"><a href="@Url.Action("Page", new { arg = totalPages - 2, postsPerPage = Model.PostsPerPage })">@(totalPages - 2)</a></li>
<li class="@(Model.CurrentPage == totalPages - 1 ? "active" : null)"><a href="@Url.Action("Page", new { arg = totalPages - 1, postsPerPage = Model.PostsPerPage })">@(totalPages - 1)</a></li>
}
<li class="@(Model.CurrentPage == totalPages ? "active" : null)"><a href="@Url.Action("Page", new { arg = totalPages, postsPerPage = Model.PostsPerPage })">@totalPages</a></li>
@* >> *@
<li class="@(Model.CurrentPage == totalPages ? "disabled" : null)">
<a href="@(Model.CurrentPage != totalPages ? urlNextPage : null)">
<span>»</span>
</a>
</li>
</ul>
</nav>
A action for you to have an idea of what is being sent to this view :
public async Task<ActionResult> Page(int arg = 1, int postsPerPage = 10)
{
var sort = Builders<Post>.Sort.Descending(p => p.Created);
var viewModel = new HomePageViewModel
{
CurrentPage = arg,
PostsPerPage = postsPerPage,
TotalPostsCount = await ZigBlogDb.Posts.CountAsync(_ => true),
Posts = await ZigBlogDb.Posts.Find(_ => true).Sort(sort).Skip((arg - 1) * postsPerPage).Limit(postsPerPage).ToListAsync()
};
return View(viewModel);
}