The last notes
All English-language materials have been translated fully automatically using the Google service
The article describes an example of placing a linked filter and a table with filtering real data from a typical highload block without complex selections
The example is not fully working, since some of the functionality has been added to it only to illustrate how to add buttons or capabilities. You will have to write the handlers yourself. But the main code is working and should work with proper porting.
Filterbitrix:main.ui.filter
Parameters:
FILTER_ID | string Filter ID (must be unique) |
GRID_ID | string The identifier of the grid to which we are applying the filter |
FILTER | array Array with fields for filtering |
ENABLE_LABEL | bool Show field names or not |
ENABLE_LIVE_SEARCH | bool Will live filtering be available? |
Call example:
use Bitrix\Main\Grid\Options as GridOptions;
use Bitrix\Main\UI\PageNavigation;
use \Bitrix\Main\Type\DateTime as DT;
use Bitrix\Main\Loader;
use Bitrix\Highloadblock as HL;
$grid_id = $filter_id = 'CLIENTS_GRID';
$APPLICATION->IncludeComponent('bitrix:main.ui.filter', '', [
'FILTER_ID' => $filter_id,
'GRID_ID' => $grid_id,
'FILTER' => [
['id' => 'DEAL_ID', 'name' => 'ID сделки', 'type'=>'text', 'default' => true],
['id' => 'DEAL_STAGE', 'name' => 'Стадия сделки', 'type' => 'list', 'items' => [
'18' => '*В обработке',
'19' => '*Договор подписан'
], 'params' => ['multiple' => 'Y'], 'default' => true],
['id' => 'DEAL_START_DATE', 'name' => 'Дата начала сделки', 'type' => 'list', 'items' => [
'1' => '0-7 дней',
'2' => '0-14 дней',
'3' => '0-30 дней',
'4' => '0-2 мес',
'5' => '0-6 мес',
], 'params' => ['multiple' => 'N'], 'default' => true],
],
'ENABLE_LIVE_SEARCH' => true,
'ENABLE_LABEL' => true,
'VALUE_REQUIRED_MODE' => true,
'FILTER_PRESETS' => [
"defaultPreset" => [
"name" => 'Пресет по сделкам',
"default" => true, // если true - пресет по умолчанию
"fields" => [
"DEAL_STAGE" => "24",
"NAME" => "Новосибирск",
]
],
"PRESET_NEW" => [
"name" => 'Пресет новый',
"default" => false, // если true - пресет по умолчанию
"fields" => [
"DEAL_ID" => "17534",
]
],
]
]);
Link filter and table. To forward data from a filter to a table, you need to collect a filter:
foreach ($filterFields as $k => $v) {
if($k == 'FIND' && $v)
$filterData['NAME'] = "%".$v."%";
else
$filterData[$k] = $v;
}
$mainFilter = [];
// Deal stage
if($filterData['DEAL_STAGE'])
$mainFilter['UF_STAGE_ID'] = $filterData['DEAL_STAGE'];
// trade ID
if($filterData['DEAL_ID'])
$mainFilter['UF_ID'] = $filterData['DEAL_ID'];
// Handle the date
if($filterData['DEAL_START_DATE'][0]){
$format = "Y-m-d H:i:s";
$today = date($format);
$interval = 0;
switch ($filterData['DEAL_START_DATE'][0]){
case '1':
$interval = 7;
break;
case '2':
$interval = 14;
break;
case '3':
$interval = 30;
break;
case '4':
$interval = 60;
break;
case '5':
$interval = 180;
break;
}
$data = \CLASS\Helper\Date::dateMinus($today, $format, 'days', $interval);
$mainFilter['>UF_BEGINDATE'] = DT::createFromTimestamp(strtotime($data));
}
bitrix: main.ui.grid
Parameter list:
GRID_ID | string Grid ID (the same was specified in the filter) |
COLUMNS | array Array with table head ROWS array Array with table values, actions in the context menu |
SHOW_ROW_CHECKBOXES | bool Show checkboxes on rows for multiple actions |
NAV_OBJECT | object Object for page |
AJAX_MODE | string Whether to use ajax mode |
AJAX_ID | string Ajax ID Taken from the filter component |
PAGE_SIZES | array Array for select with a choice of the number of elements on the page |
AJAX_OPTION_JUMP | string |
SHOW_CHECK_ALL_CHECKBOXES | bool Show "Select All" |
SHOW_ROW_ACTIONS_MENU | bool |
SHOW_GRID_SETTINGS_MENU | bool |
SHOW_NAVIGATION_PANEL | bool |
SHOW_PAGINATION | bool |
SHOW_SELECTED_COUNTER | bool Show "Selected Items" |
SHOW_TOTAL_COUNTER | bool Show "Total Items" |
SHOW_PAGESIZE | bool Display select with a choice of the number of elements on the page |
SHOW_ACTION_PANEL | bool |
ALLOW_COLUMNS_SORT | bool |
ALLOW_COLUMNS_RESIZE | bool |
ALLOW_HORIZONTAL_SCROLL | bool Horizontal scrolling will be available |
ALLOW_SORT | bool Allow sorting |
ALLOW_PIN_HEADER | bool Allow to pin the table header |
AJAX_OPTION_HISTORY | bool |
Example of calling a component:
$grid_options = new GridOptions($grid_id);
$sort = $grid_options->GetSorting(['sort' => ['DATE_CREATE' => 'DESC'], 'vars' => ['by' => 'by', 'order' => 'order']]);
$nav_params = $grid_options->GetNavParams();
$nav = new PageNavigation($grid_id);
$nav->allowAllRecords(true)
->setPageSize($nav_params['nPageSize'])
->initFromUri();
if ($nav->allRecordsShown())
$nav_params = false;
else
$nav_params['iNumPage'] = $nav->getCurrentPage();
$getListOptions = array(
"select" => ['ID', "UF_BEGINDATE", 'UF_TITLE', 'UF_STAGE_ID'],
"order" => ["ID" => "DESC"],
"filter" => $mainFilter,
'limit' => $nav_params['nPageSize'],
'offset' => $nav_params['iNumPage'] - 1,
'runtime' => $runtimes ? $runtimes : '',
'count_total' => true
);
Loader::includeModule("highloadblock");
$hlblock = HL\HighloadBlockTable::getById(15)->fetch();
$entity = HL\HighloadBlockTable::compileEntity($hlblock);
$entity_data_class = $entity->getDataClass();
$dealsData = $entity_data_class::getList($getListOptions);
$dealsCount = $dealsData->getCount();
$dealsData = $dealsData->fetchAll();
$nav->setRecordCount($dealsCount);
foreach($dealsData as $k => $row) {
$list[] = [
'data' => [
"ID" => $row['ID'],
"DEAL_START" => $row['UF_BEGINDATE'],
"DEAL_NAME" => $row['UF_TITLE'],
"DEAL_STATUS" => $row['UF_STAGE_ID'],
],
'default_action' => [
"href" => '/bitrix/admin/iblock_element_edit.php?IBLOCK_ID=2&type=content&lang=ru&ID=4&find_section_section=-1&WF=Y',
"title" => 'Редактировать элемент',
],
'actions' => [
[
'text' => 'Редактировать',
'default' => true,
'onclick' => vsprintf("contextMenuGridAction.actionEdit(%d, '%s')", [
'ID' => $row['ID'],
'NAME' => $row['NAME']
])
],
[
'text' => $row['ACTIVE'] == 'Y'
? 'Деактивировать'
: 'Активировать',
'default' => true,
'onclick' => $row['ACTIVE'] == 'Y'
? "contextMenuGridAction.actionDeactivate($row[ID])"
: "contextMenuGridAction.actionActivate($row[ID])"
],
[
'delimiter' => true,
],
[
'text' => 'Открыть на сайте',
'default' => true,
'onclick' => "contextMenuGridAction.actionOpenOnSite('$row[NEW_URL]');"
],
[
'delimiter' => true,
],
[
'text' => 'Создать символьный код',
'default' => true,
'onclick' => "if(confirm('Вы уверены, что хотите изменить символьный код элемента? Это может повлиять на ссылку, по которой на сайте отображается элемент.')) BX.Main.gridManager.getById('tbl_iblock_element_b7d3215a9c5d7a3446fc85e1a5877fc2').instance.reloadTable('POST', {'action_button_tbl_iblock_element_b7d3215a9c5d7a3446fc85e1a5877fc2':'code_translit','ID':'4','IBLOCK_ID':'2','type':'content','lang':'ru','find_section_section':'-1'})"
],
[
'delimiter' => true,
],
[
'text' => 'Удалить',
'default' => true,
'onclick' => "contextMenuGridAction.actionDelete($row[ID])"
],
]
];
}
$columns = [];
$columns[] = ['id' => 'DEAL_START', 'name' => 'Дата начала сделки', 'sort' => 'DEAL_START', 'content' => 'Дата начала сделки', 'title' => 'Дата начала сделки', 'column_sort' => 100, 'default' => true];
$columns[] = ['id' => 'DEAL_NAME', 'name' => 'Название сделки', 'sort' => 'DEAL_NAME', 'content' => 'Название сделки', 'title' => 'Название сделки', 'column_sort' => 200, 'default' => true];
$columns[] = ['id' => 'DEAL_STATUS', 'name' => 'Статус сделки', 'sort' => 'DEAL_STATUS', 'content' => 'Статус сделки', 'title' => 'Статус сделки', 'column_sort' => 300, 'default' => true];
$gridParams = [
'GRID_ID' => $grid_id,
'COLUMNS' => $columns,
'ROWS' => $list,
'FOOTER' => [
'TOTAL_ROWS_COUNT' => $dealsCount,
],
'SHOW_ROW_CHECKBOXES' => false,
'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' => 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',
'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' => $onchange->toArray()
],
[
'ID' => 'delete',
'TYPE' => 'BUTTON',
'TEXT' => 'Удалить',
'CLASS' => 'icon remove',
//'ONCHANGE' => $onchange->toArray()
],
],
]
],
],
];
$APPLICATION->IncludeComponent('bitrix:main.ui.grid', '', $gridParams);
?>
<script>
BX.ready(function ()
{
var gridObject = BX.Main.gridManager.getById('<?= $grid_id ?>');
if (gridObject.hasOwnProperty('instance')) {
gridObject.instance.reloadTable(null, null);
}
})
</script>
<script>
BX.ready(function () {
//Пример перехвата события применения фильтра
BX.addCustomEvent('BX.Main.Filter:apply', BX.delegate(function (command, params) {
//var workarea = $('#' + command); // в command будет храниться GRID_ID из фильтра
}));
});
var contextMenuGridAction = new FilterUI.ContextMenuInnerGrid();
</script>
Filter any data
The Filter-Table bundle works in Bitrix by default, but sometimes you want to add such filtering to your data, for example, to the graph output
For this to work, you need to "subscribe" to the filter application event:
<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>
Hacks
For some reason, Bitrix in its components does not automatically pick up the css file with button styles (at the time of this writing), therefore, before calling the components, it is recommended to add the css file manually:
Bitrix\Main\Page\Asset::getInstance()->addCss('/bitrix/css/main/grid/webform-button.css');
To refresh the grid without reloading the page, use the method:
<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>
Starting from version 17.0.7
, two bitrix components appeared in Bitrix: main.ui.filter
and bitrix: main.ui.grid
with the classes Bitrix\Main\UI\Filter
and Bitrix\Main\Grid
(even in the First Site edition).
Worth reading:
Comments