Reputation: 87
I am trying to fixed pagination in my project. But I do not get the correct result. I want to make this result 123 ... 12
PS I study with book Adam Freeman Pro ASP.NET Core MVC 2. Project in GitHub https://github.com/JasARGHUN/StoreProject-
Pagin model PagingInfo.cs:
public class PagingInfo
{ public int TotalItems { get; set; }
public int ItemsPerPage { get; set; }
public int CurrentPage { get; set; }
public int TotalPages =>
(int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); }
Descriptor class PageLinkTagHelper.cs
[HtmlTargetElement("div", Attributes = "page-model")]
public class PageLinkTagHelper : TagHelper
{
private IUrlHelperFactory urlHelperFactory;
public PageLinkTagHelper(IUrlHelperFactory helperFactory)
{
urlHelperFactory = helperFactory;
}
[ViewContext]
[HtmlAttributeNotBound]
public ViewContext ViewContext { get; set; }
public PagingInfo PageModel { get; set; }
public string PageAction { get; set; }
[HtmlAttributeName(DictionaryAttributePrefix = "page-url-")]
public Dictionary<string, object> PageUrlValues { get; set; } = new Dictionary<string, object>();
public bool PageClassesEnabled { get; set; } = false;
public string PageClass { get; set; }
public string PageClassNormal { get; set; }
public string PageClassSelected { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
IUrlHelper urlHelper = urlHelperFactory.GetUrlHelper(ViewContext);
TagBuilder result = new TagBuilder("div");
for (int i = 1; i <= PageModel.TotalPages; i++)
{
TagBuilder tag = new TagBuilder("a");
PageUrlValues["productPage"] = i;
tag.Attributes["href"] = urlHelper.Action(PageAction, PageUrlValues);
if (PageClassesEnabled)
{
tag.AddCssClass(PageClass);
tag.AddCssClass(i == PageModel.CurrentPage
? PageClassSelected : PageClassNormal);
}
tag.InnerHtml.Append(i.ToString());
result.InnerHtml.AppendHtml(tag);
}
output.Content.AppendHtml(result.InnerHtml);
}
}
Pagination view model ProductsListViewModel
public class ProductsListViewModel
{
public IEnumerable<Product> Products { get; set; }
public PagingInfo PagingInfo { get; set; }
public string CurrentCategory { get; set; }
}
Controller ProductController.cs
public class ProductController : Controller
{
private IProductRepository _repository;
public int PageSize = 4;
public ProductController(IProductRepository repository)
{
_repository = repository;
}
public ViewResult List(string category, int productPage = 1) =>
View(new ProductsListViewModel
{
Products = _repository.Products
.Where(p => category == null || p.Category == category)
.OrderBy(p => p.ProductID)
.Skip((productPage - 1) * PageSize)
.Take(PageSize),
PagingInfo = new PagingInfo
{
CurrentPage = productPage,
ItemsPerPage = PageSize,
TotalItems = category == null ?
_repository.Products.Count() :
_repository.Products.Where(e =>
e.Category == category).Count()
},
CurrentCategory = category
});}
View List.cshtml
@model ProductsListViewModel
@foreach (var p in Model.Products)
{
@await Html.PartialAsync("ProductSummary", p);
}
<div page-model="@Model.PagingInfo" page-action="List" page-classes-enabled="true"
page-class="btn" page-class-normal="btn-secondary"
page-class-selected="btn-primary" page-url-category="@Model.CurrentCategory"
class="btn-group pull-right m-1"></div>
Navigation menu Navigation.cshtml
@model IEnumerable<string>
<a class="btn btn-block btn-secondary border mb-1"
asp-action="List"
asp-controller="Product"
asp-route-category="">Home</a>
<div>
@foreach (string category in Model)
{
<a class="btn btn-sm btn-block border @(category == ViewBag.SelectedCategory ? "btn-info": "btn-light")"
asp-action="List"
asp-controller="Product"
asp-route-category="@category"
asp-route-productPage="1">@category</a>
}
</div>
I want to do something like this pagination
Upvotes: 0
Views: 2112
Reputation: 1
controller/
public IActionResult Index(int page=1)
{
ViewBag.Page = page;
ViewBag.TotalPage = (int)Math.Ceiling(_context.Books.Include(x => x.Author).Include(x => x.Genre).Count() / 2d);
var data = _context.Books.Include(x => x.Author).Include(x => x.Genre).Skip((page - 1) * 2).Take(2).ToList();
return View(data);
}
cshtml/
<div aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item @(page==1?"disabled":"")"><a class="page-link" asp-action="index" asp-route-page="1"><<</a></li>
<li class="page-item @(page==1?"disabled":"")"><a class="page-link" asp-action="index" asp-route-page="@(page-1)"><</a></li>
@if (page == 1)
{
for (int i = page; i <= page + 2; i++)
{
<li class="page-item @(page==i?"active":"")"><a class="page-link" asp-action="index" asp-route-page="@i">@i</a></li>
}
}
else if (page == totalPages)
{
for (int i = page - 2; i <= page; i++)
{
<li class="page-item @(page==i?"active":"")"><a class="page-link" asp-action="index" asp-route-page="@i">@i</a></li>
}
}
else
{
for (int i = page - 1; i <= page + 1; i++)
{
<li class="page-item @(page==i?"active":"")"><a class="page-link" asp-action="index" asp-route-page="@i">@i</a></li>
}
}
<li class="page-item @(page==totalPages?"disabled":"")"><a class="page-link" asp-action="index" asp-route-page="@(page+1)">></a></li>
<li class="page-item @(page==totalPages?"disabled":"")"><a class="page-link" asp-action="index" asp-route-page="@totalPages">>></a></li>
</ul>
</div>
Upvotes: 0
Reputation: 87
Ok, i tried and resolv my trouble, updated Controller, TagHelper class and View. Maybe someone will come in handy.
Controller:
public async Task<IActionResult> List(string category, int page = 1)
{
IQueryable<Product> source = _repository.Products.Where(p => category == null || p.Category == category)
.OrderBy(p => p.ProductID);
var count = await source.CountAsync();
var items = await source.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync();
PagingInfo pagingInfo = new PagingInfo(count, page, pageSize);
ProductsListViewModel productsListView = new ProductsListViewModel
{
PagingInfo = pagingInfo,
Products = items
};
return View(productsListView);}
View:
<h3><page-link page-model="Model.PagingInfo" page-action="List"></page-link></h3>
TagHelper class:
public class PageLinkTagHelper : TagHelper
{
private IUrlHelperFactory urlHelperFactory;
public PageLinkTagHelper(IUrlHelperFactory helperFactory)
{
urlHelperFactory = helperFactory;
}
[ViewContext]
[HtmlAttributeNotBound]
public ViewContext ViewContext { get; set; }
public PagingInfo PageModel { get; set; }
public string PageAction { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
IUrlHelper urlHelper = urlHelperFactory.GetUrlHelper(ViewContext);
output.TagName = "div";
// набор ссылок будет представлять список ul
TagBuilder tag = new TagBuilder("ul");
tag.AddCssClass("pagination");
// формируем три ссылки - на текущую, предыдущую и следующую
TagBuilder currentItem = CreateTag(PageModel.PageNumber, urlHelper);
// создаем ссылку на предыдущую страницу, если она есть
if (PageModel.HasPreviousPage)
{
TagBuilder prevItem = CreateTag(PageModel.PageNumber - 1, urlHelper);
tag.InnerHtml.AppendHtml(prevItem);
}
tag.InnerHtml.AppendHtml(currentItem);
// создаем ссылку на следующую страницу, если она есть
if (PageModel.HasNextPage)
{
TagBuilder nextItem = CreateTag(PageModel.PageNumber + 1, urlHelper);
tag.InnerHtml.AppendHtml(nextItem);
}
output.Content.AppendHtml(tag);
}
TagBuilder CreateTag(int pageNumber, IUrlHelper urlHelper)
{
TagBuilder item = new TagBuilder("li");
TagBuilder link = new TagBuilder("a");
if (pageNumber == this.PageModel.PageNumber)
{
item.AddCssClass("active");
}
else
{
link.Attributes["href"] = urlHelper.Action(PageAction, new { page = pageNumber });
}
link.InnerHtml.Append(pageNumber.ToString());
item.InnerHtml.AppendHtml(link);
return item;
}
}
}
Upvotes: 2
Reputation: 129
Change your for loop
for (PageModel.CurrentPage; i <= PageModel.CurrentPage + 2; i++)
That will give you 3 results based on the current page.
Then you can add a button the first and the last page on either end of the html.
There's probably a more elegant approach but that should work.
Upvotes: 0