Как сделать фильтр всех товаров на сайте по свойству, сохранив штатный функционал, и не сломав мозг?
Передо мной стояла следующая задача: сделать фильтрацию всех товаров в инфоблоке по одному свойству, сохранив штатный функционал и рабочий «Умный фильтр». Вы скажете, что в битриксе есть замечательный «умный» фильтр с его фасетными индексами, а я скажу, что да, он есть. Но давайте взглянем на исходные данные задачи :
1. У нас есть инфоблок, в корне которого лежат основные разделы

2. Фильтрация должна происходить по ссылкам с главной страницы

И так, у нас есть сразу 2 проблемы:
1. В битриксе нельзя вывести все товары из инфоблока, не указав определенный раздел инфоблока (как бы можно, но в настройках штатного компонента этого нет)
2. Как сделать ссылку на фильтр, если в запросе на фильтрацию подставляются какие-то левые значения (arrFilter_55_4161729085=Y&set_filter=Показать)?
Для более полного понимая способа решения данной задачи проделаю все шаги с самого начала на демо-сайте битрикса (https://bitrixlabs.ru/#create-demo).
Первым делом нужно создать отдельную страницу, на которой будет выводиться наш каталог с умным фильтром:

Специально выбрал фильтр по цвету, потому что цвет есть у нас во всех разделах сайта, как раз то, что нам нужно.
При переходе на созданную страницу мы видим список всех разделов инфоблока (а нам нужен список всех товаров из всех разделов данного инфоблока).
Копируем стандартный шаблон компонента «каталог», чтобы не портить стандартный + чтобы избежать возможных перезаписей шаблона после обновлений:


Теперь переходим к редактированию самого шаблона, а именно нам нужен файл «sections.php», удаляем в нем весь код и заменяем его на:
Здесь мы просто подключаем вертикальную секцию шаблона, чтобы у нас сразу выводился фильтр и список товаров без каких либо списков раздела. Вам может понадобиться подключить горизонтальную секцию, а может и вовсе оставить вывод списка разделов и сравнение товаров (в таком случае вам нужно будет скопировать из файла section_vertical.php код для вызова компонента умного фильтра и код для вызова компонента секции).
Смотрим что получилось:

Переходим к редактированию параметров компонента и выбираем нужный инфоблок:

Смотрим что получилось и ловим фиаско:

Переходим в редактирование параметров компонента и включаем умный фильтр (попутно выбираем нужные свойства для фильтрации и отключаем сайдбар и вывод дерева каталога):

Переходим к редактированию файла «section_vertical.php», ищем вызов компонента «bitrix::catalog.section» и добавляем ему к параметрам:
"SHOW_ALL_WO_SECTION" => "Y",

А вот пояснение к параметру из официальной документации:

Теперь переходим на нашу страницу с товарами и видим уже примерно следующее:

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

Пробуем оставить только свойство цвета и переходим по полученной ссылке:

Все прекрасно работает
Остается понять алгоритм генерации данного параметра в запросе:
33 — это у нас ID свойства с цветом

А вот откуда тут берется 744714710 — не понято. Сначала я думал, что это может быть айдишкой самого значения свойства, но тут циферки для ID большие слишком + я все таки решил убедиться и проверил все это дело примерно таким способом:
$res = CIBlockElement::GetList($arSort, $arFilter, false, false, $arSelect); while($ob = $res->GetNextElement())< $arFields = $ob->GetFields(); print_r($arFields); >
Но там и рядом не было ничего с нужным нам значением. Тогда я решил заглянуть в исходники компонента умного фильтра и там нашел вот такой кусочек кода:

Собственно тут видно, что ключ фильтрации у нас генерируется за счет метода «fillItemValues»:
$this->fillItemValues($arResult["ITEMS"][$PID], $value)
Находим его в файле «class.php» с исходниками компонента умного фильтра (кто бы сомневался, хотя… битрикс же):

На 642 строке данного файла находим код, который и генерирует ключ фильтра:
$keyCrc = abs(crc32($htmlKey));
Получается, что тут просто высчитывается сумма из некого «htmlKey» и берется значение суммы по модулю
Находим происхождение «htmlKey» на строке 518:
$htmlKey = htmlspecialcharsbx($key);
Смотрим из чего у нас выходит «key»:

И видим, что при обычных раскладах это просто значение свойства.
Получается, что значение свойства хешируют и берут его значение по модулю + перед хеш суммой добавляется ID свойства.
Возвращаемся к моей изначальной задаче и делаем следующее:
$propValues = CIBlockElement::GetPropertyValues(8, array(), false, array("ID" => 55));//Получаем все значения свойства "производитель" $pvalues = array(); while ($val = $propValues->Fetch())
Перебираем все значения нужного нам свойства и записываем все это дело в ассоциативный массив.
А уже при выводе списка производителей просто ищем значение по уже готовому массиву:
Тут html код вывода картинки производителя
Вауля и наш костыль готов к работе =)
При использовании данного метода есть свои нюансы, на странице с фильтром при выборе свойства фильтрации у нас всегда показывает 0 значений, хотя по факту там больше 0:

