Page 1 of 1

Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 8:18 am
by simonmlewis
I have a set of around 24 pages of content, and rather than 24 links, plus the Next, Last etc, it would be good to know how to make it like so:

First, Prev, 1, 2, 3, 4, 5 ...... 20, 21, 22, 23, 24, Next, Last

Do you have to literally put dots in the code, and tell it not to display the DIV if the number == 6, 7... and so on?
Though if you did, it would NEVER show.

Re: Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 8:20 am
by simonmlewis
This is how the code is set now.

Code: Select all

$maxPage = ceil($numrows/$rowsPerPage);
 
// print the link to access each page
$self = $_SERVER['PHP_SELF'];
$nav  = '';
 
for($page = 1; $page <= $maxPage; $page++)
{
   if ($page == $pageNum)
   {
      $nav .= " $page "; // no need to create a link to current page
   }
   else
   {
      $nav .= " <a href=\"/accessories/page/$page/\" class='pagelink'>$page</a>";
   }
}
 
// creating previous and next link
// plus the link to go straight to
// the first and last page
 
if ($pageNum > 1)
{
   $page  = $pageNum - 1;
   $prev  = " <a href=\"/accessories/page/$page/\" class='pagelink'>[Prev]</a> ";
 
   $first = " <a href=\"/accessories\" class='pagelink'>[First Page]</a>";
}
else
{
   $prev  = '&nbsp;'; // we're on page one, don't print previous link
   $first = '&nbsp;'; // nor the first page link
}
 
if ($pageNum < $maxPage)
{
   $page = $pageNum + 1;
   $next = " <a href=\"/accessories/page/$page/\" class='pagelink'>[Next]</a>";
 
   $last = " <a href=\"/accessories/page/$maxPage/\" class='pagelink'>[Last Page]</a>";
}
else
{
   $next = '&nbsp;'; // we're on the last page, don't print next link
   $last = '&nbsp;'; // nor the last page link
}
 
// print the navigation link
echo "</div><div class='navpages'>" . $first . $prev . $nav . $next . $last . "</div>";

Re: Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 9:13 am
by Celauran
Rather than iterating over the complete set, you could iterate twice; once from page 1 to, say, 5, then again from $maxPage - 5 to $maxPage. Insert your dots in between.

Re: Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 9:37 am
by simonmlewis
I'm not exactly sure how you mean.

You obviously mean in this bit of code. I need to make it do it only if there are x amount of pages though. Though I guess that bit is easy.

Code: Select all

for($page = 1; $page <= $maxPage; $page++)
{
   if ($page == $pageNum)
   {
      $nav .= " $page "; // no need to create a link to current page
   }
   else
   {
      $nav .= " <a href=\"/airsoft-accessories/page/$page/\" class='pagelink'>$page</a>";
   }
}

Re: Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 9:44 am
by Celauran
Using that bit of code you posted, and assuming you wanted to display the first 5 ... last 5 links, you could do something like this:

Code: Select all

<?php

if ($maxPage <= 10) {
    for($page = 1; $page <= $maxPage; $page++)
    {
       if ($page == $pageNum)
       {
          $nav .= " $page "; // no need to create a link to current page
       }
       else
       {
          $nav .= " <a href=\"/airsoft-accessories/page/$page/\" class='pagelink'>$page</a>";
       }
    }
} else {
    for ($page = 1; $page <= 5; $page++) {
       if ($page == $pageNum)
       {
          $nav .= " $page "; // no need to create a link to current page
       }
       else
       {
          $nav .= " <a href=\"/airsoft-accessories/page/$page/\" class='pagelink'>$page</a>";
       }    
    }
    $nav .= "...";
    for ($page = $maxPage - 5; $page <= $maxPage; $page++) {
       if ($page == $pageNum)
       {
          $nav .= " $page "; // no need to create a link to current page
       }
       else
       {
          $nav .= " <a href=\"/airsoft-accessories/page/$page/\" class='pagelink'>$page</a>";
       }    
    }
}

Re: Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 9:45 am
by Celauran
That is, admittedly, a little over simplified as you'd need to account for situations where the current page falls within that middle range (say you're on page 11 of 26), but that's the general idea.

Re: Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 9:47 am
by Celauran
What I'll typically do, though, is use a range of X pages centered on the current page, along with first, previous, next, and last buttons.
[text]<< < 3 4 5 6 7 8 9 > >>[/text]

