skip to Main Content

How do I echo the three dots “…” after a specific number (e.g., 9) and echo the last two numbers after the three dots “…” (e.g., 57 and 58) for pagination using MySQLi and PHP?

Here’s the code:

<?php

        $output = "";
        $tpages = ceil($engine->numrows("SELECT null FROM `cms_articles_comments` WHERE `article_id` = '" . $id . "'") / 10);

        if ($page == 1)
        {
            $output .= '<button type="button" class="btn btn-info pull-left goToTop" disabled><i class="fa fa-arrow-left"></i> Previous</button>';
        }
        else
        {
            $output .= '<a href="/articles/' . $seo . '&p=' . ($page - 1) . '#comments" ng-click="progress()" class="btn btn-info pull-left goToTop"><i class="fa fa-arrow-left"></i> Previous</a>';
        }

        if ($page >= $tpages)
        {
            $output .= '<button type="button" class="btn btn-info pull-right goToTop" disabled>Next <i class="fa fa-arrow-right"></i></button>';
        }
        else
        {
            $output .= '<a href="/articles/' . $seo . '&p=' . ($page + 1) . '#comments" ng-click="progress()" class="btn btn-info pull-right goToTop">Next <i class="fa fa-arrow-right"></i></a>';
        }

        $output .= '<div class="fpagination fpagination-centered"><ul>';
        for($i = 1; $i <= $tpages; $i++)
        {
            if ($i == $page)
            {
                $output .= '<li class="active"><a href="/articles/' . $seo . '&p=' . $i . '#comments" ng-click="progress()" class="goToTop">' . $i . '</a></li>';
            }
            else
            {
                $output .= '<li><a href="/articles/' . $seo . '&p=' . $i . '#comments" ng-click="progress()" class="goToTop">' . $i . '</a></li>';
            }
        }

        $output .= '</ul></div>';           
        echo $output;

    ?>

With the code provided above, I get this:

here

I want the pagination list to show like this:

here

prntscr.com/a0azua,
prntscr.com/a0ay1s

Thanks in advance.

2

Answers


  1. $bOutputOnce = FALSE;
    for($i = 1; $i <= $tpages; $i++) {
      if ($i == $page) {
        $output .= '<li class="active"><a href="/articles/' . $seo . '&p=' . $i . '#comments" ng-click="progress()" class="goToTop">' . $i . '</a></li>';
      } elseif (($i <= 9) or ($i >= ($tpages - 2))) {
        $output .= '<li><a href="/articles/' . $seo . '&p=' . $i . '#comments" ng-click="progress()" class="goToTop">' . $i . '</a></li>';
      } elseif ($bOutputOnce == FALSE) {
        $output .= '<li>&hellip;</li>';
        $bOutputOnce = TRUE;
      }
    }
    

    But again, it’s best to use a framework. Also, if you have less than 9 pages, this creates a problem and you’ll need to add more if/else code for that. In fact, it’s going to look very strange if you have 11 pages because it will be 9 … 10 11, which makes no sense.

    Login or Signup to reply.
  2. The display system you are looking for is more complex than it seems, because if you have 58 pages and your current page is 53, you’ll want to show that three-dot button before page 53 and not after, like this:

    1 2 ... 50 51 52 [53] 54 55 56 57 58
    

    And when your current page is 20, you’ll want them to appear on both sides:

    1 2 ... 18 19 [20] 21 22 23 ... 57 58
    

    In general, you want a system whereby a maximum number of labels/buttons is output (it seems to be 12 in your example), also counting the three-dot labels.

    It would be user-friendly to show at least the two pages preceding the current page, and the two following it.

    You could write a function to generate a list of page numbers that follow these rules, and use the number 0 to denote the three-dot button:

    // Returns an array of $max_length (or less) page numbers
    // where a 0 in the returned array denotes a gap in the series.
    // Parameters:
    //   $tpages:     total number of pages
    //   $page:       current page
    //   $max_length: maximum size of returned array
    function getPageList($tpages, $page, $max_length) {
        if ($tpages <= $max_length) {
            // no breaks in list
            return range(1, $tpages);
        }
        if ($page <= $max_length - 5) {
            // no break on left of page
            return array_merge(range(1, $max_length-3), array(0, $tpages-1, $tpages));
        }
        if ($page >= $tpages - $max_length + 6) {
            // no break on right of page
            return array_merge(array(1, 2, 0), range($tpages - $max_length + 4, $tpages));
        }
        // breaks on both sides
        $size = $max_length - 6;
        $first = $page - floor(($size-1)/2);
        return array_merge(array(1, 2, 0), range($first, $first + $size - 1), 
                           array(0, $tpages-1, $tpages));
    }
    

    If you call this function like this:

    getPageList(58, 53, 12)
    

    It will return this:

    [1, 2, 0, 50, 51, 52, 53, 54, 55, 56, 57, 58]
    

    Or like this, changing the current page number:

    getPageList(58, 20, 12)
    

    It will return this:

    [1, 2, 0, 18, 19, 20, 21, 22, 23, 0, 57, 58]
    

    Notice the zeroes, which are the place holders for the three-dot buttons.

    Now the difficult part has been done. You can call that function from your existing code without having to change much. Instead of your for loop, you’ll use a foreach on the output of the above function. In the loop you’ll have an extra test on the zero, so you can output the three-dot label:

    $output = "";
    // first part of your code for getting $tpages and 
    // generating prev/next buttons comes here: it does not change
    // ...
    // 
    $output .= '<div class="fpagination fpagination-centered"><ul>';
    foreach (getPageList($tpages, $page, 12) as $i)
    {
        if ($i == $page)
        {
            $output .= '<li class="active"><a href="/articles/' . $seo . '&p=' . $i . 
                         '#comments" ng-click="progress()" class="goToTop">' . 
                         $i . '</a></li>';
        }
        else if ($i == 0)
        {
            $output .= '<li>&hellip;</li>';
        }
        else
        {
            $output .= '<li><a href="/articles/' . $seo . '&p=' . $i . '#comments" 
                        ng-click="progress()" class="goToTop">' . $i . '</a></li>';
        }
    }
    $output .= '</ul></div>';           
    echo $output;
    

    Notice that the last argument to the getPageList function is 12. You can configure this number to your needs. It depends on how wide you want your output to become.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search