Но думаю, что если покопаться, то можно разобраться и с этим. В любом случае, данное решение лучше, чем просто выборка всех элементов через «GetList» и создание своего кастомного фильтра с нуля.
Надеюсь, что данная статья хоть кому-то облегчит жизнь и сэкономит пару часов,.
Создаем свой фильтр на сайте под управлением «1С-Битрикс»
При разработке одного сайта, передо мной встала следующая задача: нужно было создать компонент для быстрого подбора элементов каталога и разместить его на каждой странице сайта. Результат его работы должен был отображаться на отдельной странице. Немного подумав, я понял, что этот компонент очень похож на стандартные фильтры, реализованные в системе «1С-Битрикс», но из-за особенностей их работы они мне не подходили. В этой статье я опишу процесс поиска решения этой задачи. Возможно, он будет полезен другим разработчикам, если они столкнуться с аналогичным заданием. Все изыскания я проводил на демо-версии системы. При установке ее на локальный веб-сервер, я выбрал вариант «для разработчиков». Сразу хочу предупредить читателя, что мое решение не является идеальным, может быть вы сможете придумать что-то лучшее. Возможно, статья покажется вам сложной для понимания, поэтому читайте внимательней, я постараюсь объяснить здесь тонкости разработки компонента как можно проще.
Зачем нужен свой фильтр и почему бы не использовать стандартные?
В системе «1С-Битрикс» существует 2 компонента с функционалом фильтра – это «Умный фильтр» (bitrix:catalog.smart.filter) и «Фильтр по элементам» (bitrix:catalog.filter). По сути это просто HTML-формы с полями, в которых указаны критерии для фильтрации элементов. «Умный фильтр» обычно размещается в комплексном компоненте «Каталог», а именно на страницах со списком элементов раздела. Если разместить на странице сайта только этот компонент, корректно работать он не будет, потому что в его настройках нельзя указать страницу с компонентом, который будет фильтровать элементы и показывать результаты. То же самое касается фильтра по элементам. Его также нужно размещать на страницах комплексного компонента «Каталог». Также у этого фильтра нет никаких настроек, касающихся типа полей, которые будут использованы в HTML-форме фильтра. На рисунке можно увидеть стандартные HTML-формы фильтров в Битриксе и то, что нужно было мне.

Конечно, можно было бы попытаться настроить под себя имеющиеся фильтры, но я решил не «заморачиваться» с настройками, потому что был не уверен в результате, а зря тратить время мне не хотелось. В итоге я решил написать свой компонент. Я назвал его elfilter и разместил в папке /bitrix/components/mattweb/. Далее в тексте статьи я буду называть его mattweb:elfilter.
Как все это работает
Как я писал выше фильтр – это по сути просто HTML-форма, в полях которой собираются уникальные значения свойств элементов инфоблока. В форме фильтра используются поля различного типа. Тип полей формы (например: text, select, checkbox ) зависит от типа свойства элемента инфоблока.
При нажатии кнопки «Фильтр» данные методом POST передаются странице, на которой расположен компонент, выводящий список элементов инфоблока. Этот компонент и будет показывать результаты работы фильтра.
К URL страницы добавляется GET-параметр use_filter=y , который указывает, что фильтр активен. Параметры для фильтрации элементов сохраняются в пользовательских параметрах ( elfilter и curFilterParams ). Это нужно для обеспечения корректной работы фильтра, если отфильтрованные элементы не помещаются на одну страницу.
Для показа отфильтрованных элементов я решил использовать компонент bitrix:news.list, указав в параметрах его вызова фильтр ( $arParams[«FILTER_NAME»] => «arrElementsFilter» ). В массив $arrElementsFilter я поместил данные, переданные из формы, предварительно обработал их и привел в определенный формат.
В принципе оба компонента (фильтр и список элементов) можно разместить на одной странице.
Ниже приведена схема работы компонента mattweb:elfilter.

