I would like to make in my asp.net web form page size selection with drop down list. Actually I made it already, but when I change page size from my drop down list there isn't change anything. I guess I need to write something extra in my controller, or maybe my View is wrong?
My Index.cshtml view:
@model TimeReportingWebApp.TimeReportViewMod
@using PagedList.Mvc;
....
@using (Html.BeginForm("Index", "Users"))
{
<p>
Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" class="btn btn-primary" value="Search" />
</p>
}
<table class="table">
<tr>
<th>@Html.ActionLink("Login","Index", new { sortOrder = ViewBag.LoginSortParm, currentFilter = ViewBag.CurrentFilter })</th>
</tr>
@foreach (var item in Model.Model2) {
<tr>
<td>@Html.DisplayFor(modelItem => item.Login)</td>
</tr>
}
</table>
Page @(Model.Model2.PageCount < Model.Model2.PageNumber ? 0 : Model.Model2.PageNumber) of @Model.Model2.PageCount
@Html.PagedListPager(Model.Model2, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }) )
Select page size @Html.DropDownList("PageSize", new SelectList(new Dictionary<string, int> { { "10", 10 }, { "20", 20 }, { "100", 100 } }, "Key", "Value", Model.Model2.Count))
And this is my controller. Here I didn't added anything regarding DropDownList :
public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var users = from s in db.Users.Include(u => u.CustomerProject).Include(u => u.Service).Include(u => u.Customer) select s;
int pageSize = 20;
int pageNumber = (page ?? 1);
var inst = new TimeReportViewMod();
inst.Model1 = users.ToList();
inst.Model2 = users.ToPagedList(pageNumber, pageSize);
return View("Index", inst);
}
You need to include the dropdownlist within you <form>
tags so its value is submitted to the controller method, and that method also needs an additional parameter to bind to the value. You also need to include the selected value in the Html.PagedListPager()
so that its retained when you go to another page.
You have not shown your TimeReportViewMod
model, but its od that it contains properties IEnumerable<User>
and IPagedList<User>
, which is also IEnumerable<User>
so the first one is unnecessary. But what it should contain is the properties you use for searching and filtering so that you can strongly bind to your properties and avoid the use of ViewBag
. It should look like
public class TimeReportVM
{
[Display(Name = "Find by name")]
public string SearchString { get; set; }
public string SortOrder { get; set; }
[Display(Name = "Select page size")]
public int PageSize { get; set; }
public SelectList PageSizeList { get; set; }
public IPagedList<User> Users { get; set; }
}
Note: Its not clear what sortOrder
is for - you never use it anywhere. Nor do you ever use the value of searchString
/currentFilter
in you query.
Then you controller method is
public ActionResult Index(string sortOrder, string searchString, int pageSize, int? page)
{
if (searchString != null)
{
page = 1;
}
// this query should be taking into account the values of sortOrder and searchString?
var users = from s in db.Users.Include(u => u.CustomerProject).Include(u => u.Service).Include(u => u.Customer) select s;
TimeReportVM model = new TimeReportVM()
{
SortOrder = sortOrder,
SearchString = searchString,
PageSize = pageSize,
PageSizeList = new SelectList(new int[]{ 10, 20, 100 }),
Users = users.ToPagedList(page ?? 1, pageSize);
};
return View(model);
}
and in the view
@model TimeReportingWebApp.TimeReportViewMod
@using PagedList.Mvc;
....
@using (Html.BeginForm())
{
@Html.LabelFor(m => m.SearchString)
@Html.TextBoxFor(m => m.SearchString)
@Html.LabelFor(m => m.PageSize)
@Html.DropDownListFor(m => m.PageSize, Model.PageSizeList)
<input type="submit" class="btn btn-primary" value="Search" />
}
....
Page @(Model.Users.PageCount < Model.Users.PageNumber ? 0 : Model.Users.PageNumber) of @Model.Users.PageCount
@Html.PagedListPager(Model.Users, page => Url.Action("Index",
new { page, sortOrder = Model.SortOrder, searchString = Model.SearchString, pageSize = Model.PageSize }) )