Page 2, or 22, or… Whatever

So the pagination service/component works.  Drop in the selector into your template, be sure to import the component in your module and the service in your parent component, and subscribe to the observable from the pagination service that gives you the updated page numbers as you filter/sort data, and you’re good to go.

But as the log grows, that little section at the bottom listing the page links gets longer and longer.  Even with just local testing, my audit log had over 20 pages (when viewing 10 items per page).  So we want to only show 5 pages at a time, and update that as you scroll through (so when you get to page 5, the indicator starts showing more).

Luckily, because we set up the page range as an observable, all the updates we needed to do were in one file- the pagination service.  If we could find a way to take the full pagination array (if you remember from last week, this is just an array of numbers- representing the first item of each page) and cut it down to 5 (easy), then update the contents based on the max and min (a little more complex), then ensure the edge cases (page 1 and page end) don’t break anything (a little more complex), we’d be good to go!

So, setting up the master array is the same process- get the data from the server, and generate an array with the number of the first item on each page.  For a 6 page listing and 10 items on each page, it might end up as: [1, 11, 21, 31, 41, 51].

Then, we find the index of the page we’re currently on:

let paginationArrayMid = this.paginationArray.indexOf(start);

Where ‘start’ is passed in on click of any page indicator (as the first item to be displayed in that page).  Once we get that, we just index back 2 and forward 3 (to account for zero indexing) and we have a 5 item array to pass back in the observable as the entry array.  But first, we have to check if we are on a page that would be too low to index back 2, or too high to index forward 3 (i.e.: the first 2 pages or the last 2 pages).  I used a simple conditional check and assignment- though I’m betting there’s a prettier way:


if(paginationArrayMid - 2 < 0) { 
    paginationArrayMid = 2; 
} else if(paginationArrayMid + 3 > totalPages) {
    paginationArrayMid = totalPages - 3;
}
let paginationArrayMin = paginationArrayMid - 2;
let paginationArrayMax = paginationArrayMid + 3;

Finally, we can update the array we want to show based on where we are in the array with a simple slice- with a check built in to make sure there are at least 5 pages, otherwise, just show the full array:


if(totalPages > this.maxPagesInListing) {
    this.paginationArrayDisplay = this.paginationArray.slice(paginationArrayMin, paginationArrayMax);
} else {
    this.paginationArrayDisplay = this.paginationArray;
}

The ‘this.maxPagesInListing’ variable is just a constant set to whatever you want the displayed page range to be (in our case, it’s 5- but is easily configurable). Then just update the observable and you’re good to go!


this._entryRange.next([start - 1, start + (this.maxItemsOnPage - 1)]);

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s