Параметры компонента mattweb:elfilter
Как известно, у любого компонента в системе «1С-Битрикс» есть определенный набор папок и файлов из которых он, собственно, и состоит. Но о них я напишу немного позже, а сейчас начну с описания параметров моего компонента. Параметры компонента в системе «1С-Битрикс» хранятся в файле .parameters.php в папке компонента в массиве $arComponentParameters . Этот массив имеет определенную структуру и описывает параметры компонента. Параметры моего компонента немного «выбиваются» из этой структуры, поэтому я этот файл создавать не буду, благо он необязательный. Это никак не отобразиться на работе компонента, так как параметры в него будут передаваться при вызове компонента на страницах сайта. Мне нужно чтобы компонент присутствовал на каждой странице, поэтому я разместил его вызов в файле шаблона сайта. Вот так выглядит код вызова моего компонента.
$APPLICATION->IncludeComponent("mattweb:elfilter", ".default", Array( "IBLOCK_TYPE" => "books", // Тип информационного блока (используется только для проверки) "IBLOCK_ID" => "6", // Код информационного блока "ACTION_URL" => " /filtered.php", "USE_SECTION_FILTER" => "Y", // Фильтровать по разделам "ARR_PROPERTIES" => Array( "AUTHORS" => Array( "PROP_NAME" => "Автор(ы)", "PROP_ID" => "AUTHORS", "PROP_TYPE" => "E", "LNKD_IBLOCK_ID" => "5", "FLTFIELD_TYPE" => "ISM" ), "PUBLISHER" => Array( "PROP_NAME" => "Издатель", "PROP_ID" => "PUBLISHER", "PROP_TYPE" => "S", "FLTFIELD_TYPE" => "IS" ), "BK_PRICE" => Array( "PROP_NAME" => "Цена", "PROP_ID" => "BK_PRICE", "PROP_TYPE" => "N", "FLTFIELD_TYPE" => "ISL" ), "PAGES" => Array( "PROP_NAME" => "Число страниц", "PROP_ID" => "PAGES", "PROP_TYPE" => "N", "FLTFIELD_TYPE" => "ISR", "RNG_PARTS" => "5" ), "RENT_SELL" => Array( "PROP_NAME" => "Прокат/Продажа", "PROP_ID" => "RENT_SELL", "PROP_TYPE" => "L", "FLTFIELD_TYPE" => "IR" ), "IMAGES_SECTION" => Array( "PROP_NAME" => "Иллюстрации", "PROP_ID" => "IMAGES_SECTION", "PROP_TYPE" => "G", "FLTFIELD_TYPE" => "ISM" ), ), ), false );Ну вот, теперь самое время описать все элементы массива $arParams .
- IBLOCK_ID – идентификатор инфоблока, элементы которого будут фильтроваться;
- ACTION_URL – URL страницы, на которую будут отправляться параметры фильтра;
- USE_SECTION_FILTER - включить возможность фильтрации элементов по разделам (секциям)
- ARR_PROPERTIES – массив с данными о свойствах элементов и соответствующих им полях в форме фильтра. Каждый элемент массива описывает поле в фильтре. Важно: для корректной работы компонента имена ключей массива ARR_PROPERTIES должны соответствовать именам свойств в инфоблоке;
- PROP_NAME – текст подписи к полю в форме (название поля). Равен названию свойства в инфоблоке;
- PROP_ID – идентификатор свойства в инфоблоке;
- PROP_TYPE – тип свойства в инфоблоке (S - строка, N - число, F - файл, L - список, E - привязка к элементам, G - привязка к группам);
- FLTFIELD_TYPE – тип поля в форме фильтра;
Параметр «тип поля в форме фильтра» был придуман для того, чтобы иметь возможность в зависимости от его значения размещать в форме различные типы HTML-элементы (например, текстовые поля, списки, списки с множественным выбором, слайдеры, чекбоксы и тп). У этого параметра есть определенный список значений.
- IT – текстовое поле;
- IS – выпадающий список (select);
- ISM – выпадающий список, с возможностью выбора нескольких элементов;
- ISL – слайдер (реализован на основе jQuery noUiSlider);
- ISR – выпадающий список, значения которого представляют равные промежутки (например, 1-10, 11-20, 21-30 и тд);
- ICH – флажки (checkbox);
- IR – флажки (radio);
Файлы компонента

Мой компонент состоит из следующих файлов:
В папке js/ находятся файлы плагина jQuery noUiSlider, который необходим мне для размещения слайдера в форме.
Папка templates/.default/ содержит шаблон компонента. В ней 3 файла – сам шаблон (template.php), файл стилей (style.css) и файл component_epilog.php, который служит для подключения плагина jQuery noUiSlider.
В папке компонента находится файл component.php, который содержит весь код моего компонента. Вообще-то в этой папке еще могут быть 2 файла - .parameters.php, о котором я писал выше и .description.php – в котором хранится массив с описанием компонента. В моем случае эти файлы мне не нужны, в том числе, потому что я не собираюсь размещать компонент на страницах сайта с помощью визуального редактора.
Код компонента
Код компонента, находящийся в файле component.php разделен на блоки. По логике своей работы они аналогичны, поэтому я расскажу только про один блок, а с остальными можно ознакомиться заглянув в код компонента. Ничего сложного в нем нет. Но для начала нужно обработать входные параметры, передаваемые в компонент.
if(!CModule::IncludeModule('iblock')) < showError("Не установлен модуль Инфоблоки"); >global $USER; $arParams["IBLOCK_ID"] = intVal($arParams["IBLOCK_ID"]); $arParams["ACTION_URL"] = trim($arParams["ACTION_URL"])."?use_filter=y"; $arResult = Array();В самом начале файла подключаем модуль «Информационные блоки». После этого нам становятся доступны все методы его классов. Преобразуем идентификатор инфоблока в число и избавляемся от лишних пробелов в URL страницы с компонентом, выводящим результаты работы фильтра. Помните, я писал о ней выше? Да-да, той самой с компонентом bitrix:news.list.
Затем создаем пустой массив $arResult для хранения результатов работы компонента. Результатом работы компонента станет HTML-код отдельных полей формы фильтра, который будет «превращаться» в форму в шаблоне компонента. Итак, если в параметрах переданы какие-нибудь данные о свойствах и полях, начинаем обходить их в цикле и в зависимости от типа свойств и типа полей, обрабатываем их и сохраняем результат работы в массиве $arResult["FIELDS"] , каждый элемент отдельно.
Если пользователь выбрал параметры для фильтрации и отправил данные из формы - обрабатываем данные и сохраняем их для дальнейшего использования. На случай если в отфильтрованных результатах будет несколько страниц.
Храниться эти данные будут в параметрах пользователя.
if($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST["filter_send"]))< $arrElementsFilter = Array(); foreach($_POST as $key=>$val) < if($key == "SECTIONS" && !in_array("-", $_POST["SECTIONS"]))< // фильтр по секциям (массив) $arrElementsFilter["SECTION_ID"] = $_POST["SECTIONS"]; >else if((strpos($key, "PROPERTY_") !== false && !is_array($val) && $val != "-" && $val != "") || (strpos($key, "PROPERTY_") !== false && is_array($val) && !in_array("-", $val))) < // фильтр по свойствам $filterPropName = substr_replace($key, '', 0, strlen("PROPERTY_")); if(array_key_exists($filterPropName, $arParams["ARR_PROPERTIES"]))< // получаем тип поля фильтра $filterFieldType = $arParams["ARR_PROPERTIES"][$filterPropName]["FLTFIELD_TYPE"]; switch ($filterFieldType)< case "IT": $arrElementsFilter["$key"] = "%".$val."%"; break; case "IS": $arrElementsFilter["$key"] = $val; break; case "ISM": if(is_array($val) && count($val) >0) < $arrElementsFilter[] = Array( "LOGIC" =>"OR", array("$key" => $val) ); > break; case "ISL": $rngpattern = "/^[0-9]+\-[0-9]+$/"; if(preg_match($rngpattern, $val))< $arrVals = explode("-",$val); $arrElementsFilter["> break; case "ISR": $rngpattern = "/^[0-9]+\-[0-9]+$/"; if(preg_match($rngpattern, $val))< $arrVals = explode("-",$val); $arrElementsFilter["> break; case "ICH": if(is_array($val) && count($val) > 0) < $arrElementsFilter[] = Array( "LOGIC" =>"OR", array("$key" => $val) ); > break; case "IR": $arrElementsFilter["$key"] = $val; break; > > > > $USER->SetParam('elfilter', $arrElementsFilter); $USER->SetParam('curFilterParams', $_POST); > if(isset($_GET["use_filter"]) && $_GET["use_filter"] == "y")< $arrFilterCurParams = $USER->GetParam('curFilterParams'); >Предварительно очищаем параметры пользователя от предыдущих параметров фильтра. Делаем это в обоих случаях и при получении параметров для фильтра из формы, и при отключении фильтра - «очистке» элементов от фильтра.
if($_SERVER["REQUEST_METHOD"] == "POST" && (isset($_POST["filter_send"]) || isset($_POST["filter_reset"])))< $USER->SetParam('elfilter', ''); $USER->SetParam('curFilterParams', ''); >Переходим к описанию блока с кодом. Для примера я взял блок, работающий с текстовым свойством инфоблока.
… elseif($arProp["PROP_TYPE"] == "S") < //строка $arpropvals = Array(); $propcd = "PROPERTY_".strtoupper($arProp["PROP_ID"]); $arSelect = Array("ID", $propcd); $arFilter = Array( "IBLOCK_ID" =>$arParams["IBLOCK_ID"], "INCLUDE_SUBSECTION" => "Y" ); $res = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect); while($ob = $res->GetNextElement())< $arFlds = $ob->GetFields(); if(!in_array($arFlds[$propcd."_VALUE"], $arpropvals)) < $arpropvals[$arFlds[$propcd."_VALUE_ID"]] = $arFlds[$propcd."_VALUE"]; >> if(count($arpropvals) > 0) < asort($arpropvals); if($arProp["FLTFIELD_TYPE"] == "IS" || $arProp["FLTFIELD_TYPE"] == "ISM")< //select $fld_html = ''; > else< // input type="text" $fld_html = ''; > $arResult["FIELDS"][] = Array( "FLDNAME" => $arProp["PROP_NAME"], "PROPTYPE" => $arProp["PROP_TYPE"], "FIELDTYPE" => $arProp["FLTFIELD_TYPE"], "VALUE" => $arpropvals, "FLD_HTML" => $fld_html ); > else < $arResult["ERRORS"][] = "У свойства ".$arProp["PROP_ID"]." нет значений для фильтра"; >> …Итак, сначала получаем все значения свойства элементов инфоблока и сохраняем их в массив с именем $arpropvals . Ключами у элементов массива будут идентификаторы элементов инфоблока. Если значения есть и массив непустой, сортируем его, сохраняя ключи. Затем в зависимости от параметра типа поля (IS или ISM) в форме формируем HTML-код и сохраняем результат в массиве $arResult["FIELDS"] . Как видите, ничего сложного нет. Аналогично устроены и другие блоки кода, обрабатывающие другие типы полей.
Чтобы понять, как формируется HTML-код чекбоксов и радио-кнопок, ознакомьтесь с блоком кода, обрабатывающим свойства типа «Список».
Подключение плагина jQuery noUiSlider для создания слайдера в форме
В блоке кода, работающего в полем типа слайдер, формируется HTML-код, необходимый для корректной работы плагина jQuery noUiSlider. Подключение плагина происходит в файле component_epilog.php в обход кэширования.
Подробнее ознакомиться с кодом можно в файле component.php (строки 347-383).
Вызов плагина производится в шаблоне компонента, параметры берутся из архива $arResult .
Настройки инфоблока для демонстрации работы компонента
Для демонстрации работы компонента в демо-версии сайта, необходимо добавить новые свойства в информационный блок «Книги» (Тип – «Каталог книг»). Это нужно для большей наглядности. На рисунке ниже показаны эти свойства, их имена и типы.
Значения свойства BK_PRICE, являются ценами товаров каталога. Тип - «Число».
Значения свойства RENT_SELL, являющиеся элементами списка, будут следующие: первый элемент - «Продажа», второй элемент списка - «Прокат». Выбрать можно только один элемент.
Значения свойства IMAGES_SECTION, берутся из инфоблока «Фотографии» (тип - «Фотогалерея»).
После создания свойств, вы можете импортировать данные из .CSV-файла в информационный блок или заполнить их вручную.
Размещение компонента на странице сайта
Переходим к заключительной части статьи, а именно, к размещению компонента на странице. Немного отступлю от выше приведенной схемы и размещу оба компонента (и фильтр и список результатов) на одной странице (filtered.php). По логике работы компонента, при активном фильтре в полях формы должны находиться выбранные ранее значения. Создайте страницу с именем filtered.php в корне демо-сайта и разместите там следующий код:
SetTitle("фильтр"); ?> IncludeComponent("mattweb:elfilter", ".default", Array( "IBLOCK_TYPE" => "books", // Тип информационного блока (используется только для проверки) "IBLOCK_ID" => "6", // Код информационного блока "ACTION_URL" => " /filtered.php", "USE_SECTION_FILTER" => "Y", // Фильтровать по разделам "ARR_PROPERTIES" => Array( "AUTHORS" => Array( "PROP_NAME" => "Автор(ы)", "PROP_ID" => "AUTHORS", "PROP_TYPE" => "E", "LNKD_IBLOCK_ID" => "5", "FLTFIELD_TYPE" => "ISM" ), "PUBLISHER" => Array( "PROP_NAME" => "Издатель", "PROP_ID" => "PUBLISHER", "PROP_TYPE" => "S", "FLTFIELD_TYPE" => "IS" ), "BK_PRICE" => Array( "PROP_NAME" => "Цена", "PROP_ID" => "BK_PRICE", "PROP_TYPE" => "N", "FLTFIELD_TYPE" => "ISL" ), "PAGES" => Array( "PROP_NAME" => "Число страниц", "PROP_ID" => "PAGES", "PROP_TYPE" => "N", "FLTFIELD_TYPE" => "ISR", "RNG_PARTS" => "5" ), "RENT_SELL" => Array( "PROP_NAME" => "Прокат/Продажа", "PROP_ID" => "RENT_SELL", "PROP_TYPE" => "L", "FLTFIELD_TYPE" => "IR" ), "IMAGES_SECTION" => Array( "PROP_NAME" => "Иллюстрации", "PROP_ID" => "IMAGES_SECTION", "PROP_TYPE" => "G", "FLTFIELD_TYPE" => "ISM" ), ), ), false ); $arrElementsFilter = (isset($_GET['use_filter'])) ? $USER->GetParam('elfilter') : ""; $pagerBaseLink = (isset($_GET['use_filter'])) ? $APPLICATION->GetCurPage()."?use_filter=y" : ""; if(!isset($_GET['use_filter']))< $USER->SetParam('elfilter', ''); > $APPLICATION->IncludeComponent("bitrix:news.list", "filtered", array( "IBLOCK_TYPE" => "books", "IBLOCK_ID" => "6", "NEWS_COUNT" => "5", "SORT_BY1" => "ACTIVE_FROM", "SORT_ORDER1" => "DESC", "SORT_BY2" => "SORT", "SORT_ORDER2" => "ASC", "FILTER_NAME" => "arrElementsFilter", "FIELD_CODE" => array( 0 => "", 1 => "", ), "PROPERTY_CODE" => array( 0 => "PAGES", 1 => "PUBLISHER", 2 => "RENT_SELL", 3 => "BK_PRICE", 4 => "IMAGES_SECTION", 5 => "AUTHORS", 6 => "", ), "CHECK_DATES" => "Y", "DETAIL_URL" => "", "AJAX_MODE" => "N", "AJAX_OPTION_JUMP" => "N", "AJAX_OPTION_STYLE" => "Y", "AJAX_OPTION_HISTORY" => "N", "CACHE_TYPE" => "N", "CACHE_TIME" => "36000000", "CACHE_FILTER" => "N", "CACHE_GROUPS" => "Y", "PREVIEW_TRUNCATE_LEN" => "", "ACTIVE_DATE_FORMAT" => "d.m.Y", "SET_TITLE" => "Y", "SET_STATUS_404" => "N", "INCLUDE_IBLOCK_INTO_CHAIN" => "Y", "ADD_SECTIONS_CHAIN" => "Y", "HIDE_LINK_WHEN_NO_DETAIL" => "N", "PARENT_SECTION" => "", "PARENT_SECTION_CODE" => "", "INCLUDE_SUBSECTIONS" => "Y", "PAGER_TEMPLATE" => ".default", "DISPLAY_TOP_PAGER" => "N", "DISPLAY_BOTTOM_PAGER" => "Y", "PAGER_BASE_LINK_ENABLE" => "Y", "PAGER_BASE_LINK" => $pagerBaseLink, "PAGER_TITLE" => "Элементы", "PAGER_SHOW_ALWAYS" => "Y", "PAGER_DESC_NUMBERING" => "N", "PAGER_DESC_NUMBERING_CACHE_TIME" => "36000", "PAGER_SHOW_ALL" => "Y", "DISPLAY_DATE" => "Y", "DISPLAY_NAME" => "Y", "DISPLAY_PICTURE" => "Y", "DISPLAY_PREVIEW_TEXT" => "Y", "AJAX_OPTION_ADDITIONAL" => "" ), false ); ?>Как вы видите, на странице подключаются 2 компонента: mattweb.elfilter (фильтр) и bitrix:news.list (список новостей).
Если фильтр активен, получаем значения для фильтрации элементов из параметра пользователя elfilter и передаем этот массив в компонент bitrix:news.list. Кроме того, формируем правильные ссылки для постраничной навигации.
Иначе очищаем параметр пользователя elfilter и показываем полный список элементов.
Обращаю ваше внимание, что значения параметров в вызове компонентов указаны для демо-версии системы.
Если все сделано правильно, то на указанная страница будет выглядеть так, как на рисунке ниже.
Добавляем возможность фильтровать по разделам (добавлено 26.08.2015)
В компоненте добавлена возможность фильтровать элементы инфоблока по разделам. Для этого я немного изменил файлы компонента. В приведенных выше примерах кода эти изменения учтены.
Также необходимо добавить в файл component.php следующий код:
$arResult["FIELDS"] = Array(); // фильтр по секциям if(isset($arParams["USE_SECTION_FILTER"]) && $arParams["USE_SECTION_FILTER"] == "Y") < $arSectFilter = Array( "IBLOCK_ID" =>$arParams["IBLOCK_ID"], "GLOBAL_ACTIVE" => "Y" ); // Если у инфоблока есть секции if(CIBlockSection::GetCount($arSectFilter) > 0) < $arrSections = Array(); $dbSectList = CIBlockSection::GetList(Array("SORT" =>"ASC"), $arSectFilter, false, Array("ID","NAME")); // получаем список секций инфоблока (массив "ИД_РАЗДЕЛА" => "Название раздела") while($tmpSectArr = $dbSectList->Fetch()) < $arrSections[$tmpSectArr["ID"]] = $tmpSectArr["NAME"]; >// Формируем html на основе данных и добавляем его в $arResult["FIELDS"] $fld_html = ''; $arResult["FIELDS"][] = Array( "FLDNAME" => "Разделы", "FIELDTYPE" => "ISM", "VALUE" => $arrSections, "FLD_HTML" => $fld_html ); > >Этот код вставляется между следующими строками:
… // URL для отправки формы $arResult["ACTION_URL"] = $arParams["ACTION_URL"]; /* сюда вставляется приведенный выше код причем строку $arResult["FIELDS"] = Array(); нужно перенести сюда из условного блока с проверкой (count($arParams["ARR_PROPERTIES"]) > 0) */ if(count($arParams["ARR_PROPERTIES"]) > 0) …В результате этих действий в фильтре добавляется список с возможность выбора нескольких категорий для фильтрации элементов инфоблока.
Обновление и доработки в компоненте mattweb.elfilter (добавлено 11.01.2016)
- Добавлена возможность использования в фильтре чекбоксов ( input type="checkbox" ) и радио-кнопок ( input type="radio" ) для свойств типа «Список» (L);
- Добавлена возможность выбора нескольких элементов из списка для свойств типа «Привязка к группам» (G);
- У всех выпадающих списков в фильтре добавлена возможность выбора пустых значений;
- Кнопка «Очистить» в форме фильтра теперь отключает фильтр. При клике по ней, страница обновляется и на ней показываются все элементы.
- Исправлена ошибка: постраничная навигация при активном фильтре работала некорректно.
- Исправлена ошибка: при использовании постраничной навигации при активном фильтре в форме не выделялись значения по которым происходила фильтрация.
Использование фильтра mattweb.elfilter в комплексном компоненте (добавлено 02.07.2016)
Добавлена возможность использования фильтра внутри комплексного компонента. Проверено на компоненте «Каталог» ( bitrix:catalog ) тестовой версии CMS(редакция «Стандарт»).
Для работы внутри комплексного компонента необходимо изменить значение некоторых параметров, а также добавить 1 новый.
Я заменил вызов «умного» фильтра в файле section_vertical.php шаблона компонента «Каталог» ( bitrix:catalog ) своим.
Дефолтный шаблон компонента «Каталог» ( bitrix:catalog ) я предварительно скопировал в папку /bitrix/templates/.default/components/bitrix/catalog/.default/
Вы можете скачать измененные файлы для ознакомления.
Пример вызова компонента в файле section_vertical.php шаблона комплексного компонента «Каталог» ( bitrix:catalog )
IncludeComponent("mattweb:elfilter", ".default", Array( "IBLOCK_TYPE" => $arParams["IBLOCK_TYPE"], // Тип информационного блока (используется только для проверки) "IBLOCK_ID" => $arParams["IBLOCK_ID"], // Код информационного блока "ACTION_URL" => "", // в случае комплексного компонента оставляем параметр пустым "USE_SECTION_FILTER" => "", // в случае комплексного компонента оставляем параметр пустым, "SECTION_ID" => $arCurSection['ID'], // добавляем новый параметр для комплексного компонента "ARR_PROPERTIES" => $arParams["ARR_PROPERTIES"] ), false );?>В указанном файле значения параметров берутся из файла, где вызывается комплексный компонент «Каталог» ( bitrix:catalog ).
В демо-версии это файл /e-store/books/index.php . В нем параметры компонента добавлены в код вызова комплексного компонента.
Они выглядят аналогично как в вызове простого компонента (см. пример в статье выше)
Для ознакомления вы можете скачать архив с компонентом. Чтобы установить компонент разархивируйте загруженный архив в папку /bitrix/components/.
Также вы можете скачать архив с шаблоном (filtered) компонента bitrix:news.list и страницу filtered.php.
Умный фильтр 1С-Битрикс: умный, быстрый и красивый
До появления текущей версии главной головной болью была проблема с производительностью, а список задач на доработку повторялся чуть ли не на каждом проекте.
- привязка свойств к группам;
- не давать выбирать несовместимые опции (0-й результат);
- скрывать те значения свойств, которых нет у товаров в выбранном разделе.
Немного истории…
— Не стоит так гордиться этим технологическим монстром, что вы построили.
(с) Дарт Вейдер

Первая версия умного фильтра в БУС была тяжёлой, сложной и не всегда адекватной. Не каждый сайт мог позволить себе принять такого гостя. Идей по его улучшению у сообщества было хоть отбавляй.

Прошло несколько лет и теперь это совсем другой компонент.
Больше настроек отображения

В первой версии умного фильтра внешний вид свойств никак не настраивался. А в версии 2.0 появились следующие параметры:
- вид свойства в умном фильтре (флажки, радио-кнопки, ползунки);
- показать свойство свернутым или развернутым;
- текст подсказки к каждому свойству.
Вид в умном фильтре
Раньше свойства отображались только в виде флажков. Теперь стало возможным настраивать способ отображения свойств через настройку "Вид в умном фильтре".
Наборы способов отображения доступны в зависимости типов данных:
- Для типа данных справочник стали доступны следующие виды отображения:

- Тип данных число теперь отображается в виде ползунка

- Для типа строка настраиваются следующие виды отображения

Виды отображения задаются в настройках инфоблока 
Показывать развернутым

В умном фильтре свойства отображались развернуто: при количестве 20-100 значений конкретного свойства фильтр расползался на несколько экранов браузера и пользователю было трудно отыскать нужные параметры. Для решения этой проблемы вносились изменения в шаблон компонента. Теперь стала доступна такая настройка, с помощью которой настраивается развернутость свойства.
Подсказки

В настройках инфоблока появилась настройка текста подсказки для пользователей. Если свойство требует дополнительной информации, то это как раз тот случай, чтобы использовать эту настройку.
Страница управления отображением свойств
Если в инфоблоке содержится много свойств и возникают сложности с настройкой каждого из них — на помощь приходит специальная страница управления свойствами. Эта страница расположена в административном интерфейсе: Магазин > Продукция > Настройки каталога.
Здесь настраивается отображение в умном фильтре: выбирается в каком виде отображать свойство, как отображать и в каком порядке.
В "Настройки каталога" указываются свойства, которые выводятся во всех группах товаров. Однако если потребовалось задать для каждой группы товаров собственный набор свойств, то это теперь можно сделать в настройках магазина (Магазин > Продукция > Группы).

Настройки компонента

До выхода версии 2.0 умный фильтр работал только с торговыми каталогами. Никаких новостей и акций. Теперь можно настроить компонент на любой инфоблок.
Ползунок цен
В умном фильтре 1.0 контролы ползунка отображались круглыми и их нельзя было сузить вплотную, при этом диапазон суммы располагался в больших пределах. В версии 2.0 контролы доработали и, вместе с тем, доработали отображение диапазона цен в шаблоне умного фильтра.
У ползунка появилось четыре характерных цвета с собственными обозначениями:
- светло-зеленый - за диапазоном выбора имеются доступные товары;
- темно-зеленый - в выбранном диапазоне доступные товары;
- светло-серый - в диапазоне нет товаров;
- темно-серый - показывает сектор, в котором отсутствуют товары.
На скриншоте можно увидеть как отображается доступный диапазон цен.
Если в выбранном диапазоне расположен сектор с отсутствующими товарами, то он закрашивается серым цветом. 
Фильтрация по SKU
Появилась фильтрация товаров по свойствам и ценам SKU (торговых предложений). Однако это нововведение имеет недостатки в логике вариантов выбора - такие случаи были освещены в этой идее.
Конвертация валют
Конвертация валют, именуемая в параметрах комплексного компонента каталога как “Показывать цены в одной валюте” не происходила в умном фильтр. Таким образом, товар стоимостью 9$ отображался дешевле товара стоимостью 10 рублей. Теперь ошибка исправлена и конвертация цен происходит корректно и в каталоге и в умном фильтре.

Ускорение работы фильтра
Умный фильтр 1.0 после нажатия кнопки «Подобрать» перебирал все товары и сравнивал их свойства с искомыми. С ростом количества товаров и свойств сильно возрастала нагрузка на сайт и увеличивалось время ответа сайта.
Для ускорения придумали технологию «фасетный индекс». Она напоминает кэширование. Все товары один раз индексируются в отдельную таблицу БД (в фасет) и фильтрация проводится по этому быстрому и легкому «кэшу». Эта технология в 3-4 раза ускорила работу умного фильтра и снизила нагрузку на сервер.
Фасетный индекс включается одной кнопкой. Генерация занимает несколько минут, в зависимости от мощности сайта и размера каталога. Важно: каждый раз после добавления свойства инфоблока фасет устаревает и нужно его пересоздать вручную.
- Когда происходит добавление или редактирование разделов каталога.
- При добавлении или удаления свойства из умного фильтра.
- При выгрузке из 1С, если происходит обновление и добавление товаров с новыми свойствами.
Фильтр в карточке CRM
Фильтр в таймлайне элемента CRM позволяет быстро найти нужные документы, отфильтровать комментарии и другие события.
Допустим, вы работаете с крупными компаниями и переговоры могут длиться неделями или даже месяцами. И в какой-то момент вам понадобилось найти документ, который клиент присылал вам пару месяцев назад, например доверенность или какой-нибудь сертификат. Вы потратите много времени, если будете вручную искать его в таймлайне. А с помощью фильтра и поиска сможете сделать это за пару секунд.
Как работает фильтр?
Нажмите на кнопку Фильтр в карточке любого элемента CRM.

Откроется поисковая строка. Через строку поиска можно найти нужное событие по ключевому слову или его части.

Также откроется выпадающее меню с разными вариантами фильтров.

Стандартные фильтры облегчат поиск событий по типу.

Например, вы можете быстро найти все документы, которые относятся к данной сделке.

Или все комментарии по данному клиенту.

Выбранный фильтр сохраняется для конкретного элемента. К примеру, если вы выбрали фильтр комментарии и ожидание, то в следующий раз карточка откроется с этим же фильтром.
Используйте дополнительные поля, чтобы создать свой фильтр — например, поле дата, клиент или автор события. Чтобы выбрать нужный вариант нажмите Добавить поле.

После того как настоите поля, их можно сохранить как фильтр. Используйте его в других элементах без дополнительной настройки. Фильтр будет расположен в списке стандартных фильтров.

Фильтры можно удалять и редактировать. Для этого нажмите на Шестерёнку и выберете действие. Также вы можете закрепить любой фильтр как основной. Тогда, открыв элемент в следующий раз в таймлайне будет отображаться информация согласно закрепленному фильтру.

Кроме того, фильтр можно применить для всех пользователей CRM, выбрав соответствующую опцию. Воспользуйтесь этим вариантом, если хотите сохранить настройки фильтра для всех сотрудников в конкретном элементе CRM.




