Компонент main.ui.filter (классы Bitrix\Main\UI\Filter) выводит фильтр + поиск. Является системным компонентом.
В физической структуре его можно найти в папке /bitrix/components/bitrix/main.ui.filter
Архитектурный обзор
Системные компоненты Bitrix Framework main.ui.grid (табличное представление данных) и main.ui.filter (унифицированный интерфейс фильтрации) обеспечивают декларативный подход к реализации CRUD-интерфейсов. В связке они позволяют:
- Формировать динамические таблицы с сортировкой и пагинацией
- Реализовывать сложные фильтры с поддержкой типов данных
- Обрабатывать AJAX-запросы для обновления данных
- Интегрироваться с различными источниками данных (Highload-блоки, Инфоблоки, ORM)
Реализация компонента для Highload-блоков
1. Инициализация сущности Highload-блока
use Bitrix\Highloadblock\HighloadBlockTable;
use Bitrix\Main\Entity;
$hlblock = HighloadBlockTable::getById($arParams['BLOCK_ID'])->fetch();
$entity = HighloadBlockTable::compileEntity($hlblock);
$entityClass = $entity->getDataClass();
2. Обработка параметров фильтрации
use Bitrix\Main\UI\Filter\Options;
$filterOption = new Options($arParams['GRID_ID']);
$filterData = $filterOption->getFilter();
// Конвертация фильтра в формат D7
$runtimeFilter = [];
foreach ($filterData as $field => $value) {
if ($field === 'FIND') {
$runtimeFilter['%UF_NAME'] = $value;
} elseif (isset($fields[$field])) {
$runtimeFilter[$field] = $value;
}
}
3. Конфигурация грида
$gridConfig = [
'GRID_ID' => $arParams['GRID_ID'],
'COLUMNS' => array_map(function($field) {
return [
'id' => $field['FIELD_NAME'],
'name' => $field['EDIT_FORM_LABEL'],
'sort' => $field['FIELD_NAME'],
'type' => $this->getFieldType($field)
];
}, $userFields),
'NAV_OBJECT' => $nav,
'AJAX_MODE' => 'Y',
'AJAX_OPTION_HISTORY' => 'N'
];
Ключевые аспекты реализации
Обработка данных:
- Использование
Bitrix\Main\UI\PageNavigationдля пагинации - Интеграция с
CDBResultдля совместимости с legacy-кодом -
Оптимизация запросов через
Entity\Query:$query = new Entity\Query($entity); $query->setSelect(['*']) ->setFilter($runtimeFilter) ->setLimit($nav->getLimit()) ->setOffset($nav->getOffset());
Фильтрация:
- Поддержка типов данных через
Bitrix\Main\UI\Filter\Type -
Кастомные обработчики для полей:
\Bitrix\Main\UI\Filter\NumberType::getLogicFilter() \Bitrix\Main\UI\Filter\DateType::getLogicFilter()
Экспорт данных:
-
Интеграция с библиотекой SheetJS (xlsx):
const workbook = XLSX.utils.book_new(); const worksheet = XLSX.utils.aoa_to_sheet(data); XLSX.utils.book_append_sheet(workbook, worksheet, "Data"); XLSX.writeFile(workbook, filename);
Пример интеграции с системным фильтром
$APPLICATION->IncludeComponent(
'bitrix:main.ui.filter',
'',
[
'FILTER_ID' => $gridId,
'GRID_ID' => $gridId,
'FILTER' => [
[
'id' => 'ID',
'name' => 'ID',
'type' => 'number',
'default' => true
],
[
'id' => 'UF_DATE',
'name' => 'Дата',
'type' => 'date',
'exclude' => [
DateType::NEXT_DAYS,
DateType::LAST_DAYS
]
]
],
'ENABLE_LIVE_SEARCH' => true
]
);
Оптимизация производительности
- Кеширование метаданных Highload-блоков
- Пакетная обработка данных через
Bitrix\Main\ORM\Query\Result::fetchCollection() - Использование индексированных полей для фильтрации
- Ленивая загрузка данных через
SHOW_MORE_BUTTON
Безопасность
-
Валидация параметров:
if (!preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $arParams['FILTER_NAME'])) { throw new SystemException('Invalid filter name'); } -
Экранирование выходных данных:
$row[$field] = htmlspecialcharsbx($value, ENT_COMPAT, LANG_CHARSET); -
Проверка прав доступа:
if ($arParams['CHECK_PERMISSIONS'] === 'Y' && !$USER->CanDoOperation('edit_other_settings')) { ShowError('Access denied'); return; }
Компонент
Пример вызова компонента
<?$APPLICATION->IncludeComponent(
"yournamespace:leads.list",
"",
Array(
"BLOCK_ID" => "1",
"CHECK_PERMISSIONS" => "N",
"DETAIL_URL" => "",
"FILTER_NAME" => "arrFilterHL",
"PAGEN_ID" => "page",
"ROWS_PER_PAGE" => "12",
"SORT_FIELD" => "ID",
"SORT_ORDER" => "DESC",
"GRID_ID" => "leads_list", // Опционально. Можно захардкодить внутри, если нужно.
)
);?>
Файл component.php
<?php if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true)die();
/**
* @global object $APPLICATION
* @var array $arResult
* @var array $arParams
*/
$requiredModules = array('highloadblock');
foreach ($requiredModules as $requiredModule)
{
if (!CModule::IncludeModule($requiredModule))
{
ShowError(GetMessage("F_NO_MODULE"));
return 0;
}
}
if (!$arParams['GRID_ID']) {
ShowError($this->__name . ': GRID_ID не определен');
return false;
}
$list_id = $arParams['GRID_ID'];
use Bitrix\Highloadblock as HL;
use Bitrix\Main\Entity;
use Bitrix\Main\Grid\Options as GridOptions;
use Bitrix\Main\Application;
$request = Application::getInstance()->getContext()->getRequest();
// hlblock info
$hlblock_id = $arParams['BLOCK_ID'];
if (empty($hlblock_id))
{
ShowError(GetMessage('HLBLOCK_LIST_NO_ID'));
return 0;
}
$hlblock = HL\HighloadBlockTable::getById($hlblock_id)->fetch();
if (empty($hlblock))
{
ShowError(GetMessage('HLBLOCK_LIST_404'));
return 0;
}
// check rights
if (isset($arParams['CHECK_PERMISSIONS']) && $arParams['CHECK_PERMISSIONS'] == 'Y' && !$USER->isAdmin())
{
$operations = HL\HighloadBlockRightsTable::getOperationsName($hlblock_id);
if (empty($operations))
{
ShowError(GetMessage('HLBLOCK_LIST_404'));
return 0;
}
}
$entity = HL\HighloadBlockTable::compileEntity($hlblock);
// page size
$gridOptions = new GridOptions($list_id);
$gridPageSize = $gridOptions->getCurrentOptions()['page_size'];
// Устанавливаем количество из объекта грида.
if (!empty($gridPageSize)) {
$pageSize = (int)$gridPageSize;
} else {
$pageSize = (int)($arParams['ROWS_PER_PAGE'] ?? 10);
}
// fields info
$fields = $GLOBALS['USER_FIELD_MANAGER']->GetUserFields('HLBLOCK_'.$hlblock['ID'], 0, LANGUAGE_ID);
// ui.filter
$stringFields = [];
foreach ($fields as $fieldName => $field)
{
if ($field['USER_TYPE_ID'] === 'string') {
$stringFields[] = $fieldName;
}
}
$filterD = [];
if ($request->isAjaxRequest()
&& $request->getQuery("grid_id") !== null
&& $request->getQuery("grid_id") === $list_id)
{
$filterOption = new Bitrix\Main\UI\Filter\Options($list_id);
$filterData = $filterOption->getFilter([]);
/*foreach ($filterData as $k => $v) {
// Тут разбор массива $filterData из формата, в котором его формирует main.ui.filter в формат,
// который подойдет для вашей выборки.
// Обратите внимание на поле "FIND", скорее всего его вы и захотите засунуть в фильтр по NAME и еще паре полей.
//$filter['UF_LEAD_NAME'] = "%".$filterData['FIND']."%";
}*/
// Число.
$numberFilter = \Bitrix\Main\UI\Filter\NumberType::getLogicFilter($filterData, ['ID']);
if (!empty($numberFilter)) {
$filterD[] = $numberFilter;
}
// Дата.
$dateFilter = \Bitrix\Main\UI\Filter\DateType::getLogicFilter($filterData, []);
if (!empty($dateFilter)) {
$filterD[] = $dateFilter;
}
// Обрабатываем поисковую строку. Ищем по всем полям с типом 'string'.
if (!empty($filterData['FIND']) && !empty($stringFields)) {
$searchValue = '%' . $filterData['FIND'] . '%';
$conditions = [];
foreach ($stringFields as $field) {
$conditions[] = [
'=%' . $field => $searchValue
];
}
// Собираем все условия в OR-группу.
$filterD = [
[
'LOGIC' => 'OR',
...$conditions // Распаковываем массив условий.
]
];
}
}
// sort
$sortId = 'ID';
$sortType = 'DESC';
if (isset($arParams['SORT_FIELD']) && isset($fields[$arParams['SORT_FIELD']]))
{
$sortId = $arParams['SORT_FIELD'];
}
// for compatibility
elseif (isset($_GET['sort_id']) && isset($fields[$_GET['sort_id']]))
{
$sortId = $_GET['sort_id'];
}
if (isset($arParams['SORT_ORDER']) && in_array($arParams['SORT_ORDER'], array('ASC', 'DESC'), true))
{
$sortType = $arParams['SORT_ORDER'];
}
// for compatibility
if (isset($_GET['sort_type']) && in_array($_GET['sort_type'], array('ASC', 'DESC'), true))
{
$sortType = $_GET['sort_type'];
}
// for main.ui.grid
if (isset($_GET['grid_action'])) {
if (isset($_GET['by'])) {
$sortId = $_GET['by'];
}
if (isset($_GET['order']) && in_array($_GET['order'], array('ASC', 'DESC', 'asc', 'desc'), true)) {
$sortType = $_GET['order'];
}
}
// pagen
if ($pageSize>0)
{
$pagenId = isset($arParams['PAGEN_ID']) && trim($arParams['PAGEN_ID']) != '' ? trim($arParams['PAGEN_ID']) : 'page';
//$perPage = intval($arParams['ROWS_PER_PAGE']);
$perPage = $pageSize;
$nav = new \Bitrix\Main\UI\PageNavigation($pagenId);
$nav->allowAllRecords(true)
->setPageSize($perPage)
->initFromUri();
}
else
{
$arParams['ROWS_PER_PAGE'] = 0;
}
// start a query
$mainQuery = new Entity\Query($entity);
$mainQuery->setSelect(array('*'));
$mainQuery->setOrder(array($sortId => $sortType));
// filter
if (
isset($arParams['FILTER_NAME']) &&
!empty($arParams['FILTER_NAME']) &&
preg_match('/^[A-Za-z_][A-Za-z01-9_]*$/', $arParams['FILTER_NAME']))
{
global ${$arParams['FILTER_NAME']};
$filter = ${$arParams['FILTER_NAME']};
if (is_array($filter))
{
$mainQuery->setFilter($filter);
}
}
if (!empty($filterD)) {
$mainQuery->setFilter($filterD);
}
// pagen
if ($perPage > 0)
{
$mainQueryCnt = $mainQuery;
$result = $mainQueryCnt->exec();
$result = new CDBResult($result);
$nav->setRecordCount($result->selectedRowsCount());
$arResult['nav_object'] = $nav;
unset($mainQueryCnt, $result);
$mainQuery->setLimit($nav->getLimit());
$mainQuery->setOffset($nav->getOffset());
}
// execute query
// ->setGroup($group)
// ->setOptions($options);
$result = $mainQuery->exec();
$result = new CDBResult($result);
// build results
$rows = array();
$tableColumns = array();
while ($row = $result->fetch())
{
foreach ($row as $k => $v)
{
$arUserField = $fields[$k];
if ($k == 'ID')
{
$tableColumns['ID'] = true;
continue;
}
if ($arUserField['SHOW_IN_LIST'] != 'Y')
{
continue;
}
$html = call_user_func_array(
array($arUserField['USER_TYPE']['CLASS_NAME'], 'getadminlistviewhtml'),
array(
$arUserField,
array(
'NAME' => 'FIELDS['.$row['ID'].']['.$arUserField['FIELD_NAME'].']',
'VALUE' => htmlspecialcharsbx(is_array($v) ? implode(', ', $v) : $v)
)
)
);
$tableColumns[$k] = true;
$row[$k] = $html;
}
$rows[] = $row;
}
$arResult['rows'] = $rows;
$arResult['fields'] = $fields;
$arResult['tableColumns'] = $tableColumns;
$arResult['sort_id'] = $sortId;
$arResult['sort_type'] = $sortType;
// for compatibility
$arResult['NAV_STRING'] = '';
$arResult['NAV_PARAMS'] = '';
$arResult['NAV_NUM'] = 0;
$this->IncludeComponentTemplate();
Данные получены, теперь начнем с ними работать.
Также выведем кнопку "скачать excel файл" с нашей таблицей из грида.
В Битрикс такую верстку и функционал (кнопка с иконкой "шестерёнка", выпадающее меню с пунктом "Excel" и вызовом BX.adminList.ShowMenu) формирует админский компонент для списков — это компонент bitrix:main.interface.grid (или старый административный список, основанный на CAdminList).
Поэтому заморачиваться не будем и воспользуемся навыками "гугления", забираем первую попавшуюся либу из поисковыой выдачи. У меня это xlsx.full.min.js
Файл template.php
<?php
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
die();
}
/** @global CMain $APPLICATION */
/** @var array $arParams */
/** @var array $arResult */
if (!empty($arResult['ERROR'])) {
echo $arResult['ERROR'];
return false;
}
/**
* Документация по main.ui.grid.
*
* D7
* https://dev.1c-bitrix.ru/api_d7/bitrix/main/systemcomponents/gridandfilter/mainuigrid/index.php
*
* Из Битрикс24 (здесь описано больше параметров).
* https://bx24devbook.website.yandexcloud.net/Razrabotka/UI/Tablicy/Obzor.html
*
* Фильтр
* https://dev.1c-bitrix.ru/api_d7/bitrix/main/systemcomponents/gridandfilter/mainuifilter.php
*/
$list_id = $arParams['GRID_ID'];
$columns = [];
$list = [];
$columns[] = [
'id' => 'ID',
'name' => 'ID',
'sort' => 'ID',
'default' => true,
'width' => 100,
'first_order' => 'desc',
];
foreach ($arResult['fields'] as $field) {
$columns[] = [
'id' => $field['FIELD_NAME'],
'name' => $field['EDIT_FORM_LABEL'],
'sort' => $field['FIELD_NAME'],
// Определяет должна ли отображаться колонка по умолчанию в гриде. По умолчанию колонки не отображаются.
'default' => true,
'first_order' => 'desc',
];
}
foreach ($arResult['rows'] as $row) {
$list[] = [
'data' => $row,
];
}
$pageSizes = [
['NAME' => '10', 'VALUE' => '10'],
['NAME' => '20', 'VALUE' => '20'],
['NAME' => '50', 'VALUE' => '50'],
['NAME' => '100', 'VALUE' => '100'],
['NAME' => '200', 'VALUE' => '200'],
['NAME' => '500', 'VALUE' => '500'],
['NAME' => '1000', 'VALUE' => '1000'],
];
$filterOption = new Bitrix\Main\UI\Filter\Options($list_id);
$filterData = $filterOption->getFilter([]);
$filter = [];
foreach ($filterData as $k => $v) {
// Тут разбор массива $filterData из формата, в котором его формирует main.ui.filter в формат, который подойдет для вашей выборки.
// Обратите внимание на поле "FIND", скорее всего его вы и захотите засунуть в фильтр по NAME и еще паре полей
$filter['UF_LEAD_NAME'] = "%".$filterData['FIND']."%";
$filter['ID'] = $filterData['ID_numsel'];
}
$ui_filter = [
['id' => 'ID', 'name' => 'ID', 'type' => 'number', 'default' => true],
['id' => 'UF_LEAD_NAME', 'name' => 'Имя лида', 'type' => 'text', 'default' => true],
[
'id' => 'UF_CREATED_BY',
'name' => 'Дата создания',
'type' => 'date',
'default' => true,
"exclude" => array(
\Bitrix\Main\UI\Filter\DateType::NEXT_WEEK,
\Bitrix\Main\UI\Filter\DateType::NEXT_MONTH,
\Bitrix\Main\UI\Filter\DateType::TOMORROW,
\Bitrix\Main\UI\Filter\DateType::LAST_90_DAYS
)
],
];
?>
<h3 class="my-2">Лиды</h3>
<div class="leads-list-content">
<div class="leads-list__top">
<div class="leads-list__filter">
<?$APPLICATION->IncludeComponent(
'bitrix:main.ui.filter',
'',
[
'FILTER_ID' => $list_id,
'GRID_ID' => $list_id,
'FILTER' => $ui_filter,
'ENABLE_LIVE_SEARCH' => true,
'ENABLE_LABEL' => true
]
);?>
</div>
<div class="leads-list__cta">
<div>
<button id="download-excel" class="ui-btn ui-btn-success">Скачать Excel</button>
</div>
</div>
</div>
<div class="leads-list__table">
<? $APPLICATION->IncludeComponent(
'bitrix:main.ui.grid',
'',
[
'GRID_ID' => $list_id,
'COLUMNS' => $columns,
'ROWS' => $list,
'NAV_OBJECT' => $arResult["nav_object"], // Объект постраничной навигации.
'AJAX_MODE' => 'Y', // Всегда должен быть 'Y'.
'AJAX_ID' => \CAjax::getComponentID('bitrix:main.ui.grid', '.default', ''),
'AJAX_OPTION_JUMP' => 'N',
'AJAX_OPTION_HISTORY' => 'N',
// По сколько показывать.
'SHOW_PAGESIZE' => true,
'PAGE_SIZES' => $pageSizes,
'SHOW_PAGINATION' => true,
'ALLOW_SORT' => true,
'SHOW_CHECK_ALL_CHECKBOXES' => false,
'SHOW_ROW_CHECKBOXES' => false,
'SHOW_SELECTED_COUNTER' => false,
// Для кнопки "Загрузить еще".
'CURRENT_PAGE' => $arResult['nav_object']->getCurrentPage(),
'ENABLE_NEXT_PAGE' => true,
'SHOW_MORE_BUTTON' => false, // true чтобы включить.
'NAV_PARAM_NAME' => 'page',
'SHOW_GROUP_EDIT_BUTTON' => false,
'SHOW_GROUP_DELETE_BUTTON' => false,
// Сообщения.
'HANDLE_RESPONSE_ERRORS' => true,
// Общее количество.
'SHOW_NAVIGATION_PANEL' => true,
'SHOW_TOTAL_COUNTER' => true,
'TOTAL_ROWS_COUNT' => $arResult['nav_object']->getRecordCount(),
'DEFAULT_PAGE_SIZE' => (int)$arParams['ROWS_PER_PAGE']
]
);
?>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>
<script>
document.querySelector('#download-excel').addEventListener('click', function() {
// Проверяем наличие грида.
let grid = BX.Main.gridManager.getById('<?=$list_id?>');
if (!grid || !grid.instance) {
alert('Грид не найден!');
return;
}
let data = [];
// Получаем заголовки из DOM.
let headers = [];
let headerCells = document.querySelectorAll('.main-grid-cell-head');
headerCells.forEach(function(cell, index) {
// Пропускаем первую ячейку, так как пустая.
if (index > 0) {
headers.push(cell.textContent.trim());
}
});
data.push(headers);
// Получаем данные строк из DOM.
let rows = document.querySelectorAll('.main-grid-row');
rows.forEach(function(row) {
let rowData = [];
let cells = row.querySelectorAll('.main-grid-cell');
cells.forEach(function(cell, index) {
// Пропускаем первую ячейку, так как пустая.
if (index > 0) {
rowData.push(cell.textContent.trim());
}
});
data.push(rowData);
});
// Формируем имя файла: список_ID + текущая дата и время.
let fileName = generateFileNameForDownload('<?=$list_id?>')
// Генерируем Excel-файл.
let ws = XLSX.utils.aoa_to_sheet(data);
let wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
XLSX.writeFile(wb, fileName);
});
function generateFileNameForDownload(id, ext = 'xlsx') {
let now = new Date();
let dateStr = now.getFullYear() +
'-' + ('0' + (now.getMonth() + 1)).slice(-2) +
'-' + ('0' + now.getDate()).slice(-2) +
'_' + ('0' + now.getHours()).slice(-2) +
'-' + ('0' + now.getMinutes()).slice(-2) +
'-' + ('0' + now.getSeconds()).slice(-2);
return id + '_' + dateStr + '.' + ext;
}
</script>
Еще примеры
Работа с инфоблоком
<?php
include($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");
$APPLICATION->SetTitle("Тестовый список");
use \Bitrix\Iblock\PropertyEnumerationTable;
use Bitrix\Main\Grid\Options as GridOptions;
use Bitrix\Main\UI\PageNavigation;
CModule::IncludeModule("iblock");
$list_id = 'example_list';
$grid_options = new GridOptions($list_id);
$sort = $grid_options->GetSorting(['sort' => ['DATE_CREATE' => 'DESC'], 'vars' => ['by' => 'by', 'order' => 'order']]);
$nav_params = $grid_options->GetNavParams();
$nav = new PageNavigation($list_id);
$nav->allowAllRecords(true)
->setPageSize($nav_params['nPageSize'])
->initFromUri();
if ($nav->allRecordsShown()) {
$nav_params = false;
} else {
$nav_params['iNumPage'] = $nav->getCurrentPage();
}
$ui_filter = [
['id' => 'NAME', 'name' => 'Название', 'type'=>'text', 'default' => true],
['id' => 'DATE_CREATE', 'name' => 'Дата создания', 'type'=>'date', 'default' => true],
];
?>
<h2>Фильтр</h2>
<div>
<?$APPLICATION->IncludeComponent('bitrix:main.ui.filter', '', [
'FILTER_ID' => $list_id,
'GRID_ID' => $list_id,
'FILTER' => $ui_filter,
'ENABLE_LIVE_SEARCH' => true,
'ENABLE_LABEL' => true
]);?>
</div>
<div style="clear: both;"></div>
<hr>
<h2>Таблица</h2>
<?php
$filterOption = new Bitrix\Main\UI\Filter\Options($list_id);
$filterData = $filterOption->getFilter([]);
foreach ($filterData as $k => $v) {
// Тут разбор массива $filterData из формата, в котором его формирует main.ui.filter в формат, который подойдет для вашей выборки.
// Обратите внимание на поле "FIND", скорее всего его вы и захотите засунуть в фильтр по NAME и еще паре полей
$filterData['NAME'] = "%".$filterData['FIND']."%";
}
$filterData['IBLOCK_ID'] = 68;
$filterData['ACTIVE'] = "Y";
$columns = [];
$columns[] = ['id' => 'ID', 'name' => 'ID', 'sort' => 'ID', 'default' => true];
$columns[] = ['id' => 'NAME', 'name' => 'Название', 'sort' => 'NAME', 'default' => true];
$columns[] = ['id' => 'DATE_CREATE', 'name' => 'Создано', 'sort' => 'DATE_CREATE', 'default' => true];
$res = \CIBlockElement::GetList($sort['sort'], $filterData, false, $nav_params,
["ID", "IBLOCK_ID", "NAME", "CODE", "PROPERTY_MANAGER", "PROPERTY_AIM_OF_REQUEST", "DATE_CREATE",
"PROPERTY_LAST_NAME", "PROPERTY_E_MAIL", "PROPERTY_FIRST_NAME", "PROPERTY_STATUS_OF_REQUEST"]
);
$nav->setRecordCount($res->selectedRowsCount());
while($row = $res->GetNext()) {
$list[] = [
'data' => [
"ID" => $row['ID'],
"NAME" => $row['NAME'],
"DATE_CREATE" => $row['DATE_CREATE'],
],
'actions' => [
[
'text' => 'Просмотр',
'default' => true,
'onclick' => 'document.location.href="?op=view&id='.$row['ID'].'"'
], [
'text' => 'Удалить',
'default' => true,
'onclick' => 'if(confirm("Точно?")){document.location.href="?op=delete&id='.$row['ID'].'"}'
]
]
];
}
$APPLICATION->IncludeComponent('bitrix:main.ui.grid', '', [
'GRID_ID' => $list_id,
'COLUMNS' => $columns,
'ROWS' => $list,
'SHOW_ROW_CHECKBOXES' => false,
'NAV_OBJECT' => $nav,
'AJAX_MODE' => 'Y',
'AJAX_ID' => \CAjax::getComponentID('bitrix:main.ui.grid', '.default', ''),
'PAGE_SIZES' => [
['NAME' => '20', 'VALUE' => '20'],
['NAME' => '50', 'VALUE' => '50'],
['NAME' => '100', 'VALUE' => '100']
],
'AJAX_OPTION_JUMP' => 'N',
'SHOW_CHECK_ALL_CHECKBOXES' => false,
'SHOW_ROW_ACTIONS_MENU' => true,
'SHOW_GRID_SETTINGS_MENU' => true,
'SHOW_NAVIGATION_PANEL' => true,
'SHOW_PAGINATION' => true,
'SHOW_SELECTED_COUNTER' => true,
'SHOW_TOTAL_COUNTER' => true,
'SHOW_PAGESIZE' => true,
'SHOW_ACTION_PANEL' => true,
'ALLOW_COLUMNS_SORT' => true,
'ALLOW_COLUMNS_RESIZE' => true,
'ALLOW_HORIZONTAL_SCROLL' => true,
'ALLOW_SORT' => true,
'ALLOW_PIN_HEADER' => true,
'AJAX_OPTION_HISTORY' => 'N'
]);
?>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>
Работа с Битрикс ORM
<?php
include($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");
$APPLICATION->SetTitle("Тестовый список");
use \Bitrix\Iblock\PropertyEnumerationTable;
use Bitrix\Main\Grid\Options as GridOptions;
use Bitrix\Main\UI\PageNavigation;
$list_id = 'example_list';
$grid_options = new GridOptions($list_id);
$sort = $grid_options->GetSorting(['sort' => ['ID' => 'DESC'], 'vars' => ['by' => 'by', 'order' => 'order']]);
$nav_params = $grid_options->GetNavParams();
$nav = new PageNavigation('request_list');
$nav->allowAllRecords(true)
->setPageSize($nav_params['nPageSize'])
->initFromUri();
$filterOption = new Bitrix\Main\UI\Filter\Options($list_id);
$filterData = $filterOption->getFilter([]);
$filter = [];
foreach ($filterData as $k => $v) {
// Тут разбор массива $filterData из формата, в котором его формирует main.ui.filter в формат, который подойдет для вашей выборки.
// Обратите внимание на поле "FIND", скорее всего его вы и захотите засунуть в фильтр по NAME и еще паре полей
$filter['NAME'] = "%".$filterData['FIND']."%";
}
$res = ExampleTable::getList([
'filter' => $filter,
'select' => [
"*",
],
'offset' => $nav->getOffset(),
'limit' => $nav->getLimit(),
'order' => $sort['sort']
]);
$ui_filter = [
['id' => 'NAME', 'name' => 'Название', 'type'=>'text', 'default' => true],
['id' => 'DATE_CREATE', 'name' => 'Дата создания', 'type'=>'date', 'default' => true],
];
?>
<h2>Фильтр</h2>
<div>
<?$APPLICATION->IncludeComponent('bitrix:main.ui.filter', '', [
'FILTER_ID' => $list_id,
'GRID_ID' => $list_id,
'FILTER' => $ui_filter,
'ENABLE_LIVE_SEARCH' => true,
'ENABLE_LABEL' => true
]);?>
</div>
<div style="clear: both;"></div>
<hr>
<h2>Таблица</h2>
<?php
$columns = [];
$columns[] = ['id' => 'ID', 'name' => 'ID', 'sort' => 'ID', 'default' => true];
$columns[] = ['id' => 'NAME', 'name' => 'Название', 'sort' => 'NAME', 'default' => true];
$columns[] = ['id' => 'DATE_CREATE', 'name' => 'Создано', 'sort' => 'DATE_CREATE', 'default' => true];
foreach ($res->fetchAll() as $row) {
$list[] = [
'data' => [
"ID" => $row['ID'],
"NAME" => $row['NAME'],
"DATE_CREATE" => $row['DATE_CREATE'],
],
'actions' => [
[
'text' => 'Просмотр',
'default' => true,
'onclick' => 'document.location.href="?op=view&id='.$row['ID'].'"'
], [
'text' => 'Удалить',
'default' => true,
'onclick' => 'if(confirm("Точно?")){document.location.href="?op=delete&id='.$row['ID'].'"}'
]
]
];
}
$APPLICATION->IncludeComponent('bitrix:main.ui.grid', '', [
'GRID_ID' => $list_id,
'COLUMNS' => $columns,
'ROWS' => $list,
'SHOW_ROW_CHECKBOXES' => false,
'NAV_OBJECT' => $nav,
'AJAX_MODE' => 'Y',
'AJAX_ID' => \CAjax::getComponentID('bitrix:main.ui.grid', '.default', ''),
'PAGE_SIZES' => [
['NAME' => '20', 'VALUE' => '20'],
['NAME' => '50', 'VALUE' => '50'],
['NAME' => '100', 'VALUE' => '100']
],
'AJAX_OPTION_JUMP' => 'N',
'SHOW_CHECK_ALL_CHECKBOXES' => false,
'SHOW_ROW_ACTIONS_MENU' => true,
'SHOW_GRID_SETTINGS_MENU' => true,
'SHOW_NAVIGATION_PANEL' => true,
'SHOW_PAGINATION' => true,
'SHOW_SELECTED_COUNTER' => true,
'SHOW_TOTAL_COUNTER' => true,
'SHOW_PAGESIZE' => true,
'SHOW_ACTION_PANEL' => true,
'ALLOW_COLUMNS_SORT' => true,
'ALLOW_COLUMNS_RESIZE' => true,
'ALLOW_HORIZONTAL_SCROLL' => true,
'ALLOW_SORT' => true,
'ALLOW_PIN_HEADER' => true,
'AJAX_OPTION_HISTORY' => 'N'
]);
?>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>