Reputation: 555
I want to implement pagination
into my application.
My Controller
public ActionResult Leading(string type, int? pageNumber)
{
IEnumerable<LeadingClass> data;
LeadingDatabaseHandle DatabaseHandle = new LeadingDatabaseHandle ();
if (type.HasValue)
{
data = DatabaseHandle(type).ToPagedList(pageNumber ?? 1, 10);
}
else
{
data = DatabaseHandle.LeadingAll().ToPagedList(pageNumber ?? 1, 10);
}
LeadingFilterVM model = new LeadingFilterVM
{
Type = type,
TypeList = new List<SelectListItem>
{
new SelectListItem{ Text = "General", Value = "1" },
new SelectListItem{ Text = "Advance", Value = "2" }
},
Leadings = data
};
return View(model);
}
My `Data Model
public class LeadingClass
{
public int Id { get; set; }
public string Name{ get; set; }
public string Type { get; set; }
}
My View Model
public class LeadingFilterVM
{
public string Type { get; set; }
public IEnumerable<SelectListItem> TypeList { get; set; }
public IEnumerable<LeadingClass> Leadings { get; set; }
}
And my View
@model Website.Models.Leading.ViewModels.LeadingFilterVM
@using PagedList;
@using PagedList.Mvc;
@using (Html.BeginForm("Leading", "Home", FormMethod.Get))
{
@Html.DisplayNameFor(m => m.Leadings.FirstOrDefault().Type)
@Html.DropDownListFor(m => m.Type, Model.TypeList, "All Type", new { @class = "form-control"})
}
<table class="table table-hover">
<tr>
<th>@Html.DisplayNameFor(m => m.Leadings.FirstOrDefault().Id)</th>
<th>@Html.DisplayNameFor(m => m.Leadings.FirstOrDefault().Name)</th>
</tr>
@foreach (var item in Model.Leadings)
{
<tr>
<td>@Html.DisplayFor(modelItem => item.Id)</td>
<td>@Html.DisplayFor(modelItem => item.Name)</td>
</tr>
}
</table>
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
@Html.PagedListPager(Model, pageNumber => Url.Action("Leading", new
{
pageNumber
}))
It is throwing error: Compiler Error Message:
CS1061: 'LeadingFilterVM' does not contain a definition for 'PageNumber' and no extension method 'PageNumber' accepting a first argument of type 'LeadingFilterVM' could be found (are you missing a using directive or an assembly reference?)
Can anyone please guide me?
Upvotes: 1
Views: 1737
Reputation:
The model in the view is LeadingFilterVM
and that model does not contain a property for PageNumber
.
Note that there are other issues with your code, and you need to change the view model to
public class LeadingFilterVM
{
public string Type { get; set; }
public IEnumerable<SelectListItem> TypeList { get; set; }
public IPagedList<LeadingClass> Leadings { get; set; } //IPagedList, not IEnumerable
}
Then you need to change the view to use the Leadings
property which is the IPagedList
Page @(Model.Leadings.PageCount < Model.Leadings.PageNumber ? 0 : Model.Leadings.PageNumber) of @Model.Leadings.PageCount
@Html.PagedListPager(Model.Leadings, page => Url.Action("Leading", new { page, type = Model.Type }))
and change the signature of the method to
public ActionResult Leading(int? type, int? pageNumber)
You also need to change the code to generate the SelectList
to
TypeList = new List<SelectListItem>
{
new SelectListItem{ Text = "General", Value = "General" },
new SelectListItem{ Text = "Advance", Value = "Advance" }
},
or just simply TypeList = new SelectList(new string[]{ "General", "Advance" })
, since you need to post back either "General" or "Advance", not an int
. Having said that, I would recommend that Type
be in int
with a FK relationship to a Types
table in your database.
Note its not clear what your DatabaseHandle.LeadingAll()
and DatabaseHandle(type)
methods return, but they should be returing IQueryable<LeadingClass>
(not IEnumerable<>
or IList<>
) otherwise you defeating the benefits of server side paging. The typical code for getting the records would be
public ActionResult Leading(string type, int? pageNumber)
{
IQueryable<LeadingClass> data = db.LeadingClass;
if (type != null)
{
data = data.Where(x => x.Type == type.Value);
}
LeadingFilterVM model = new LeadingFilterVM
{
....
Leadings = data..ToPagedList(pageNumber ?? 1, 10)
};
return View(model);
}
Upvotes: 1