[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Пагинатор
AlmazDelDiablo
Добрый день, друзья ) Вчера задался целью написать пагинатор. Без подглядывания в чужой код и заимствования логики. Вот такой вот получился:
class paginator {

var $num_pages = 0;
var $nav = 'Страницы: ';
var $query = array();
var $num_rows = 0;

function generate_page( $table ) {
global $db, $cfg, $page;
$cfg['rows_to_page'] = (int)$cfg['rows_to_page'];
$this->num_rows = $db->get_result( $db->query( "SELECT COUNT(*) as `cnt` FROM `". DB_PREF ."_". $table ."`" ) ,0 );
$this->num_pages = $this->num_rows / $cfg['rows_to_page'];

if( $page > $this->num_pages ) {
$page = 1;
}

if( $this->num_rows < $cfg['rows_to_page'] ) {
$this->nav .= '1';
$this->query_min[1] = 0;
} else {
for( $i = 1; $i < $this->num_pages; $i++ ) {
$this->query[$i] = $i * $cfg['rows_to_page'] - $cfg['rows_to_page'];
if( $page == $i ) {
$this->nav .= $i.' ';
} else {
$this->nav .= '<a href="/index.php?cat='.$i.'">'.$i.'</a> ';
}
}
}
}
}

В общем он работает, чему я очень рад. Но, во-первых, хотелось бы услышать критику на его счет (может уязвимые места или где-то что-то упростить). И еще. Не могу придумать, как бы сделать так, чтобы траницы выводились не просто подряд «Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20», а группированись вот так: «Страницы: 1 ... 6 7 8 ... 40»

ПС: посмотреть, как он работает можно тут: http://nbans.npanel.ru/index.php



Спустя 35 минут, 53 секунды (19.01.2011 - 14:20) vital написал(а):
Может все-таки стоит позаимствовать логику?) Есть ведь уже готовые *выводилки* циферек. Погугли и посмотри как сделано.

Спустя 38 минут, 56 секунд (19.01.2011 - 14:59) Hoodzon написал(а):
А если у тебя нет БД, но есть массив с данными? что тогда? Будешь новый писать?

Спустя 1 час, 43 минуты, 26 секунд (19.01.2011 - 16:42) AlmazDelDiablo написал(а):
Цитата (Hoodzon @ 19.01.2011 - 15:59)
А если у тебя нет БД, но есть массив с данными? что тогда? Будешь новый писать?

Угу, так как в данном движке пагинатор нужен всего в двух местах и в обоих идет выборка из базы. Но я учту, ибо изначально не задумался на этот счет )

Спустя 3 часа, 1 минута, 16 секунд (19.01.2011 - 19:44) twin написал(а):
Прикольно))) Класс из одного метода. Ты монстр.

Спустя 7 часов, 36 минут, 14 секунд (20.01.2011 - 03:20) Invis1ble написал(а):
AlmazDelDiablo
Цитата
Класс из одного метода. Ты монстр

точно =) Надо было там еще interface приплести )

Могу выложить свой класс (стырен у glock18 и апгрейжен). Посмотри, что и как... В нем реализованы сниппеты, можешь переделать под себя.
class Pagination
{
public $itemCount = 0;
public $currentPage = 0;
private $pageSize = 10;
private $pageCount = 0;
private $leftsidePagesNum = 2;
private $rightsidePagesNum = 2;
public $display = array
(
'next' => true,
'prev' => true,
'last' => true,
'first' => true,
'elem' => true
);

public function __construct($itemCount=0, $currentOffset=0, $pageSize=10)
{
$this->itemCount = $itemCount;
$this->pageSize = $pageSize;
$this->currentPage = floor($currentOffset / $this->pageSize);
}

public function CalculatePageCount()
{
$this->pageCount = ceil($this->itemCount / $this->pageSize);
}

public function Render()
{
if ($this->pageCount == 0) $this->CalculatePageCount();
if ($this->pageCount <= 1) return '';

$leftmost = ($this->currentPage - $this->leftsidePagesNum > 0) ? $this->currentPage - $this->leftsidePagesNum : 0;
$rightmost = ($this->currentPage + $this->rightsidePagesNum < $this->pageCount) ? $this->currentPage + $this->rightsidePagesNum : $this->pageCount - 1;

$out = '<table class="paginator" cellspacing=0><tr><td>страницы: </td>';

if ($this->currentPage > 0 && $this->display['prev'])
$out .= '<td class="page">' . $this->PageLinkHtml('<img class="prev-next" src="' . ICONS_DIR . 'prev.gif" alt="предыдущая" title="предыдущая" />', $this->currentPage - 1) . '</td>';

if ($this->currentPage > $this->leftsidePagesNum && $this->display['first'])
{
$out .= '<td class="page">' . $this->PageLinkHtml('1', 0) . '</td>';
$out .= '<td>' . ' ... ' . '</td>';
}

for ($i = $leftmost; $i <= $rightmost; $i++)
{
if ($i == $this->currentPage)
$out .= '<td class="curr-page">' . ($i + 1) . '</td>';
else
$out .= '<td class="page">' . $this->PageLinkHtml($i + 1, $i) . '</td>';
}

if ($this->currentPage < ($this->pageCount - 1 - $this->rightsidePagesNum) && $this->display['last'])
{
$out .= '<td>' . ' ... ' . '</td>';
$out .= '<td class="page">' . $this->PageLinkHtml($this->pageCount, $this->pageCount - 1) . '</td>';
}

if ($this->currentPage < ($this->pageCount - 1) && $this->display['next'])
$out .= '<td class="page">' . $this->PageLinkHtml('<img class="prev-next" src="' . ICONS_DIR . 'next.gif" alt="следующая" title="следующая" />', $this->currentPage + 1) . '</td>';

$out .= '</tr></table>';

if ($this->display['elem'])
{
$currPageFirstElem = $this->currentPage * $this->pageSize + 1;
$currPageLastElem = $this->currentPage + 1 == $this->pageCount ? $this->itemCount : ($this->currentPage + 1) * $this->pageSize;

$out .= '<table id="element-count"><tr>';

$out .= '<td>элементов: всего - ' . $this->itemCount . ', показано - ';
$out .= $currPageFirstElem != $currPageLastElem ? 'с ' . $currPageFirstElem . ' по ' . $currPageLastElem : $currPageFirstElem;

$out .= '</td></tr></table>';
}

return $out;
}

private function PageLinkHtml($text, $page)
{
$offset = $page * $this->pageSize;

return '<a class="paginator-item" offset=' . $offset . ' href="#">' . $text . '</a>'; // ссылка сделана для AJAX, переделай под себя
}
}


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


_____________
Блог | VK | GitHub | Twitch
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.