views:

96

answers:

1

<< 1 2 3 4 ... 15 16 17 ... 47 48 49 50 >>

<< 1 2 3 4 5 6 7 ... 47 48 49 50 >>

<< 1 2 3 4 ... 44 45 46 47 48 49 50 >>

(the bold is the selected page)

Is there any cleaver logic out there that creates scaling pagination like this? I have created one of these before but it ended up as a mess of logic statements.

The language i am doing this in now is PHP but if you have examples or tips for any language, it would be appreciated.

By scaling i mean when there are only a few pages. The pagination displays this.

<< 1 2 3 4 5 6 7 >>

As the number of pages grow to a certain point, the pagination stops showing all numbers and starts splitting them up.

<< 1 2 3 4 ... 47 48 49 50 >>

<< 1 2 3 4 5 6 ... 47 48 49 50 >>

<< 1 2 3 4 5 6 7 8 ... 47 48 49 50 >>

<< 1 2 3 4 .. 7 8 9 ... 47 48 49 50 >>

<< 1 2 3 4 .. 15 16 17 ... 47 48 49 50 >>

<< 1 2 3 4 ... 44 45 46 47 48 49 50 >>

<< 1 2 3 4 ... 47 48 49 50 >>

(note, the actual numbers and how many it shows before and after is not relevant)

+2  A: 

Sorry for the blob of code but here goes. Hopefully the comments are enough to tell you how it works - if leave a comment and I might add some more.

    /**
     * Get a spread of pages, for when there are too many to list in a single <select>
     * Adapted from phpMyAdmin common.lib.php PMA_pageselector function
     *
     * @param integer total number of items
     * @param integer the current page
     * @param integer the total number of pages
     * @param integer the number of pages below which all pages should be listed
     * @param integer the number of pages to show at the start
     * @param integer the number of pages to show at the end
     * @param integer how often to show pages, as a percentage
     * @param integer the number to show around the current page
     */
    protected function pages($rows, $pageNow = 1, $nbTotalPage = 1, $showAll = 200, $sliceStart = 5, $sliceEnd = 5, $percent = 20, $range = 10)
    {
     if ($nbTotalPage < $showAll)
      return range(1, $nbTotalPage);

     // Always show the first $sliceStart pages
     $pages = range(1, $sliceStart);

     // Always show last $sliceStart pages
     for ($i = $nbTotalPage - $sliceEnd; $i <= $nbTotalPage; $i++)
      $pages[] = $i;

     $i = $sliceStart;
     $x = $nbTotalPage - $sliceEnd;
     $met_boundary = false;
     while ($i <= $x)
     {
      if ($i >= ($pageNow - $range) && $i <= ($pageNow + $range))
      {
       // If our pageselector comes near the current page, we use 1
       // counter increments
       $i++;
       $met_boundary = true;
      }
      else
      {
       // We add the percentate increment to our current page to
       // hop to the next one in range
       $i = $i + floor($nbTotalPage / $percent);

       // Make sure that we do not cross our boundaries.
       if ($i > ($pageNow - $range) && !$met_boundary)
         $i = $pageNow - $range;
      }

      if ($i > 0 && $i <= $x)
       $pages[] = $i;
     }

     // Since because of ellipsing of the current page some numbers may be double,
     // we unify our array:
     sort($pages);
     return array_unique($pages);
    }
Greg
Thanks, i didn't go with your code exactly but it helped me learn where i can improve mine some.
Ólafur Waage