In Part 1, we're just going to set up the logic and a fixed pager
- You'll need to create a new project, using the MVC web template.
- Create a new class in your models folder called People. Give them 2 properties: Id and Name.
- Set up your database with entity framework. Seed it with 12 people. Here's my class & seed data.
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
Seeder
context.People.AddOrUpdate(
p => p.Id,
new Person { Id=1, Name="Alex" },
new Person { Id=2, Name="Aaron" },
new Person { Id=3, Name="Amish" },
new Person { Id=4, Name="David" },
new Person { Id=5, Name="Miguel" },
new Person { Id=6, Name="Andrew" },
new Person { Id=7, Name="Andy" },
new Person { Id=8, Name="Josh" },
new Person { Id=9, Name="Grey" },
new Person { Id=10, Name="Yola" },
new Person { Id=11, Name="Mark" },
new Person { Id=12, Name="Max" },
new Person { Id=13, Name="Ben" }
);
Before we start building I think it's useful to look at how pagers work.
There are two key variables:
- How many results you want on a page: I'll call this variable PageSize.
- What page the viewer is on. I'll call this CurrentPage.
- There is a third variable called Skip that we'll get to in a second.
Lets look at what happens when a visitor uses our pager
The visitor goes to our page for the first time. Page counting will start at 0.
Our Controller accesses the Database. Does any sorting. Sort first, or you're gonna have a bad time. THEN pulls the number of records we set PageSize. In this case lets assume we set it to three. The controller passes those records to the view, view displays those three records.
The visitor clicks over to page 2.
Same as before. Our Controller accesses the Database. Sorts.Skip requires some kind of sort even if it's just by Id. Does a Skip. Then pulls the number of records we set in PageSize. To calculate the Skip you multiply the PageSize and CurrentPage.
First page you skip 0 (this is why you start counting pages at 0), Second page you skip 3, etc...
Go ahead and set up an MVC project, using the above classes and seeder, seed your database.
Onto Code...
Go into your home controller and create a new Action Result with a call to the database.
public ActionResult People()
{
ApplicationDbContext db = new ApplicationDbContext(); List<Person> people = db.People.ToList();
return View(people);
}
{
ApplicationDbContext db = new ApplicationDbContext(); List<Person> people = db.People.ToList();
return View(people);
}
Create a view to match the new action result and put a loop creating a table in it.
<table class="table table-responsive table-striped">
@foreach (var item in Model)
{
<tr><td>@item.Id</td><td>@item.Name</td></tr>
}
</table>
You'll also want to add your @model statement to the top of your view if you haven't
@model IEnumerable<RaginPagin.Models.Person>
If you run this you get all of the results on a single page. We only want 3 results first. To get only 3 modify the People Action code as follows.
public ActionResult People()
{
ApplicationDbContext db = new ApplicationDbContext();
int PageSize = 3;
List<Person> people = db.People.Take(PageSize).ToList();
return View(people);
}
We get three results on the first page but there's no way to move forward. We'll need something in the view to help us navigate. add the following under the table in your view.
<ul class="pagination">
<li><a href="~/home/people/0">1</a></li>
<li><a href="~/home/people/1">2</a></li>
<li><a href="~/home/people/2">3</a></li>
<li><a href="~/home/people/3">4</a></li>
<li><a href="~/home/people/4">5</a></li>
</ul>
Note that the link text is one more than the CurrentPage
<li><a href="~/home/people/0">1</a></li>
If we run this, we'll still get the page, only three but the pages all return the same three results.
We need to go back to our HomeController and tell it what to do with the CurrentPage we're passing it at the end of the URL.
public ActionResult People(int? id)
{
ApplicationDbContext db = new ApplicationDbContext();
int PageSize = 3;
skip = PageSize * id.Value;
List<Person> people = db.People.OrderBy(p=>p.Id).Skip(skip).Take(PageSize).ToList();
return View(people);
}
@foreach (var item in Model)
{
<tr><td>@item.Id</td><td>@item.Name</td></tr>
}
</table>
You'll also want to add your @model statement to the top of your view if you haven't
@model IEnumerable<RaginPagin.Models.Person>
If you run this you get all of the results on a single page. We only want 3 results first. To get only 3 modify the People Action code as follows.
public ActionResult People()
{
ApplicationDbContext db = new ApplicationDbContext();
int PageSize = 3;
List<Person> people = db.People.Take(PageSize).ToList();
return View(people);
}
We get three results on the first page but there's no way to move forward. We'll need something in the view to help us navigate. add the following under the table in your view.
<ul class="pagination">
<li><a href="~/home/people/0">1</a></li>
<li><a href="~/home/people/1">2</a></li>
<li><a href="~/home/people/2">3</a></li>
<li><a href="~/home/people/3">4</a></li>
<li><a href="~/home/people/4">5</a></li>
</ul>
Note that the link text is one more than the CurrentPage
<li><a href="~/home/people/0">1</a></li>
If we run this, we'll still get the page, only three but the pages all return the same three results.
We need to go back to our HomeController and tell it what to do with the CurrentPage we're passing it at the end of the URL.
public ActionResult People(int? id)
{
ApplicationDbContext db = new ApplicationDbContext();
int PageSize = 3;
skip = PageSize * id.Value;
List<Person> people = db.People.OrderBy(p=>p.Id).Skip(skip).Take(PageSize).ToList();
return View(people);
}
Here is where we implement the Skip Linq call. Skip requires some sort or order on the data before it will run. I did this with another Linq call ordering the data by Id
The parameter of the current page is coming through as the id. It needs to be nullable to handle the default case of no parameter passed.
You then need to handle the possibility of Null for id. I handle it like this.
public ActionResult People(int? id)
{
ApplicationDbContext db = new ApplicationDbContext();
int PageSize = 3;
int skip = 0;
if (id.HasValue) {
skip = PageSize * id.Value;
}
List<Person> people = db.People.OrderBy(p=>p.Id).Skip(skip).Take(PageSize).ToList();
return View(people);
}
{
ApplicationDbContext db = new ApplicationDbContext();
int PageSize = 3;
int skip = 0;
if (id.HasValue) {
skip = PageSize * id.Value;
}
List<Person> people = db.People.OrderBy(p=>p.Id).Skip(skip).Take(PageSize).ToList();
return View(people);
}
Here's the raw video an edited version is planned.
This is great site. Many thanks for advice and I will tell all colleague.
ReplyDelete