Матвей Земсков

Заметки веб-мастера

Воскресенье, 26 января 2014 10:01

Создаем свой фильтр на сайте под управлением «1С-Битрикс»

Оцените материал
(16 голосов)

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

Зачем нужен свой фильтр и почему бы не использовать стандартные?

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

Фильтры в 1С-Битрикс

Конечно, можно было бы попытаться настроить под себя имеющиеся фильтры, но я решил не «заморачиваться» с настройками, потому что был не уверен в результате, а зря тратить время мне не хотелось. В итоге я решил написать свой компонент. Я назвал его 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

Параметры компонента mattweb:elfilter

Как известно, у любого компонента в системе «1С-Битрикс» есть определенный набор папок и файлов из которых он, собственно, и состоит. Но о них я напишу немного позже, а сейчас начну с описания параметров моего компонента. Параметры компонента в системе «1С-Битрикс» хранятся в файле .parameters.php в папке компонента в массиве $arComponentParameters. Этот массив имеет определенную структуру и описывает параметры компонента. Параметры моего компонента немного «выбиваются» из этой структуры, поэтому я этот файл создавать не буду, благо он необязательный. Это никак не отобразиться на работе компонента, так как параметры в него будут передаваться при вызове компонента на страницах сайта. Мне нужно чтобы компонент присутствовал на каждой странице, поэтому я разместил его вызов в файле шаблона сайта. Вот так выглядит код вызова моего компонента.

PHP

$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);

Файлы компонента

Файлы компонента mattweb:elfilter

Мой компонент состоит из следующих файлов:

В папке 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

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"], каждый элемент отдельно.

Если пользователь выбрал параметры для фильтрации и отправил данные из формы - обрабатываем данные и сохраняем их для дальнейшего использования. На случай если в отфильтрованных результатах будет несколько страниц.

Храниться эти данные будут в параметрах пользователя.

PHP

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["><$key"] = $arrVals;
						}
					break;
					case "ISR":
						$rngpattern = "/^[0-9]+\-[0-9]+$/";
						if(preg_match($rngpattern, $val)){
							$arrVals = explode("-",$val);
							$arrElementsFilter["><$key"] = $arrVals;
						}
					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');
}

Предварительно очищаем параметры пользователя от предыдущих параметров фильтра. Делаем это в обоих случаях и при получении параметров для фильтра из формы, и при отключении фильтра - «очистке» элементов от фильтра.

PHP

if($_SERVER["REQUEST_METHOD"] == "POST" && (isset($_POST["filter_send"]) || isset($_POST["filter_reset"]))){
	$USER->SetParam('elfilter', '');
	$USER->SetParam('curFilterParams', '');
}

Переходим к описанию блока с кодом. Для примера я взял блок, работающий с текстовым свойством инфоблока.

PHP

…
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 = '<select name="PROPERTY_'.$arProp["PROP_ID"];
					if($arProp["FLTFIELD_TYPE"] == "ISM") $fld_html .= '[]" multiple = "multiple" size="5">';
					if($arProp["FLTFIELD_TYPE"] == "IS") {
						$fld_html .= '">';						
					}
					$fld_html .= '<option value="-">-</option>';
					foreach($arpropvals as $key => $value){
						if(empty($key) || empty($value)) continue;
						if(array_key_exists("PROPERTY_".$arProp["PROP_ID"], $arrFilterCurParams) && $arrFilterCurParams["PROPERTY_".$arProp["PROP_ID"]] == $value)
						{
							$fld_html .= '<option value="'.$value.'" selected="selected">'.$value.'</option>';
						}
						else
						{
							$fld_html .= '<option value="'.$value.'">'.$value.'</option>';
						}						
					}
					$fld_html .= '</select>';
				}
				else{
					// input type="text"
					$fld_html = '<input type="text" name="PROPERTY_'.$arProp["PROP_ID"].'" id="fld_'.$arProp["PROP_ID"].'"/>';
				}			
								
				$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 в корне демо-сайта и разместите там следующий код:

PHP

<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
$APPLICATION->SetTitle("фильтр");
?>
<?
// компонент фильтр
$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
); 

$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
	);
?>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>

Как вы видите, на странице подключаются 2 компонента: mattweb.elfilter (фильтр) и bitrix:news.list (список новостей).

Если фильтр активен, получаем значения для фильтрации элементов из параметра пользователя elfilter и передаем этот массив в компонент bitrix:news.list. Кроме того, формируем правильные ссылки для постраничной навигации.

Иначе очищаем параметр пользователя elfilter и показываем полный список элементов.

Обращаю ваше внимание, что значения параметров в вызове компонентов указаны для демо-версии системы.

Если все сделано правильно, то на указанная страница будет выглядеть так, как на рисунке ниже.

Страница с компонентами

Добавляем возможность фильтровать по разделам (добавлено 26.08.2015)

В компоненте добавлена возможность фильтровать элементы инфоблока по разделам. Для этого я немного изменил файлы компонента. В приведенных выше примерах кода эти изменения учтены.

Также необходимо добавить в файл component.php следующий код:

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 = '<select name="SECTIONS[]" multiple = "multiple" size="5">';
		$fld_html .= '<option value="-">-</option>';
		foreach($arrSections as $key => $value){
			if(array_key_exists("SECTIONS", $arrFilterCurParams) && in_array($key, $arrFilterCurParams["SECTIONS"]))
			{
				$fld_html .= '<option value="'.$key.'" selected="selected">'.$value.'</option>';
			}
			else{
				$fld_html .= '<option value="'.$key.'">'.$value.'</option>';
			}			
		}
		$fld_html .= '</select>';
		
		$arResult["FIELDS"][] = Array(
			"FLDNAME" => "Разделы",
			"FIELDTYPE" => "ISM",
			"VALUE" => $arrSections,
			"FLD_HTML" => $fld_html
		);		
	}
}

Этот код вставляется между следующими строками:

PHP

…
// 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)

PHP

<?
	// компонент фильтр mattweb:elfilter
	$APPLICATION->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.

Прочитано 74462 раз
Мои услуги

Предлагаю следующие услуги:

  • Верстка шаблона сайта из дизайн-макета для CMS «1С-Битрикс Управление сайтом» и CMS “Joomla”
  • Создание форм различной сложности (обратная связь, анкеты и тп) для указанных CMS
  • Настройка и кастомизация компонентов и модулей для указанных CMS
  • Доработка модулей и компонентов для указанных CMS, добавление нестандартного функционала
  • Разработка лендингов (landing-pages)

По все вопросам обращайтесь через форму обратной связи

Скачать

Предлагаю вашему вниманию:

Наверх