В блог

Гриды и фильтры в Битриксе

UPD: По многочисленным просьбам добавили файлы с примерами готовых страниц, на которых используются гриды и фильтры. Пользуйтесь :) Там два файла – один с примером на инфоблоке, второй – на битриксовом ORM

Скорее всего, вы сталкивались с задачей вывести в публичной части (да и в админке) проекта какую-либо служебную информацию для пользователей в табличном виде. Наверняка, вы писали собственные шаблоны для компонентов и потом добавляли костыли для фильтрации и сортировки этих данных.

Начиная с версии 17.0.7  Главного модуля 1С-Битрикс вышли два компонента: bitrix:main.ui.filter и bitrix:main.ui.grid с классами Bitrix\Main\UI\Filter и Bitrix\Main\Grid (есть даже в редакции «Первый сайт»).

ef118e766db6540ac860d.png

Таблица

За вывод таблицы отвечает компонент bitrix:main.ui.grid. Параметры:

GRID_ID
string Идентификатор грида (такой же указывали у фильтра)
COLUMNS
array Массив с head таблицы ROWS array Массив с значениями таблицы, действиями в контекстном меню
SHOW_ROW_CHECKBOXES
bool Показывать чекбоксы у строк для множественных действий
NAV_OBJECT
object Объект для постранички
AJAX_MODE
string Использовать ли ajax режим
AJAX_ID
string Ajax ID Берется из компонента фильтра
PAGE_SIZES
array Массив для селекта с выбором кол-ва элементов на странице
AJAX_OPTION_JUMP
string
SHOW_CHECK_ALL_CHECKBOXES
bool Показывать "Выбрать все"
SHOW_ROW_ACTIONS_MENU
bool
SHOW_GRID_SETTINGS_MENU
bool
SHOW_NAVIGATION_PANEL
bool
SHOW_PAGINATION
bool
SHOW_SELECTED_COUNTER
bool Показывать "Выбрано элементов"
SHOW_TOTAL_COUNTER
bool Показывать "Всего элементов"
SHOW_PAGESIZE
bool Выводить селект с выбором кол-ва элементов на странице
SHOW_ACTION_PANEL
bool
ALLOW_COLUMNS_SORT
bool
ALLOW_COLUMNS_RESIZE
bool
ALLOW_HORIZONTAL_SCROLL
bool Будет доступен горизонтальный скролл
ALLOW_SORT
bool Разрешить сортировку
ALLOW_PIN_HEADER
bool Разрешать закреплять шапку таблицы
AJAX_OPTION_HISTORY
bool

Пример вызова компонента:

$grid_options = new Bitrix\Main\Grid\Options('report_list');
$sort = $grid_options->GetSorting(['sort' => ['ID' => 'DESC'], 'vars' => ['by' => 'by', 'order' => 'order']]);
$nav_params = $grid_options->GetNavParams();

$nav = new Bitrix\Main\UI\PageNavigation('report_list');
$nav->allowAllRecords(true)
    ->setPageSize($nav_params['nPageSize'])
    ->initFromUri();

// Кнопка удалить
$onchange = new Onchange();
$onchange->addAction(
    [
        'ACTION' => Actions::CALLBACK,
        'CONFIRM' => true,
        'CONFIRM_APPLY_BUTTON'  => 'Подтвердить',
        'DATA' => [
            ['JS' => 'Grid.removeSelected()']
        ]
    ]
);

$APPLICATION->IncludeComponent('bitrix:main.ui.grid', '', [ 
    'GRID_ID' => 'report_list', 
    'COLUMNS' => [ 
        ['id' => 'ID', 'name' => 'ID', 'sort' => 'ID', 'default' => true], 
        ['id' => 'DATE', 'name' => 'Дата', 'sort' => 'DATE', 'default' => true], 
        ['id' => 'AMOUNT', 'name' => 'Сумма', 'sort' => 'AMOUNT', 'default' => true], 
        ['id' => 'PAYER_INN', 'name' => 'ИНН Плательщика', 'sort' => 'PAYER_INN', 'default' => true], 
        ['id' => 'PAYER_NAME', 'name' => 'Плательщик', 'sort' => 'PAYER_NAME', 'default' => true], 
        ['id' => 'IS_SPEND', 'name' => 'Тип операции', 'sort' => 'IS_SPEND', 'default' => true], 
    ], 
    'ROWS' => $list, //Самое интересное, опишем ниже
    'SHOW_ROW_CHECKBOXES' => true, 
    'NAV_OBJECT' => $nav, 
    'AJAX_MODE' => 'Y', 
    'AJAX_ID' => \CAjax::getComponentID('bitrix:main.ui.grid', '.default', ''), 
    'PAGE_SIZES' => [ 
        ['NAME' => "5", 'VALUE' => '5'], 
        ['NAME' => '10', 'VALUE' => '10'], 
        ['NAME' => '20', 'VALUE' => '20'], 
        ['NAME' => '50', 'VALUE' => '50'], 
        ['NAME' => '100', 'VALUE' => '100'] 
    ], 
    'AJAX_OPTION_JUMP'          => 'N', 
    'SHOW_CHECK_ALL_CHECKBOXES' => true, 
    '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, 
    'ACTION_PANEL'              => [ 
        'GROUPS' => [ 
            'TYPE' => [ 
                'ITEMS' => [ 
                    [ 
                        'ID'    => 'set-type', 
                        'TYPE'  => 'DROPDOWN', 
                        'ITEMS' => [ 
                            ['VALUE' => '', 'NAME' => '- Выбрать -'], 
                            ['VALUE' => 'plus', 'NAME' => 'Поступление'], 
                            ['VALUE' => 'minus', 'NAME' => 'Списание'] 
                        ] 
                    ], 
                    [ 
                        'ID'       => 'edit', 
                        'TYPE'     => 'BUTTON', 
                        'TEXT'        => 'Редактировать', 
                        'CLASS'        => 'icon edit', 
                        'ONCHANGE' => '' 
                    ], 
                    [
                        'ID'       => 'delete',
                        'TYPE'     => 'BUTTON',
                        'TEXT'     => 'Удалить',
                        'CLASS'    => 'icon remove',
                        'ONCHANGE' => $onchange->toArray()
                    ],
                ], 
            ] 
        ], 
    ], 
    'ALLOW_COLUMNS_SORT'        => true, 
    'ALLOW_COLUMNS_RESIZE'      => true, 
    'ALLOW_HORIZONTAL_SCROLL'   => true, 
    'ALLOW_SORT'                => true, 
    'ALLOW_PIN_HEADER'          => true, 
    'AJAX_OPTION_HISTORY'       => 'N' 
]);

