Постраничная навигация
Постраничная навигация позволяет не загружать все записи сразу, а показывать их частями — по 10, 15 или 50 на странице.

Чтобы добавить навигацию к записям, выполните три действия.
-
Создайте объект навигации.
-
Выполните запрос к базе данных.
-
Передайте объект навигации компоненту для вывода ссылок.
Как настроить объект навигации через API
Создать и сконфигурировать объект
Создайте объект постраничной навигации и укажите его поведение с помощью методов allowAllRecords, setPageSizes, setRecordCount.
$pagination = new \Bitrix\Main\UI\PageNavigation('nav-name');
/**
* Конфигурируем
*/
$pagination
// разрешаем показ всех записей
->allowAllRecords(true)
// указываем, какие варианты выбора страниц есть
->setPageSizes([
5,
10,
20,
50,
100,
])
// указываем общее число записей
->setRecordCount($totalCount)
;
Идентификатор навигации, например nav-name, должен быть уникальным на странице. Он используется в URL: ?nav-name=page-3.
Классы навигации
-
\Bitrix\Main\UI\PageNavigation— работает с прямой навигацией, -
\Bitrix\Main\UI\ReversePageNavigation— отвечает за обратную навигацию, -
\Bitrix\Main\UI\AdminPageNavigation— создает навигацию в административном разделе.
Инициализировать навигацию из URL
Объект прочитает из адреса текущую страницу и количество записей с помощью метода initFromUri().
$pagination->initFromUri();
Поддерживаются два формата:
-
GET-параметры —
/items/?nav-name=page-3-size-20, -
ЧПУ—
/items/nav-name/page-3/size-20/.
Выполнить запрос к базе данных
В запросе передайте данные с помощью методов:
-
getLimit()—максимальное количество записей, -
getOffset()— позицию записи, с которой начинать выборку.
$records = \Bitrix\Main\UserTable::query()
->setLimit($pagination->getLimit())
->setOffset($pagination->getOffset())
->fetchCollection();
Если нужны фильтры, добавьте их в запрос.
$records = \Bitrix\Main\UserTable::query()
->setFilter(['>ID' => 10])
->setLimit($pagination->getLimit())
->setOffset($pagination->getOffset())
->fetchCollection();
Чтобы получить общее число записей, выполните отдельный запрос до основного:
$totalCount = \Bitrix\Main\UserTable::query()
->setFilter(['>ID' => 10])
->count();
$pagination->setRecordCount($totalCount);
Метод count() выполняет SELECT COUNT(*) и возвращает число. ORM не выполняет подсчет автоматически, чтобы избежать лишних запросов к базе.
На таблицах с сотнями тысяч или миллионами записей запрос SELECT COUNT(*) выполняется долго и создает нагрузку на базу. Если общее число не нужно, используйте навигацию без COUNT.
Как отобразить навигацию
Чтобы на странице отобразить ссылки, передайте объект навигации в компонент.
Компонент main.pagenavigation
Подключите компонент main.pagenavigation и передайте объект навигации через NAV_OBJECT. Компонент выведет ссылки.
$APPLICATION->IncludeComponent('bitrix:main.pagenavigation', '.default', [
'NAV_OBJECT' => $pagination,
'SEF_MODE' => 'Y', // включить ЧПУ
'PAGE_WINDOW' => 5, // количество отображаемых номеров страниц вокруг текущей, например, … 2 3 4 5 6 …
'SHOW_ALWAYS' => 'N', // если страница одна: Y — показать навигацию, N — скрыть
'SHOW_COUNT' => 'Y' // показывать информацию о количестве записей, например, 1–10 из 123
]);
В компоненте доступно четыре системных шаблона:
-
.default— обычный вид, -
admin— для административной части, -
grid— компактный, для таблиц, -
modern— современный стиль.
Компонент main.ui.grid
Чтобы добавить навигацию в грид, передайте объект навигации в компонент main.ui.grid. Он выведет таблицу с колонками HEADERS, строками ROWS и постраничной навигацией NAV_OBJECT. Параметр NAV_PARAMS подключит ЧПУ для ссылок навигации.
$APPLICATION->IncludeComponent('bitrix:main.ui.grid', '', [
'GRID_ID' => 'my_grid',
'HEADERS' => [...],
'ROWS' => $rows,
'NAV_OBJECT' => $pagination,
'NAV_PARAMS' => ['SEF_MODE' => 'Y'],
]);
Как кастомизировать шаблон
Чтобы создать собственный шаблон навигации, используйте методы объекта \Bitrix\Main\UI\PageNavigation:
-
getRecordCount()— возвращает число записей, -
getPageCount()— возвращает число страниц, -
getCurrentPage()— возвращает номер текущей страницы, -
getPageSize()— возвращает количество записей на странице, -
allRecordsShown()— возвращаетtrue, если показаны все записи на одной странице, -
getPageSizes()— возвращает разрешенные размеры страниц[5, 10, 20, ...], -
allRecordsAllowed()— определяет, можно ли показать все записи, -
getId()— возвращает идентификатор навигации, -
getOffset()— возвращает смещение: номер первой записи текущей страницы, нумерация начинается с нуля, -
getLimit()— возвращает фактическое число записей на текущей странице.
Как сформировать URL с параметрами навигации
Ссылки на нужные страницы можно сгенерировать вручную с помощью метода addParams().
/**
* Получаем ссылку на текущую страницу с параметрами навигации
* Оба формата поддерживаются PageNavigation::initFromUri()
*/
$uri = new \Bitrix\Main\Web\Uri('https://example.ru/items/');
$pagination = new \Bitrix\Main\UI\PageNavigation('my-items');
// ЧПУ-формат
$isHumanUrl = true;
echo (string)$pagination->addParams(clone $uri, $isHumanUrl, 3);
// https://example.ru/items/my-items/page-3/
// GET-формат
$isHumanUrl = false;
echo (string)$pagination->addParams(clone $uri, $isHumanUrl, 3);
// https://example.ru/items/?my-items=page-3
Большие таблицы
Если записей много, делать COUNT неэффективно. Используйте навигацию без точного подсчета.
Как работает навигация без COUNT
-
Запрашивайте на одну запись больше, чем нужно на странице.
-
Если «лишняя» запись получена, следующая страница существует.
-
Установите в навигацию приблизительное общее число записей:
позиция выборки + количество полученных записей.$pagination = new \Bitrix\Main\UI\PageNavigation('users'); $pagination ->allowAllRecords(false) ->setPageSize(20) ->initFromUri() ; $users = []; $queryResult = \Bitrix\Main\UserTable::query() ->setOffset($pagination->getOffset()) ->setLimit( $pagination->getLimit() + 1 ) ->exec() ; foreach ($queryResult as $i => $user) { if ($i === $pagination->getLimit()) { break; } $users[] = $user; } $pagination->setRecordCount( $pagination->getOffset() + $queryResult->getSelectedRowsCount() ); -
Подключите компонент, но скройте общее число.
$APPLICATION->IncludeComponent('bitrix:main.pagenavigation', '', [ 'NAV_OBJECT' => $pagination, 'SHOW_COUNT' => 'N', // не показывать общее количество 'SEF_MODE' => 'Y', ]);
Для навигации без COUNT не включайте allowAllRecords(true). Это позволит указать в URL полную выборку. В результате после вызова initFromUri() максимальное значение и начальная позиция не установятся.