Reputation: 511
I am trying to find a solution for creating a PaginatedList with a ViewModel.
Tutorial (using only an ordinary model)
https://learn.microsoft.com/en-us/aspnet/core/data/ef-mvc/sort-filter-page?view=aspnetcore-2.1
Similar problem
How do I paginate through a ViewModel in MVC CORE?
MVC/Entity framework core using ViewModel with paging
My Code
Controller
public async Task<IActionResult> Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewData["CurrentFilter"] = searchString;
var palletAccounts = from p in _context.PalletAccount
select p;
if (!String.IsNullOrEmpty(searchString))
{
palletAccounts = palletAccounts.Where(s => s.AccountName.Contains(searchString));
}
switch (sortOrder)
{
case "name_desc":
palletAccounts = palletAccounts.OrderByDescending(s => s.AccountName);
break;
default:
palletAccounts = palletAccounts.OrderBy(s => s.AccountName);
break;
}
var palletAccountSelectListItems = (from p in _context.PalletAccount
select p.PalletGroupName).Distinct().Select(a => new SelectListItem(a,a));
int pageSize = 10;
return View(new PalletAccountViewModel { PalletAccounts = await PaginatedList<PalletAccount>.CreateAsync(palletAccounts.AsNoTracking(), page ?? 1, pageSize), GroupNames = await palletAccountSelectListItems.ToListAsync()});
}
ModelView
public class PalletAccountViewModel
{
public PalletAccount PalletAccount { get; set; }
public IEnumerable<PalletAccount> PalletAccounts { get; set; }
public IEnumerable<SelectListItem> GroupNames { get; set; }
}
Index-page (razor)
@model PaginatedList<PalletPortal.Models.ViewModels.PalletAccountViewModel> <--if I use the model without PaginatedList it works fine (except the paging obviously).
@{
ViewData["Title"] = "Pallkonto";
}
<div class="space"></div>
<section class="main-section">
<table class="table" id="tableCenter">
<thead>
<tr>
<th>
<a asp-action="Index" asp-route-sortOrder="@ViewData["NameSortParm"]" asp-route-currentFilter="@ViewData["CurrentFilter"]">@Html.DisplayNameFor(model => model.PalletAccount.AccountName)</a>
</th>
<th>
@Html.DisplayNameFor(model => model.PalletAccount.PalletGroupName)
</th>
<th>
@Html.DisplayNameFor(model => model.PalletAccount.PalletAccountType)
</th>
<th>
@Html.DisplayNameFor(model => model.PalletAccount.IsActive)
</th>
<th> <button class="button" id="myBtn"><span>Skapa pallkonto </span></button></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.PalletAccounts)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.AccountName)
</td>
<td>
@Html.DisplayFor(modelitem => item.PalletGroupName)
</td>
<td>
@Html.DisplayFor(modelitem => item.PalletAccountType)
</td>
<td>
@Html.DisplayFor(modelItem => item.IsActive, new { @class = "checkbox" })
</td>
<td>
<a asp-action="Delete" asp-route-id="@item.ID"><button class="button" style="vertical-align: middle"><span>Radera </span></button></a>
<a asp-action="Edit" asp-route-id="@item.ID"><button class="button" style="vertical-align: middle"><span>Redigera </span></button></a>
</td>
</tr>
}
</tbody>
</table>
@{
var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.HasNextPage ? "disabled" : "";
}
<a asp-action="Index"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-page="@(Model.PageIndex - 1)"
asp-route-currentFilter="@ViewData["CurrentFilter"]"
class="btn btn-default @prevDisabled">
Previous
</a>
<a asp-action="Index"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-page="@(Model.PageIndex + 1)"
asp-route-currentFilter="@ViewData["CurrentFilter"]"
class="btn btn-default @nextDisabled">
Next
</a>
I cannot access my models in the Index-page (PalletAccount and palletAccounts).
For example: model => model.PalletAccount.AccountName
Can someone point me in the right direction?
Thanks in advance.
Upvotes: 1
Views: 2754
Reputation:
Your controller is passing an instance of PalletAccountViewModel
to the view, therefore you need to change the model in the view to
@model PalletAccountViewModel
Then since you want paginate the PalletAccounts
property, you need to change the view model to
public class PalletAccountViewModel
{
public PalletAccount PalletAccount { get; set; }
public PaginatedList<PalletAccount> PalletAccounts { get; set; } // change
public IEnumerable<SelectListItem> GroupNames { get; set; }
}
and in the view
@{
var prevDisabled = !Model.PalletAccounts.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.PalletAccounts.HasNextPage ? "disabled" : "";
}
Upvotes: 1