Передаем данные в таблицу

$list = [
    [
        'data'    => [ //Данные ячеек
        "ID" => 1,
            "NAME" => "Название 1",
            "AMOUNT" => 1000,
            "PAYER_NAME" => "Плательщик 1"
        ],
        'actions' => [ //Действия над ними
            [
                'text'    => 'Редактировать',
                'onclick' => 'document.location.href="/accountant/reports/1/edit/"'
            ],
            [
                'text'    => 'Удалить',
                'onclick' => 'document.location.href="/accountant/reports/1/delete/"'
            ]

        ],
    ], [
        'data'    => [ //Данные ячеек
            "ID" => 2,
            "NAME" => "Название 2",
            "AMOUNT" => 3000,
            "PAYER_NAME" => "Плательщик 2"
        ],
        'actions' => [ //Действия над ними
            [
                'text'    => 'Редактировать',
                'onclick' => 'document.location.href="/accountant/reports/2/edit/"'
            ],
            [
                'text'    => 'Удалить',
                'onclick' => 'document.location.href="/accountant/reports/2/delete/"'
            ]

        ],
    ]
];

Результат вывода:

60474cfc43365608eb3d4.png


Панель действий ACTION_PANEL:

a663fd9d297d7542f3d7a.png

Фильтр

За фильтрацию отвечает компонент bitrix:main.ui.filter. Его параметры:

FILTER_ID
string Идентификатор фильтра (должен быть уникальным)
GRID_ID
string Идентификатор грида к которому применяем фильтр
FILTER
array Массив с полями для фильтрации
ENABLE_LABEL
bool Показывать название полей или нет
ENABLE_LIVE_SEARCH
bool Будет ли доступна live-фильтрация

Пример вызова:

$APPLICATION->IncludeComponent('bitrix:main.ui.filter', '', [ 
    'FILTER_ID' => 'report_list', 
    'GRID_ID' => 'report_list', 
    'FILTER' => [ 
        ['id' => 'DATE', 'name' => 'Дата', 'type' => 'date'], 
        ['id' => 'IS_SPEND', 'name' => 'Тип операции', 'type' => 'list', 'items' => ['' => 'Любой', 'P' => 'Поступление', 'M' => 'Списание'], 'params' => ['multiple' => 'Y']],
        ['id' => 'AMOUNT', 'name' => 'Сумма', 'type' => 'number'], 
        ['id' => 'PAYER_INN', 'name' => 'ИНН Плательщика', 'type' => 'number'], 
        ['id' => 'PAYER_NAME', 'name' => 'Плательщик'], 
    ], 
    'ENABLE_LIVE_SEARCH' => true, 
    'ENABLE_LABEL' => true 
]);

Результат:

7c3c71980bdbcc9adcfde.png

Также фильтры можно сохранять для быстрого использования:

574cf22ff811195be0df7.png

Связка фильтра и таблицы

Чтобы пробросить данные из фильтра в таблицу, необходимо собрать фильтр:

$filter = [];
$filterOption = new Bitrix\Main\UI\Filter\Options('report_list');
$filterData = $filterOption->getFilter([]);
foreach ($filterData as $k => $v) {
    $filter[$k] = $v;            
}

Скачать примеры

Архив с двумя файлами — один с примером на инфоблоке, второй — на битриксовом ORM.

Фильтрация любых данных

Связка Фильтр-Таблица работает в Битриксе по-умолчанию, но иногда хочется такую фильтрацию добавить к своим данным, например, к выводу графика

29a6ffa9dc26064da258b.png
Данные из фильтра передаются в кастомный компонент статистики

Для того, чтобы это заработало, необходимо «подписаться» на событие применения фильтра:

<script type="text/javascript">
BX.addCustomEvent('BX.Main.Filter:apply', BX.delegate(function (command, params) { 
    var workarea = $('#' + command); // в command будет храниться GRID_ID из фильтра 

    $.post(window.location.href, function(data){ 
        workarea.html($(data).find('#' + command).html()); 
    }) 
}));
</script>

Хаки

Почему-то Битрикс в своих компонентах автоматически не подцепляет css-файл со стилями кнопок (на момент написания статьи), поэтому перед вызовом компонентов, рекомендуется добавить css-файл вручную:

Bitrix\Main\Page\Asset::getInstance()->addCss('/bitrix/css/main/grid/webform-button.css');

Чтобы обновить грид без перезагрузки страницы, воспользуйтесь методом:

<script type="text/javascript">
var reloadParams = { apply_filter: 'Y', clear_nav: 'Y' };
var gridObject = BX.Main.gridManager.getById('report_list'); // Идентификатор грида

if (gridObject.hasOwnProperty('instance')){
  gridObject.instance.reloadTable('POST', reloadParams);
}
</script>
Хочу проект
Закрыть