Friday, December 22, 2017

Multiple PagedList Pager In A Single View

Good afternoon!
In a situation wherein a single page will contain multiple paging such as displaying master-details records or similar requirements, using a couple or more PagedList pager will cause logical errors such as when you click on the paging of details record to traverse to the next page, the paging of master record will move to the next record as well. In order to solve this dilemma, we need to assign a specific page variable to a PagedList object to prevent this issue from happening. In this example, I'll demonstrate showing products information from AdventureWorks database whose stocks are above or below a certain reorder point. The page model class below has two page properties namely BelowReorderPage and AboveReorderPage. And these properties are assigned to their specific PagedList object whether ProductsBelowReorder or ProductsAboveReorder.
PageModel.cs
public class PageModel
{
 public int BelowReorderPage { get; set; }
 public int AboveReorderPage { get; set; }
 public int Size { get; set; }

 public PageModel()
 {
  BelowReorderPage = 1;
  AboveReorderPage = 1;
  Size = 10;
 }
}

public class ProductPageModel
{
 public PageModel PageModel { get; set; }
 public ProductPageModel(PageModel pageModel)
 {
  ProductsBelowReorder = new PagedList<ProductViewModel>(new List<ProductViewModel>(), 1, pageModel.Size);
  ProductsAboveReorder = new PagedList<ProductViewModel>(new List<ProductViewModel>(), 1, pageModel.Size);
  PageModel = pageModel;
 }

 public IPagedList<ProductViewModel> ProductsBelowReorder { get; set; }
 public IPagedList<ProductViewModel> ProductsAboveReorder { get; set; }
}
The controller class will retrieve the records from the Product table and assign them to the PagedList properties. Note that the ProductsBelowReorder PagedList property is assigned with the BelowReorderPage page while the ProductsAboveReorder is allocated with AboveReorderPage page.
HomeController.cs
public class HomeController : Controller
{
 private AdventureWorksEntities _context;

 public HomeController()
 {
  _context = new AdventureWorksEntities();
 }
 
 // GET: Home
 public ActionResult Index(PageModel pageModel)
 {
  var productsBelowReorder = (from prod in _context.Products
         join prodInv in _context.ProductInventories
         on prod.ProductID equals prodInv.ProductID
         where prodInv.Quantity < prod.ReorderPoint
         select new ProductViewModel()
         {
          ProductID = prod.ProductID,
          ProductName = prod.Name,
          ProductNumber = prod.ProductNumber,
          ListPrice = prod.ListPrice,
          LocationID = prodInv.LocationID,
          Quantity = prodInv.Quantity,
          ReorderPoint = prod.ReorderPoint
         }).ToList();

  var productsAboveReorder = (from prod in _context.Products
         join prodInv in _context.ProductInventories
         on prod.ProductID equals prodInv.ProductID
         where prodInv.Quantity >= prod.ReorderPoint
         select new ProductViewModel()
         {
          ProductID = prod.ProductID,
          ProductName = prod.Name,
          ProductNumber = prod.ProductNumber,
          ListPrice = prod.ListPrice,
          LocationID = prodInv.LocationID,
          Quantity = prodInv.Quantity,
          ReorderPoint = prod.ReorderPoint
         }).ToList();

  var model = new ProductPageModel(pageModel)
  {
   ProductsBelowReorder = productsBelowReorder.ToPagedList(pageModel.BelowReorderPage, pageModel.Size),
   ProductsAboveReorder = productsAboveReorder.ToPagedList(pageModel.AboveReorderPage, pageModel.Size)
  };

  return View(model);
 }
}
The view will display each product information in a tabular format and is assigned with a PagedListPager helper. Each pager has been assigned with a particular model and paging options. For the products whose stocks are above the reorder point, the RouteValueDictionary parameter sets the AboveReorderPage with the current page while the BelowReorderPage is assigned with the BelowReorderPage page. The approach also applies to the products whose stocks are below the reorder point.
Index.cshtml
<div class="container">
    <div class="row table-responsive">
        <h3>Products Above ReorderPoint</h3>
        <table class="table table-bordered table-condensed table-striped">
            <thead>
                <tr>
                    <th>Product ID</th>
                    <th>Product Name</th>
                    <th>Product Number</th>
                    <th>ListPrice</th>
                    <th>Location ID</th>
                    <th>Quantity</th>
                    <th>Reorder Point</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var productAboveReorder in Model.ProductsAboveReorder)
                {
                    <tr>
                        <td>@productAboveReorder.ProductID</td>
                        <td>@productAboveReorder.ProductName</td>
                        <td>@productAboveReorder.ProductNumber</td>
                        <td>@productAboveReorder.ListPrice</td>
                        <td>@productAboveReorder.LocationID</td>
                        <td>@productAboveReorder.Quantity</td>
                        <td>@productAboveReorder.ReorderPoint</td>
                    </tr>
                }
            </tbody>
        </table>
        @Html.PagedListPager(Model.ProductsAboveReorder, page => Url.Action("Index",
                                    "Home",
                                      new RouteValueDictionary() {
                                        { "AboveReorderPage", page },
                                        { "BelowReorderPage", Model.PageModel.BelowReorderPage }
                                      }), PagedListRenderOptions.ClassicPlusFirstAndLast)
    </div>
    <div class="row table-responsive">
        <h3>Products Below ReorderPoint</h3>
        <table class="table table-bordered table-condensed table-striped">
            <thead>
                <tr>
                    <th>Product ID</th>
                    <th>Product Name</th>
                    <th>Product Number</th>
                    <th>ListPrice</th>
                    <th>Location ID</th>
                    <th>Quantity</th>
                    <th>Reorder Point</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var productBelowReorder in Model.ProductsBelowReorder)
                {
                    <tr>
                        <td>@productBelowReorder.ProductID</td>
                        <td>@productBelowReorder.ProductName</td>
                        <td>@productBelowReorder.ProductNumber</td>
                        <td>@productBelowReorder.ListPrice</td>
                        <td>@productBelowReorder.LocationID</td>
                        <td>@productBelowReorder.Quantity</td>
                        <td>@productBelowReorder.ReorderPoint</td>
                    </tr>
                }
            </tbody>
        </table>
        @Html.PagedListPager(Model.ProductsBelowReorder, page => Url.Action("Index",
                                    "Home",
                                      new RouteValueDictionary() {
                                        { "BelowReorderPage", page },
                                        { "AboveReorderPage", Model.PageModel.AboveReorderPage }
                                      }), PagedListRenderOptions.ClassicPlusFirstAndLast)
    </div>
</div>
Output Source Code: Github - Multiple PagedList Pager

0 comments:

Post a Comment