@i_want_to_know_everything

Рассчет отступов в пагинации?

Пишу пагинацию, не могу сообразить как правильно прописать условие для расстановки разрывов (троеточий).
1 2 3 4 5 ... 20 >
< 1 ... 7 8 9 10 11 ... 20 >
< 1 ... 16 17 18 19 20

Получаются огромные конструкции со множеством if, поделитесь пожалуйста решением
  • Вопрос задан
  • 506 просмотров
Решения вопроса 1
@djay
Тема затёртая до дыр, обсуждалась миллионы раз, есть множество реализаций.
Этот подход называется Digg Style Pagination.

Погугли и поищи, мне как-то неохото расписывать все от начала и до конца.
Вот пример, с которого можно начать.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Stalker_RED
@Stalker_RED
На самом деле достаточно четырех if-ов и одного цикла. Правда условия у этих if-ов довольно развесистые.

Сперва вычисляем какие номера страниц видны в начале, в конце и в середине
$start = 1 + $indent;
$end = $total - $indent;
$mid_start = $current - $indent;
$mid_end = $current + $indent;


Первый и последний if-else выводят активную или неактивную стрелочку ← →
(вместо неактивной, можно и вообще не выводить)

Цикл пробегает по всем страницам, проверяет не текущая ли это страница, или страница попадает в видимый диапазон, и нужно вывести кликабельную ссылку или троеточие.

лапша c кусками бутстрапа
public static function renderPaginator($total, $current, $indent = 3)
    { 
        $start = 1 + $indent;
        $end = $total - $indent;
        $mid_start = $current - $indent;
        $mid_end = $current + $indent;
        
        ?>
    
    <nav style="margin: 0 auto;">
        <ul class="pagination">
            <?
            
            $skip1 = ($start > $current || $current > $end);
            
            if ($current == 1) { // previous
                ?><li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li><?
            } else {
                ?><li><a href="?page=<?=($current-1)?>" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li><?
            }
            for ($p = 1; $p <= $total; $p++) { // each page
                if ($p == $current) {
                    ?>
                    <li class="active"><a href="#"><?=$p?> <span class="sr-only">(текущая)</a></li><?
                } else {
                    
                    if($p < $start
                    || ($p > $mid_start && $mid_end > $p)
                    || ($p > $end)
                    || ($p == $start && $p == $mid_start)
                    || ($p == $end && $p == $mid_end)
                    ) {
                    ?>
                    <li><a href="?page=<?=$p?>"><?=$p?></a></li><?
                    } elseif($p == $start || $p == $end) {
                    ?>
                    <li class="disabled"><a href="#">...</a></li><?
                    }
                }
            }
            if ($current == $total) { // next
                ?><li class="disabled"><a href="#" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li><?
            } else {
                ?><li><a href="?page=<?=($current-1)?>" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li><?
            }
            ?>
  
        </ul>
    </nav>    
    <?
    }

Ответ написан
Комментировать
@look2009
Контроллер
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = 1;
}

$dataitems = array(
'start' => ($page - 1) * 20,
'limit' => 20
);
Модель
$sql = "SELECT * FROM table order by `id`";

if (isset($dataitems['start']) || isset($dataitems['limit'])) {
if ($dataitems['start'] < 0) {
$dataitems['start'] = 0;
}

if ($dataitems['limit'] < 1) {
$dataitems['limit'] = 20;
}

$sql .= " LIMIT " . (int)$dataitems['start'] . "," . (int)$dataitems['limit'];
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы