Pagination is one of those annoying features that aren't fun to implement in any programming language, but a feature that is pretty much essential for a good UI.
Before we start, if you are relatively new to JavaScript, then I recommend Web Design with HTML, CSS, JavaScript and jQuery as a good set of books and a good starting point.
And if you are already familiar with JavaScript, then I can recommend Secrets of the JavaScript Ninja to get some real in depth knowledge on the JavaScript language.
The following implementation covers the basics of what pagination is and how it functions. Feel free to modify it in any way that you wish. A few improvements could be to add numeric paging to it and to allow for multiple pagers per page, etc.
Tabular pagination
What is pagination? We have a collection of data in some format. We then specify a set number of elements that we want to display per page. We render our pagination controls, such as next and previous. And depending on which page we are on, we will cut a chunk of the 'data' out based on the current page and the number of elements per page, and we render only that specific set of data.
We then redraw our pager controls and we're good to go.
In this particular pagination method, the data is already pre-loaded on the page and we are simply selectively choosing which 'chunk' to render.
Define A Few Variables
Let's start by setting up the variables that we will need to store the paging data, such as the number of items per page and the current page we're on, and we'll declare an Array to hold our data. We'll also create a subsection of the Array to store just the currently displayed elements.
// global JavaScript variables
var list = new Array();
var pageList = new Array();
var currentPage = 1;
var numberPerPage = 10;
var numberOfPages = 1; // calculates the total number of pages
The list variable will store the collection of data to be sorted. This can be anything from strings, integers to JavaScript objects. The currentPage variable will keep track of where we are in the pagination. numberPerPage dictates the amount of items to show per page. pageList plays a very important role in the script as it will keep track of the items to display on the current page only.
We don't need to store it separately, but depending on your data it can
make the process easier and for our example, it will make the process
easier to follow. The numberOfPages
is calculated when the page loads and will tell us the total number of
pages required to render the collection. This is necessary if we're
going to be doing numeric pagination.
Next up let's create some sample data to work with. An array of 200 integers should be enough to get an idea of the process.
1. Create A Test List (optional)
If you have data ready to go you can skip this step. Otherwise, run the function onLoad.
function makeList() {
for (x = 0; x < 200; x++)
list.push(x);
}
function load() {
makeList();
}
window.addEventListener('load', load);
2. Calculate Number of Pages
We'll need to know the number of pages in our application so that we can handle enabling and disabling the pager buttons accordingly. For example, getting to the last page will automatically disable the next and last buttons, etc. We can add this functionality to our load function as well.
function load(){
makeList();
numberOfPages = getNumberOfPages();
loadList)(;
}
function getNumberOfPages() {
return Math.ceil(list.length / numberPerPage);
}
The number of pages can be calculated by dividing the total number of items in the collection by the number of items to display per page. So a collection of 33 items showing 10 per page would return 4 pages in total (rounding up).
3. Create Paging Buttons
We'll be making a first-next-previous-last pager to navigate through the pages. After each page is loaded a check will occur to verify the state of all the buttons, such as disabling the next button when the last page is reached as mentioned previously.
The following HTML will render the pagination controls.
<input type="button" id="first" onclick="firstPage()" value="first" />
<input type="button" id="next" onclick="nextPage()" value="next" />
<input type="button" id="previous" onclick="previousPage()" value="previous" />
<input type="button" id="last" onclick="lastPage()" value="last" />
Each button control will call a different function. The only difference in each functions implementation is the value of the currentPage variable that gets set. After that we call loadList(), which is the function that will draw the elements onto the screen.
The nextPage function is implemented as follows:
function nextPage() {
currentPage += 1;
loadList();
}
While the previousPage function is as such:
function previousPage() {
currentPage -= 1;
loadList();
}
Here is the firstPage function
function firstPage() {
currentPage = 1;
loadList();
}
And last but not least, the lastPage function.
function lastPage() {
currentPage = numberOfPages;
loadList();
}
It's essentially the same function called each time with a change in a variable. For something this simple, inlining the script might be preferred. You can also create a single function to handle this process and simply add a parameter to control the currentPage variable. But for the sake of explaining the process, I broke it down into 4 separate functions.
4. LoadList()
Next up is splitting our data up into their appropriate page counterparts. First, we calculate the index of the first element and of the last element for that particular page.
For example, on page 1 the first element would be at index '0' and the
last element on index '9' (if the page size is 10).
Next we call the slice function of our Array and tell it where to start slicing from and where to end. The result will be another Array with
just the elements that we're currently looking for.
You start at the
current page, minus one, plus the page offset. And the end is just that
start number plus the offset again. The 2 new functions at the bottom drawList and check will render the subset and then update the pager buttons respectively.
function loadList() {
var begin = ((currentPage - 1) * numberPerPage);
var end = begin + numberPerPage;
pageList = list.slice(begin, end);
drawList(); // draws out our data
check(); // determines the states of the pagination buttons
}
5. Draw The List
The drawList function will draw to the page only the values in the pageList Array variable, which is the subset of data that we wish to display.
function drawList() {
document.getElementById("list").innerHTML = "";
for (r = 0; r < pageList.length; r++) {
document.getElementById("list").innerHTML += pageList[r] + "
";
}
}
6. Update Button Statuses
So far we have an Array with the items to paginate through, and our control buttons that will determine which page we go to next. And we have our function that will draw the elements for the current page that we are on. That's a fully working pagination module.
But, we can do a bit better. After each new subset is loaded we'll want
to determine the state of the paging buttons (next, prev, first, last).
For example, if we are on page 1, then our first and previous buttons should be disabled. We can run the following function after each new page list is generated.
function check() {
document.getElementById("next").disabled = currentPage == numberOfPages ? true : false;
document.getElementById("previous").disabled = currentPage == 1 ? true : false;
document.getElementById("first").disabled = currentPage == 1 ? true : false;
document.getElementById("last").disabled = currentPage == numberOfPages ? true : false;
}
You could also add the ability to wrap back around to the 1st page once the user selects next from the last.
7. Full Working Code
Here is the full working JavaScript example for your copy/paste pleasure.
<script type="text/javascript">
var list = new Array();
var pageList = new Array();
var currentPage = 1;
var numberPerPage = 10;
var numberOfPages = 0;
function makeList() {
for (x = 0; x < 200; x++)
list.push(x);
numberOfPages = getNumberOfPages();
}
function getNumberOfPages() {
return Math.ceil(list.length / numberPerPage);
}
function nextPage() {
currentPage += 1;
loadList();
}
function previousPage() {
currentPage -= 1;
loadList();
}
function firstPage() {
currentPage = 1;
loadList();
}
function lastPage() {
currentPage = numberOfPages;
loadList();
}
function loadList() {
var begin = ((currentPage - 1) * numberPerPage);
var end = begin + numberPerPage;
pageList = list.slice(begin, end);
drawList();
check();
}
function drawList() {
document.getElementById("list").innerHTML = "";
for (r = 0; r < pageList.length; r++) {
document.getElementById("list").innerHTML += pageList[r] + "<br/>";
}
}
function check() {
document.getElementById("next").disabled = currentPage == numberOfPages ? true : false;
document.getElementById("previous").disabled = currentPage == 1 ? true : false;
document.getElementById("first").disabled = currentPage == 1 ? true : false;
document.getElementById("last").disabled = currentPage == numberOfPages ? true : false;
}
function load() {
makeList();
loadList();
}
window.onload = load;
</script>
<div style="text-align:center;">
<input type="button" id="first" onclick="firstPage()" value="first" />
<input type="button" id="next" onclick="nextPage()" value="next" />
<input type="button" id="previous" onclick="previousPage()" value="previous" />
<input type="button" id="last" onclick="lastPage()" value="last" />
<div id="list"></div>
</div>
Fork on Codepen.io
Update 1: I have updated the code to include numeric pagination, which you can find here.
Update 2: If you are rendering more complex HTML elements to your list, you can find out how to do that over in this article.