Ok, so you can find the pagination tutorial in the bootstrap documentation, and it looks great, works great, but there is one thing that is missing, the JavaScript that actually links the pagination widget to the pages that you create in your application. This article will explain in detail how you can connect the pagination widget to a series of div’s that contain well, whatever you want them to.
First, you should go to the Bootstrap page http://twitter.github.io/bootstrap/components.html#pagination and take a look at the pagination example. The code from the page above is below.
<div class="pagination"> <ul> <li class="disabled"><a href="#">«</a></li> <li class="active"><a href="#">1</a></li> </ul> </div>
That’s all there is to building the widget that provides the pagination bar on your page, and admit it looks pretty cool out of the box, but this is just the UI, there is nothing on the page to show you how to use it. Now that you have taken a look let’s set up a real world working set of div’s and the corresponding li options.
<div class="pagination-container" >
<div data-page="1" >
Content for Div Number 1
</div>
<div data-page="2" style="display:none;">
Content for Div Number 2
</div>
<div data-page="3" style="display:none;">
Content for Div Number 3
</div>
<div data-page="4" style="display:none;">
Content for Div Number 4
</div>
<div data-page="5" style="display:none;">
Content for Div Number 5
</div>
<div class="pagination pagination-centered pagination-large" style="position:absolute; bottom:0;">
<ul class="page_control ">
<li data-page="-" ><a href="#" ><</a></li>
<li class="active" data-page="1">
<a href="#" >1</a>
</li>
<li data-page="2"><a href="#" >2</a></li>
<li data-page="3"><a href="#" >3</a></li>
<li data-page="4"><a href="#" >4</a></li>
<li data-page="5"><a href="#" >5</a></li>
<li data-page="+"><a href="#" >></a></li>
</ul>
</div>
</div>
Now, let me explain what has been added to the example code from the Bootstrap page. To start things off I wrapped the content div’s as well as the pagination widget in a div named pagination-container, this step is crucial as the JQuery JavaScript will later use this as a way to find the child div tags. Next, notice the inclusion of the div’s that will contain the content you would like to switch out. Inside these tags you will have noticed that there is an attribute named data-page and each div has a numerical value starting at 1. The data attribute is a new to HTML5 and allows you to store name, value pairs inside of any HTML tag. This tag is intended to be a custom data element that should store private data for which there are no more appropriate attributes or elements. You can read more about the data attribute at w3.org. JQuery happens to have a nice set of built in methods that allow you to access and use the values that can be found in the data attribute. For an in depth look at Jquery.data() take a look at the following resource (http://api.jquery.com/jQuery.data/). After looking at the content holders , you may have noticed the inclusion of the inline style attribute on the container that holds the bootstrap.
style="position:absolute; bottom:0;"
The CSS above just positions the paginator to the bottom of the pagination-container div. This is pretty important as you want to give the appearance that the paginator is static, and it would jump when the height of the content tags change otherwise.
The changes in the li tags that make up the bootstrap paginator’s ‘buttons’ include the addition of the data attributes. After careful inspection, you notice that the data element values and name matches with the data elements that can be found on in the top level div tags.
Now let’s take a look at the script that runs the paginator. We’ll add a function in the script tags named paginationHandler, the code for the function can be found below.
var paginationHandler = function(){
$('.page_control li').unbind('click', paginationHandler);
var currentPage = $(this).data('page'),
activePage = $(this).parent().find('.active').data('page'),
num_elements = $(this).parent().children().length,
// This equals the first data-page value after the < button.
start = 1,
// This is the end of the actual pages, remember it is offset by the < and > buttons.
end = num_elements – 2;
if(currentPage === '+' ){
(activePage < end) ? currentPage = activePage + 1 : currentPage = start;
}
if(currentPage === '-'){
(activePage > start) ? currentPage = activePage - 1 : currentPage = end;
}
// Remove the active class to the li
$(this).parent().find('.active').removeClass('active');
// Add the active class to the appropriate li taking
$(this).parent().find('li[data-page*=' + currentPage + ']').addClass('active');
// Add a fade out / in effect to the div holding the
// actual data. You must have a div with the data-page
// attribute for every li tag that contains the same
// data attribute or you will get unreliable
// results.
$(this).parents("div .pagination-container").find('div[data-page*=' + activePage + ']').fadeOut('fast', function(){
$(this).parents("div .pagination-container").find('div[data-page*=' + currentPage + ']').fadeIn('fast');
$('.page_control li').bind('click', paginationHandler);
});
}
Next, we have to bind the function to the li tags that reside in the div with the class .page_control. The code to do so is below.
$('.page_control li').bind('click', paginationHandler );
Now let me explain. The first line in our function unbinds the event from the li tag. This is done because if the user decides to click repeatedly on say the ‘next’ button before the fade in animation has completed then all hell will break loose and you may have several div tags displayed at one.
$(this).data(‘page’) actually gets the value in the data attribute and stores it in the current page variable. The next line goes up to the parent tag of the li that was clicked, which is of course, the ul tag and finds the element that contains the active class, and gets the value in the data element of that li tag. This gives you the active page number. The next line gets the total length of the pagination elements, so say if you wanted to make this example work for ten elements instead of five just add the li tags and div tags, no need to modify the JavaScript. Start is always going to be one and remember we have two elements that are not actually pages, they are the next and previous buttons, so deduct two from the total number of elements to get the ending page.
The two if statements handle the user pressing the next and the previous button. One feature I added was the ability to go back to start so to speak if you page past the last element, you may need to modify the code here to 1) add more elements, or 2) just stop at the end, it’s your call.
The line below removes the active class from the pagination widget, and the second line adds the active class to the new current page of the widget.
// Remove the active class to the li
$(this).parent('ul').children('.active:first').removeClass('active');
// Add the active class to the appropriate li taking
$(this).parent().find('li[data-page*=' + currentPage + ']').addClass('active');
This next piece fades out the current content div and then fades in the new content div, and last but not least, we rebind the function to the li elements so that the user can once again click the li tags and change the content.
// Add a fade out / in effect to the div holding the
// actual data. You must have a div with the data-page
// attribute for every li tag that contains the same
// data attribute or you will get unreliable
// results.
$(this).parents("div .pagination-container").find('div[data-page*=' + activePage + ']').fadeOut('fast', function(){
$(this).parents("div .pagination-container").find('div[data-page*=' + currentPage + ']').fadeIn('fast');
$('.page_control li').bind('click', paginationHandler );
});
You will need:
http://twitter.github.io/bootstrap/index.html
