Last Updated: February 25, 2016
·
1.364K
· jesuscast

Badass handmade pagination in php

Alright so I was trying to implement a pagination system in my laravel application but everything made me create many files and I thought it could be simplier. So I made this.

First of all I want my pagination to be like this:

  1. It can show about 10 pages in the pagination but it could be changed.
  2. It has previous and next arrows.
  3. Somehow it highlights the current page in the pagination.
  4. The number of items per page can be changed.

First of all I made a little php snippet to test the concept. It uses << as the previous and >> as the next arrows, and it highlights the current page number with this double dashes around ex --3--

So let's say that the total number of items is 200 and the pagination shows 4 pages with 9 items per page. That gives us about 22 total pages.

If we are in page 1 it should look like this:

--1--       2       3    4   >>

if we are in page 8

<<     --8--     9     10    11    >>

If we are in page 22

<<   20   20   21   --22--

CODE:

$paginate = True;

//Retrieve those values from your database
$totalItems = 200; //I would retrieve the total items from the database
$page = 22;  //and I would retrieve this with a $_GET['page'] so they could 
//write something like http://yoursite/show/products?page=12


$itemsPerPage = 9; //set this up
$pagesInPagination = 4; //set this up too

//we calcute the last page by dividing and we round up
//to show all the items even though they are not gonna fill the whole page
$lastPage = ceil($totalItems/$itemsPerPage); 
$previousPage = ($page > 1)? ($page-1):1;
$nextPage = ($page!=$lastPage)? ($page+1):$page;

//the pagination is going to be a string with all the values
//I save it in a variable so we could use it several times in the page
//for example, at the top and at the bottom of each page
$pagination = "";

if($paginate==True and $lastPage>$pagesInPagination){
    $modOf = $page%$pagesInPagination;
    if((($page-$modOf)/$pagesInPagination)!=0){ 
        // we are in the middle of the list
        //therefore we need << to get to the previous set of pages
        $pagination .= "<<"; 
    }
    else { //we are in the first bunch of elements so we don't need <<
        $pagination.="";
    }
    for($i = ($page-$modOf); $i<=($page-$modOf+$pagesInPagination); $i++){
        if($i == $lastPage){
            //if we are in the last page we gotta stop
            //no matter that we cannot complete the pages in pagination value,
            //but we fill the pagination with pages from behind
            $pagination  = str_replace("<<", "", $pagination);
            $pagination = "<< ".($i-($pagesInPagination-$modOf))." ".$pagination;
            break;
        }
        else {
            if(($i == $page) && ($i!=0)){
                //mark the current page
                $pagination.=" --".$i."-- ";    
            }
            else if($i!=0){
                //just add the number
                $pagination.=" ".$i." ";    
            }
        }
    }
    if($page!=($lastPage-1)){
        //to go to the next page because we are not at the end yet
        $pagination.=">>";    
    }
    else {
        $pagination.="";
    }
}
else { 
    //since we cannot complete a whole pagination
    //we just show all the pages we can and highlight the current one
    for($i = 1; $i<= $lastPage; $i++ ){
        if($i==$page){
            $pagination.= " --".$i."-- ";
        }
        else{
            $pagination.=" ".$i." ";
        }
    }
}
echo($pagination);

NOW that we see that that thing works, let's make it real. I'm going to use the bootstrap pagination
styles because they look pretty.

As we see the only thing we need to do is to replace the "--".$i."--" for some divs and ul's and li's.
Keep in mind that in order to make it look nice you have to have bootstrap 3 or whatever bootstrap was available at June 15 2014.

//Those variables are for your project
//change them!
$yourUrl = "https://yourwebsite.com/products";

$paginate = True;

//Retrieve those values from your database
$totalItems = 200; //I would retrieve the total items from the database
$page = 22;  //and I would retrieve this with a $_GET['page so they could ']
//write something like http://yoursite/show/products?page=12


$itemsPerPage = 9; //set this up
$pagesInPagination = 4; //set this up too

//we calcute the last page by dividing and we round up
//to show all the items even though they are not gonna fill the whole page
$lastPage = ceil($totalItems/$itemsPerPage); 
$previousPage = ($page > 1)? ($page-1):1;
$nextPage = ($page!=$lastPage)? ($page+1):$page;

//the pagination is going to be a string with all the values
//I save it in a variable so we could use it several times in the page
//for example, at the top and at the bottom of each page
$paginationDiv = "";

if($paginate==True and $lastPage>$pagesInPagination){
    $modOf = $page%$pagesInPagination;
    if((($page-$modOf)/$pagesInPagination)!=0){ 
        // we are in the middle of the list
        //therefore we need << to get to the previous set of pages
        $paginationDiv.= "<div class='text-center'><ul class='pagination'><li><a class='' href='".$yourUrl."?page=".$previousPage."'>&laquo;</a></li>";
    }
    else { //we are in the first bunch of elements so we don't need <<
        $paginationDiv.="<div class='text-center'><ul class='pagination'>";
    }
    for($i = ($page-$modOf); $i<=($page-$modOf+$pagesInPagination); $i++){
        if($i == $lastPage){
                    /*
                      I'm just writing break instead of the replacing function of the code from above
                    because replacing in this more complicated string could lead to problems
                    since you would be modifying it and I can't really tell which pattern I could use, it            would be a mess so I'm just showing
                     available pages in this last pagination*/
            break;
        }
        else {
            if(($i == $page) && ($i!=0)){
                //mark the current page
                $paginationDiv.="<li class='active'><a class='' href='".$yourUrl."?page=".$i."'>".$i."</a></li>";
            }
            else if($i!=0){
                //just add the number
                $paginationDiv.="<li><a class='' href='".$yourUrl."?page=".$i."'>".$i."</a></li>";   
            }
        }
    }
    if($page!=($lastPage-1)){
        //to go to the next page because we are not at the end yet
        $paginationDiv.="<li><a class='' href='".$yourUrl."?page=".$nextPage."'>&raquo;</a></li></div><!-- end text-center for pagination--></ul><!-- end pagination-->";
    }
    else{
        $paginationDiv.="</div><!-- end text-center for pagination--></ul><!-- end pagination-->";
    }
}
else { 
    //since we cannot complete a whole pagination
    //we just show all the pages we can and highlight the current one
    for($i = 1; $i<= $lastPage; $i++ ){
        if($i==$page){
            $paginationDiv.="<li class='active'><a class='' href='".$yourUrl."?page=".$i."'>".$i."</a></li>";
        }
        else if($i!=0){
            //just add the number
            $paginationDiv.="<li><a class='' href='".$yourUrl."?page=".$i."'>".$i."</a></li>";   
        }
    }
}
echo($paginationDiv);

Here are some images of how this looks like

Picture

Picture

Picture

I'm sorry but I think that when I was using the conditional operator (condition)?value1:value2 coderwall thought it was the end of a php file and so it put in two boxes, just take the code from one box and put the code from the other right next to it