Пресет в main.ui.filter

Вот как бы нет нареканий к большущим компонентам main.ui.filter и main.ui.grid, но я нигде не видел рабочий код для передачи данных для пресета фильтра и последующей фильтрации выборки для main.ui.grid.

Фокус в том, что пресет задаётся до вызова этих компонентов, и выбранный "по умолчанию" должен примениться к выборке main.ui.grid.
Что бы это реализовать в компоненте в месте где получаем и проверяем значения фильтра делаем так:
$arResult['GRID']['FILTER_ID'] = (str)$arParams['FILTER_ID];
$arResult['GRID']['FILTER_FIELDS'] =  $arParams['FILTER_FIELDS] // массив полей фильтра
$arResult['GRID']['FILTER_OBJ'] = new Bitrix\Main\UI\Filter\Options($arResult['GRID']['FILTER_ID'], $arParams['FILTER_PRESETS']); // либо запилить пресет прямо в компонент.
$filterData = $arResult['GRID']['FILTER_OBJ']->getFilter($arResult['GRID']['FILTER_FIELDS']); // получили массив для фильтрации

Фильтруем! :)

0
25.09.2020 17:34:38
И добавлю свой коротки алгоритм обработки полученного фильтра $filterData
....
$filterData = $arResult['GRID']['FILTER_OBJ']->getFilter($arResult['GRID']['FILTER_FIELDS']); // получили массив для фильтрации
$arResult['GRID']['GET_LIST']['filter'] = []; // массив условий для последующей фильтрации в ::getList(...)

if ($filterData["FILTER_APPLIED"] == true) {
    foreach ($filterData as $k => $v) {
        $v = htmlspecialchars($v);
        if (is_numeric(str_replace(",",".",$v))) $v = floatval(str_replace(",",".",$v)); // преобразование числа
        if (preg_match('#(_from|_to)#', $k, $logics)){
            $logics = $logics[1];
            $k = preg_replace('#(_from|_to)#', '', $k);
            if ($logics=="_from"){
                $logics = ">";
            }elseif($logics=="_to"){
                $logics = "<";
            }
        }elseif (preg_match('#^(<|>|!=|>=|<=|%)#', $v, $logics) && $logics[1]){
            $logics = $logics[1];
            $v = preg_replace('#^'.$logics.'#', '', $v);
        } else {
            $logics = '%';
        }
        if ($k == 'CONTRAGENT') {
            $arResult['GRID']['GET_LIST']['filter'][$logics.'CONTRAGENT_NAME'] = $v;
        }elseif ($k == 'ADDRESS') {
            $arResult['GRID']['GET_LIST']['filter'][$logics.'ADDRESS_NAME'] = $v;
        }elseif ($k == 'ACCOUNT_NUMBER') {
            $arResult['GRID']['GET_LIST']['filter'][$logics.'ACCOUNT_NUMBER'] = $v;
        }elseif (isset($arResult['GRID']['FILTER_TABLE_CODE'][$k])) {
            $col_name = $arResult['GRID']['FILTER_TABLE_CODE'][$k]?:$k;
            $arResult['GRID']['GET_LIST']['filter'][$logics.$col_name] = $v;
        }elseif ($k == 'FIND' && !empty($v)) {
            $find = [];
            foreach($arResult['GRID']['FILTER_TABLE_CODE'] as $code => $col_name){
                if ($col_name) $find[$logics.$col_name] = trim($v);
            }
            $arResult['GRID']['GET_LIST']['filter'][] = array_merge(["LOGIC" => "OR"],$find);
        }
    }
    unset($col_name, $find);
}

Комментируйте, буду рад!
0
13.11.2020 11:56:32
Заметил, что возможна ситуация поиска "пробела" для этого требуется исключить такой кейс:
вместо
$v = htmlspecialchars($v);
написать
$v = trim(preg_replace('#\s+|\t+#im',' ',htmlspecialchars($v)));
if (empty($v)) continue;
0
Эдуард
30.05.2023 02:31:41
Алгоритм обработки фильтра встроен в ядро:
\Bitrix\Main\UI\Filter\Type::getLogicFilter($filterFields, $sourceFields);
где $sourceFields - массив описания полей фильтра:
$sourceFields = [
   ['id' => 'ID', 'name' => 'ID', 'type' => 'number', 'default' => true],    
   ['id' => 'DATE_UPDATE', 'name' => 'Дата обновления', 'type' => 'date', 'default' => true]
];