Re: Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 10:08 am
by simonmlewis
Yes I see the issue with the page number within the dots - and just came a cropper with that!
So how would I do it with the range of X Pages. As I could easily just add on the page "total page: 15" at the end.

Re: Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 10:32 am
by Celauran
This is a simple paginator I wrote quite a while ago. I had to modify it slightly to not rely on other classes (models, requests, etc) so it might not be 100% perfect, but it should do what you need.

Code: Select all

<?php

class Paginator {

    protected $page;
    protected $per_page;
    protected $results;

    /**
     * @param (int) $results   The total number of entities in the result set
     * @param (int) $per_page  Number of items to display on a page
     */
    public function __construct($results, $per_page = 10) {
        $this->page = 1;
        $this->per_page = $per_page;
        $this->results = $results;
    }

    public function getPage() {
        return $this->page;
    }

    public function setPage($page) {
        $this->page = (int) $page;
    }

    /**
     * @return (int) Total number of pages
     */
    public function getPageCount() {
        return ceil($this->results / $this->per_page);
    }

    /**
     * @param (int) $count Number of pages to display in paginator
     */
    public function getPageNumbers($count) {
        $numbers = array();

        if ($this->page < ceil($count / 2)) {
            for ($i = 1; $i <= $count; $i++) {
                $numbers[] = $i;
            }
        } else if (($this->getPageCount() - $this->page) < ceil($count / 2)) {
            for ($i = $this->getPageCount() - ($count - 1); $i <= $this->getPageCount(); $i++) {
                $numbers[] = $i;
            }
        } else {
            for ($i = $this->page - (floor($count / 2)); $i <= $this->page + (floor($count / 2)); $i++) {
                $numbers[] = $i;
            }
        }

        return $numbers;
    }

    /**
     * @param (int) $count  Number of pages to display in the paginator
     *
     * @return (array)  Array containing first, previous, ..., next, last pages
     */
    public function getPagesForDisplay($count = 7) {
        $pages = array(
            'first' => 1,
            'last' => $this->getPageCount(),
        );

        if ($this->page > 1) {
            $pages['previous'] = $this->page - 1;
        }

        $pages['numbers'] = $this->getPageNumbers($count);

        if ($this->page < $this->getPageCount()) {
            $pages['next'] = $this->page + 1;
        }

        return $pages;
    }
}
Pass your row count to the paginator, and optionally the number of items you'd like per page. The getPagesForDisplay method will return the specified number of pages (defaults to 7) centered around the current page (which you can set via setPage method)

Re: Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 10:41 am
by simonmlewis
Sorry, but I wish I had the knowledge to understand what you have written there, as well as to integrate that into my code.

I have seen code that has the dots, like you did earlier, and then still shows the page that you are on. That would be better. Tho it might vbe a combination of the two.

Re: Page Numbering: how do you get the ... between them?

Posted: Wed Jun 24, 2015 10:49 am
by Celauran
It's really quite simple. Something like this should do, but use it or don't, as you wish.

Code: Select all

<?php
...
$results = mysql_num_rows($result); // or similar
$paginator = new Paginator($results);
$pages = $paginator->getPagesForDisplay();
...
?>
<ul id="paginator">
    <?php if (isset($pages['first'])): ?>
        <li><a href="/some/page/here/<?= $pages['first']; ?>">&laquo;</a></li>
    <?php endif; ?>

    <?php if (isset($pages['previous'])): ?>
        <li><a href="/some/page/here/<?= $pages['previous']; ?>">&lsaquo;</a></li>
    <?php endif; ?>

    <?php foreach ($pages['numbers'] as $page): ?>
        <?php if ($page == $paginator->getPage()): ?>
            <li><?php echo $page; ?></li>
        <?php else: ?>
            <li><a href="/some/page/here/<?= $page; ?>"><?php echo $page; ?></a></li>
        <?php endif; ?>
    <?php endforeach; ?>

    <?php if (isset($pages['next'])): ?>
        <li><a href="/some/page/here/<?= $pages['next']; ?>">&rsaquo;</a></li>
    <?php endif; ?>

    <?php if (isset($pages['last'])): ?>
        <li><a href="/some/page/here/<?= $pages['last']; ?>">&raquo;</a></li>
    <?php endif; ?>
</ul>