JPagination - постраничная навигация в компоненте
Класс JPagination в Joomla позволяет разработчикам надежно добавлять пагинацию в свои компоненты. Как в Front-End, так и в Back-End. Файл, описывающий этот класс находится по адресу
/libraries/joomla/html/pagination.php
// подключение класса jimport('joomla.html.pagination');
Конструктор
__construct($total,$limitstart,$limit)
В конструкторе класса используется три переменные:
- $total — Общее количество элементов в списке,
- $limitstart — переменная, которая задает начало отсчета для пагинации,
- $limit — количество элементов, которое будет выводиться на каждой странице.
Методы класса
getPagesCounter()— Возвращает строку, которая отображает текущую страницу и общее количество страниц.
Пример
getResultsCounter()— Возвращает строку, которая отображает текущие результаты.
Пример
getPagesLinks()— Возвращает строку, которая отображает ссылки результата разбиения на страницы
getListFooter()— Возвращает комбинацию из нескольких элементов. В том числе — выпадающий список Limit, а так же тоже, что возвращают функции getPagesLinks() и getResultsCounter(). Внешний вид для Front-End и Back-End будет отличаться, т. к. подключаются соответствующие CSS стили для админки.
- Front-end:
- Back-end:
getLimitBox()— Возвращает код HTML, который будет выводить выпадающий список Limit
Простой пример c базой данных
Большинство разработчиков не используют SQL_CALC_FOUND_ROWS, который вернет количество всех подходящих под запрос записей, когда количество записей ограничивается LIMIT’ом. Обычая ошибка в таком случаем — это выполнить два почти одинаковых запроса. А в результате замедление работы
$db = JFactory::getDBO(); $limit = $mainframe->getUserStateFromRequest("$option.limit", 'limit', 14, 'int'); // Я предполагаю, что getUserStateFromRequest предназначен для сеанса или по другим причинам $limit_start = JRequest::getVar('limitstart', 0, '', 'int'); $db->setQuery('SELECT SQL_CALC_FOUND_ROWS * FROM jos_content', $limit_start, $limit); $items = &$db->loadAssocList(); if (empty($items)) { $jAp->enqueueMessage($db->getErrorMsg(), 'error'); return; } else { //Здесь начинается красота $db->setQuery('SELECT FOUND_ROWS();'); //не перезагружем запрос! а просто вернем данные их предыдущего запроса jimport('joomla.html.pagination'); $pageNav = new JPagination( $db->loadResult(), $limit_start, $limit ); foreach($items as $item) { //вывод элементов } echo $pageNav->getListFooter(); // отображаем навигацию }
Реализация в MVC-компоненте
Изменения в модели
Объявляем переменные $_total и $_pagination в модели; Они будут возвращены функциями getTotal() и getPagination(), соответственно.
/** * Items total * @var integer */ var $_total = null; /** * Pagination object * @var object */ var $_pagination = null;
Добавляем в конструктор (или создаем его) две переменные — $limitstart и $limit. Они будут нужны для класса JPagination.
function __construct() { parent::__construct(); global $mainframe, $option; // Получаем переменные для постраничной навигации $limit = $mainframe->getUserStateFromRequest('global.list.limit', 'limit', $mainframe->getCfg('list_limit'), 'int'); $limitstart = JRequest::getVar('limitstart', 0, '', 'int'); // In case limit has been changed, adjust it $limitstart = ($limit != 0 ? (floor($limitstart / $limit) * $limit) : 0); $this->setState('limit', $limit); $this->setState('limitstart', $limitstart); }
Пересмотрим функцию getData() в компоненте. Добавим значения переменных $limitstart и $limit в метод _getList(). Это позволит выбирать нужные строки, а не все строки.
function getData() { // if data hasn't already been obtained, load it if (empty($this->_data)) { $query = $this->_buildQuery(); $this->_data = $this->_getList($query, $this->getState('limitstart'), $this->getState('limit')); } return $this->_data; }
Создадим новую функцию getTotal(). В этой функции будем использовать метод _getListCount() класса JModel. Эта функция будет возвращать общее количество строк в запросе. Значение, которое она будет возвращать будет использоваться в следующей функции getPagination().
function getTotal() { // Load the content if it doesn't already exist if (empty($this->_total)) { $query = $this->_buildQuery(); $this->_total = $this->_getListCount($query); } return $this->_total; }
Создадим функцию getPagination(). Эта функция будет создавать и возвращать новый объект Pagination, который будет передаваться в Вид.
function getPagination() { // Load the content if it doesn't already exist if (empty($this->_pagination)) { jimport('joomla.html.pagination'); $this->_pagination = new JPagination($this->getTotal(), $this->getState('limitstart'), $this->getState('limit') ); } return $this->_pagination; }
Изменения в Виде
Допишите в представлении (view) функционал, который будет получать объект класса JPagination из модели и назначать переменную для работы с ним из шаблона
... // Получаем данные из модели $items =& $this->get('Data'); $pagination =& $this->get('Pagination'); // Назначаем переменные для работы с данными из шаблона $this->assignRef('items', $items); $this->assignRef('pagination', $pagination); ...
Изменения в Шаблоне
Добавьте область footer-а, где будет находиться навигация по страницам, к таблице, отображающей ваш список данных. Метод getListFooter() класса JPagination генерирует кнопки и их функционал «следующая/предыдущая» как на картинках:
- Front-End
- Back-End
Измените свойство colspan=«9» тега <td> для соответствия количеству колонок в вашей таблице.
... <tfoot> <tr> <td colspan="9"><?php echo $this->pagination->getListFooter(); ?></td> </tr> </tfoot> .