Зачем нужен свой фильтр и почему бы не использовать стандартные?
В системе «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
. Этот массив имеет определенную структуру и описывает параметры компонента. Параметры моего компонента немного «выбиваются» из этой структуры, поэтому я этот файл создавать не буду, благо он необязательный. Это никак не отобразиться на работе компонента, так как параметры в него будут передаваться при вызове компонента на страницах сайта. Мне нужно чтобы компонент присутствовал на каждой странице, поэтому я разместил его вызов в файле шаблона сайта. Вот так выглядит код вызова моего компонента.
PHP
Ну вот, теперь самое время описать все элементы массива $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 разделен на блоки. По логике своей работы они аналогичны, поэтому я расскажу только про один блок, а с остальными можно ознакомиться заглянув в код компонента. Ничего сложного в нем нет. Но для начала нужно обработать входные параметры, передаваемые в компонент.
PHP
В самом начале файла подключаем модуль «Информационные блоки». После этого нам становятся доступны все методы его классов. Преобразуем идентификатор инфоблока в число и избавляемся от лишних пробелов в URL страницы с компонентом, выводящим результаты работы фильтра. Помните, я писал о ней выше? Да-да, той самой с компонентом bitrix:news.list.
Затем создаем пустой массив $arResult
для хранения результатов работы компонента. Результатом работы компонента станет HTML-код отдельных полей формы фильтра, который будет «превращаться» в форму в шаблоне компонента. Итак, если в параметрах переданы какие-нибудь данные о свойствах и полях, начинаем обходить их в цикле и в зависимости от типа свойств и типа полей, обрабатываем их и сохраняем результат работы в массиве $arResult["FIELDS"]
, каждый элемент отдельно.
Если пользователь выбрал параметры для фильтрации и отправил данные из формы - обрабатываем данные и сохраняем их для дальнейшего использования. На случай если в отфильтрованных результатах будет несколько страниц.
Храниться эти данные будут в параметрах пользователя.
PHP
Предварительно очищаем параметры пользователя от предыдущих параметров фильтра. Делаем это в обоих случаях и при получении параметров для фильтра из формы, и при отключении фильтра - «очистке» элементов от фильтра.
PHP
Переходим к описанию блока с кодом. Для примера я взял блок, работающий с текстовым свойством инфоблока.
PHP
Итак, сначала получаем все значения свойства элементов инфоблока и сохраняем их в массив с именем $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 в корне демо-сайта и разместите там следующий код:
PHP
Как вы видите, на странице подключаются 2 компонента: mattweb.elfilter (фильтр) и bitrix:news.list (список новостей).
Если фильтр активен, получаем значения для фильтрации элементов из параметра пользователя elfilter
и передаем этот массив в компонент bitrix:news.list. Кроме того, формируем правильные ссылки для постраничной навигации.
Иначе очищаем параметр пользователя elfilter
и показываем полный список элементов.
Обращаю ваше внимание, что значения параметров в вызове компонентов указаны для демо-версии системы.
Если все сделано правильно, то на указанная страница будет выглядеть так, как на рисунке ниже.
Добавляем возможность фильтровать по разделам (добавлено 26.08.2015)
В компоненте добавлена возможность фильтровать элементы инфоблока по разделам. Для этого я немного изменил файлы компонента. В приведенных выше примерах кода эти изменения учтены.
Также необходимо добавить в файл component.php следующий код:
PHP
Этот код вставляется между следующими строками:
PHP
В результате этих действий в фильтре добавляется список с возможность выбора нескольких категорий для фильтрации элементов инфоблока.
Обновление и доработки в компоненте 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)
PHP
В указанном файле значения параметров берутся из файла, где вызывается комплексный компонент «Каталог» (bitrix:catalog
).
В демо-версии это файл /e-store/books/index.php. В нем параметры компонента добавлены в код вызова комплексного компонента.
Они выглядят аналогично как в вызове простого компонента (см. пример в статье выше)
Для ознакомления вы можете скачать архив с компонентом. Чтобы установить компонент разархивируйте загруженный архив в папку /bitrix/components/.
Также вы можете скачать архив с шаблоном (filtered) компонента bitrix:news.list и страницу filtered.php.