I’ve used PagedList.MVC for pagination in my application. This is working fine. Pagination is working fine and also the OrderBy dropdownlist is working fine. When i select value from dropdownlist it gives the desired sorted result. I mean if i select A-Z then it sorts the items fine in ascending order but when i click 2nd page or next page it doesn’t sort any item and the url is become like this
http://localhost:41213/Home/Products?page=2&pageSize=6
And also how can I make this pageSize=6 a dynamic ? I want this to put in dropdownlist like {5,10,15,20} and when user selects a value then it should display that selected numbers of item.
Controller
[HttpGet]
public ActionResult Products(int? OrderBy, int page=1, int pageSize=6)
{
private Shopping db = new Shopping();
switch (OrderBy)
{
case 1:
List<Product> listProductsasc = db.Products.OrderBy(p => p.Name).ToList();
PagedList<Product> modelasc = new PagedList<Product>(listProductsasc, page, pageSize);
return View(modelasc);
case 2:
List<Product> listProductsdesc = db.Products.OrderByDescending(p => p.Name).ToList();
PagedList<Product> modeldesc = new PagedList<Product>(listProductsdesc, page, pageSize);
return View(modeldesc);
default:
List<Product> listProducts = db.Products.ToList();
PagedList<Product> modeldefault = new PagedList<Product>(listProducts, page, pageSize);
return View(modeldefault);
}
}
View
@model PagedList.IPagedList<FypStore.Models.Product>
@using PagedList.Mvc
<div class="row">
<div class="col-sm-6">
@using (Html.BeginForm("Products", "Home", FormMethod.Get, new { id = "Form1" }))
{
<div class="col-sm-8">
Sort by:
@Html.DropDownList("OrderBy", new List<SelectListItem>
{
new SelectListItem{ Text="A-Z", Value = "1" },
new SelectListItem{ Text="Z-A", Value = "2" }
}, "-- Order By --")
</div>
<div class="col-sm-4">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Filter" />
</div>
</div>
</div>
}
</div>
</div>
<br />
@Html.PagedListPager(Model, page => Url.Action("Products", new { page, pageSize = Model.PageSize }))
Showing @Model.FirstItemOnPage to @Model.LastItemOnPage of @Model.TotalItemCount Products
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You need to modify the route parameters of the PagedListPager() method to include the vale of the sort order, for example
@Html.PagedListPager(Model, page => Url.Action("Products", new { OrderBy = ViewBag.SortOrder, page, pageSize = Model.PageSize }))
and then in the method, include
ViewBag.SortOrder = OrderBy;
before you return the view. However a better approach is to use a view model containing the properties used by the view which will resolve other issues with your code (for example, if you select the "Z-A" option and submit the form, when you return it, the collection is sorted, but dropdown displays "-- Order By --" indicating its not sorted. You view model should be
public class ProductsVM
{
[Display(Name = "Sort by:")]
public int? OrderBy { get; set; }
public IEnumerable<SelectListItem> OrderList { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
PagedList<Product> Products { get; set; }
}
and the controller method would be
[HttpGet]
public ActionResult Products(int? orderBy, int page=1, int pageSize=6)
{
private Shopping db = new Shopping();
IEnumerable<Product> products = db.Products; // not .ToList()
if (orderBy == 1)
{
products = products.OrderBy(p => p.Name);
}
else if (orderBy == 2)
{
products = products.OrderByDescending(p => p.Name)
}
ProductsVM model = new ProductsVM
{
OrderBy = orderBy,
OrderList = new List<SelectListItem>
{
new SelectListItem{ Text="A-Z", Value = "1" },
new SelectListItem{ Text="Z-A", Value = "2" }
},
Page = page,
PageSize = pageSize,
Products = new PagedList<Product>(products, page, pageSize);
};
return View(model);
}
And finally modify you view to use the view model
@model ProductsVM
....
@using (Html.BeginForm("Products", "Home", FormMethod.Get))
{
@Html.LabelFor(m => m.OrderBy)
@Html.DropDownListForFor(m => m.OrderBy, Model.OrderList, "-- Order By --")
<input type="submit" class="btn btn-default" value="Filter" />
}
@Html.PagedListPager(Model.Products, page => Url.Action("Products", new { orderBy = Model.OrderBy, page, pageSize = Model.PageSize }))
Showing @Model.Products.FirstItemOnPage to @Model.Products.LastItemOnPage of @Model.Products.TotalItemCount Products
Method 2
To fix your page links you need to pass the OrderBy parameter to the view. The easiest way would be to use ViewBag.
In your controller:
[HttpGet]
public ActionResult Products(int? OrderBy, int page = 1, int pageSize = 2)
{
ViewBag.OrderBy = OrderBy;
...
In your view:
@Html.PagedListPager(Model, page => Url.Action("Products", new { page, pageSize = Model.PageSize, OrderBy = ViewBag.OrderBy }))
Another way would be to use a view model. Create a class called ProductsViewModel and populate its properties in your controller like this:
List<Product> modelasc = new PagedList<Product>(listProductsasc, page, pageSize); var viewModel = ProductsViewModel(); viewModel.Products = modelasc; viewModel.OrderBy = OrderBy; return View(viewModel);
And use them inside the view:
@model FypStore.Models.ProductsViewModel
...
@Html.PagedListPager(Model, page => Url.Action("Products", new { page, pageSize = Model.Products.PageSize, OrderBy = Model.OrderBy }))
And also how can I make this pageSize=6 a dynamic ?
You do it the same way as with your OrderBy parameter: make a dropdown list with the name pageSize:
<div class="col-sm-8">
Page size:
@Html.DropDownList("pageSize", new List<SelectListItem>
{
new SelectListItem{ Text="2", Value = "2" },
new SelectListItem{ Text="3", Value = "3" }
}, "-- Page Size --")
</div>
Side note: you might want to remove the .ToList(); part of your query in the controller and move it elsewhere. Because now your code fetches all the data from the database and then sorts it and extracts the necessary number of products. You should always perform sorting and paging logic on database side and fetch only those products that you want to display on the current page.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0