Pagination

2008-11-12

I really hate creating pagination but for some things you just can't avoid it. So let me paste a rather generic PHP script to create pagination so that I don't have to bother with this annoying "math" anymore.

You call it by pagination(20, 2, 5, "http://qfox.nl/blog?5,") or something. If you need a different url structure you can obviously tinker that in yourself. The same goes for the layout, all css is inline except for the class given below.

An example can be found here, once there are enough topics (25+).

Have fun with it. Hope it helps you.

Code: (CSS)
.pag { display: block; float: left; height: 21px; width: 25px; text-align: center; border: 1px solid white; padding-top: 4px; margin-right: 2px; }
.pag:hover { border: 1px solid red; }


Code: (PHP)
function pagination($totalitems, $currentpage, $itemsperpage, $urlprefix, $evenwhenitsuseless = false) {
$extra = 6; // on each side, except start/end/hellips
$maxboxes = (2*$extra)+4;

// get number of pages
$lastpage = floor((($totalitems-1)/$itemsperpage))+1;

// no point in pagination if there is just one page
if ($lastpage < 2 && !$evenwhenitsuseless) return;

// first get the start-end numbers without padding
$startpage = max(2,($currentpage-$extra));
$endpage = min($lastpage - 2, $currentpage + $extra+1);

// now pad to fit $maxboxes pages (4 for start/end and hellipses)
$padright = max(0, $extra-$currentpage+2);
$padleft = max(0, ($currentpage - ($lastpage-$extra)) + 3);

// for the loop
$starti = max(2, $startpage - $padleft);
$endi = min($lastpage-2, $endpage+$padright);

// first page
paginate(0, $currentpage, $urlprefix);
// second page, if there are more...
if ($starti === 2 && $lastpage > 1) paginate(1, $currentpage, $urlprefix);
elseif ($starti > 2 && $lastpage > 1) paginate(0,0,null,true);

if ($lastpage > 2) { // 1 and 2 are painted outside of this loop (regardless), the loop is useless if there are <3 pages
for ($i=$starti; $i<$endi; ++$i) {
paginate($i, $currentpage, $urlprefix);
}
}

if ($endpage > 0) {
// second last page, if there are more
if ($endi === $lastpage -2 && $lastpage > 3) paginate($endpage, $currentpage, $urlprefix);
if ($endi < $lastpage-2 && $lastpage > 3) paginate(0,0,null,true);
// last page
paginate($lastpage-1, $currentpage, $urlprefix);
}
echo "

";
}
function paginate($i, $currentpage, $urlprefix, $hellips = false) {
if ($hellips) {
echo "";
}
elseif ($i == $currentpage) {
echo "".($i+1)." ";
}
else {
echo "".($i+1)."";
}
}

And here's a port to Javscript (added; March 2009)

Code: (JS)
function pagination(intTotalItems, intCurrentPage, intItemsPerPage, strUrlPrefix, boolEvenWhenItsUseless) {
var paginate = function(j, boolHellips) {
if (boolHellips) return "";
if (j === intCurrentPage) return ""+(j+1)+" ";
return ""+(j+1)+"";
}

var extra, maxboxes, lastpage, startpage, endpage, padleft, padright, starti, endi, i, strContent="";

extra = 4; // number of page buttons on each side of the current page (excluding start/end/hellips)
maxboxes = (2*extra)+4;

// get number of pages
lastpage = Math.floor(((intTotalItems-1)/intItemsPerPage))+1;

// no point in pagination if there is just one page
if (lastpage < 2 && !boolEvenWhenItsUseless) return;

// first get the start-end numbers without padding
startpage = Math.max(2,(intCurrentPage-extra));
endpage = Math.min(lastpage - 2, intCurrentPage + extra + 1);

// now pad to fit $maxboxes pages (4 for start/end and hellipses)
padright = Math.max(0, extra-intCurrentPage+2);
padleft = Math.max(0, (intCurrentPage - (lastpage-extra)) + 3);

// for the loop
starti = Math.max(2, startpage - padleft);
endi = Math.min(lastpage-2, endpage+padright);

// first page
strContent += paginate(0);
// second page, if there are more...
if (starti === 2 && lastpage > 1) strContent += paginate(1);
else if (starti > 2 && lastpage > 1) strContent += paginate(0, true);

if (lastpage > 2) { // 1 and 2 are painted outside of this loop (regardless), the loop is useless if there are <3 pages
for (i=starti; i strContent += paginate(i);
}
}

if (endpage > 0) {
// second last page, if there are more
if (endi === lastpage -2 && lastpage > 3) strContent += paginate(endpage);
if (endi < lastpage-2 && lastpage > 3) strContent += paginate(0, true);
// last page
strContent += paginate(lastpage-1);
}

return strContent+"


";
}

Hope it helps you.