Публикую решение такой задачи:
В инфоблоке 2 числовых свойства – «Минимальная длина» и «Максимальная длина»
Выводить в фильтре нужно одно свойство «Длина».
Генерировать множество промежуточных значений для множественного св-ва скриптом – не выход, так как создаст слишком большое кол-во избыточных данных в БД и утяжелит работу фильтра.
Решение: сделать фейковое свойство в шаблоне фильтра, используя тот же js контрол для диапазона, что используется для подобных свойств. Реальные св-ва, по которым будет работать фильтр спрятать стилями. Левый ползунок св-ва «Длина» будет устанавливать значение «До» для св-ва «Минимальная длина», правый ползунок св-ва «Длина» будет устанавливать значение «От» для св-ва «Максимальная длина»
Реализация:
catalog.smart.filter - template.php:
1. Где-то вначале объявляем. Сюда же подставлять свои значения.
Код |
---|
$rangeProperty = [
"NAME" => "Длина",
"MINIMAL_VALUE_PROPERTY_CODE" => "MINIMALNAYA_DLINA",
"MAXIMUM_VALUE_PROPERTY_CODE" => "MAKSIMALNAYA_DLINA",
]; |
2. Внутри цикла foreach после «// not prices» перед первым div
(собираем данные у реальных свойств для использования их в фейковом)
Код |
---|
$isRangeRealProperty = false;
if ($arItem["DISPLAY_TYPE"] == "A" && is_array($rangeProperty))
{
if ($rangeProperty["MINIMAL_VALUE_PROPERTY_CODE"] == $arItem["CODE"])
{
$rangeProperty["MINIMAL_VALUE"] = $arItem["VALUES"]["MIN"]["VALUE"];
$rangeProperty["MINIMAL_HTML_VALUE"] = $arItem["VALUES"]["MAX"]["HTML_VALUE"];
$rangeProperty["MINIMAL_FILTERED_VALUE"] = $arItem["VALUES"]["MIN"]["FILTERED_VALUE"];
$rangeProperty["LEFT_VALUE_MAX"] = $arItem["VALUES"]["MAX"]["VALUE"];
$rangeProperty["LEFT_VALUE_REAL_PROPERTY_ID"] = $arItem["VALUES"]["MAX"]["CONTROL_ID"];
$isRangeRealProperty = true;
}
elseif ($rangeProperty["MAXIMUM_VALUE_PROPERTY_CODE"] == $arItem["CODE"])
{
$rangeProperty["MAXIMUM_VALUE"] = $arItem["VALUES"]["MAX"]["VALUE"];
$rangeProperty["MAXIMUM_HTML_VALUE"] = $arItem["VALUES"]["MIN"]["HTML_VALUE"];
$rangeProperty["MAXIMUM_FILTERED_VALUE"] = $arItem["VALUES"]["MAX"]["FILTERED_VALUE"];
$rangeProperty["RIGHT_VALUE_MAX"] = $arItem["VALUES"]["MIN"]["VALUE"];
$rangeProperty["RIGHT_VALUE_REAL_PROPERTY_ID"] = $arItem["VALUES"]["MIN"]["CONTROL_ID"];
$isRangeRealProperty = true;
}
} |
3. Сразу после у первого div с классом «bx_filter_parameters_box» добавляем (скрываем реальные св-ва)
Код |
---|
if($isRangeRealProperty):?> style="display:none"<?endif?> |
4. Сразу после switch перед закрытием цикла foreach (выводим фейковое поле с js битрикса для диапазонов и своим js для обработки изменения фейкового свойства)
Код |
---|
<?
if (is_array($rangeProperty) && isset($rangeProperty["MINIMAL_VALUE"]) && isset($rangeProperty["MAXIMUM_VALUE"]))
{
$rangePropertyId = rand();
$rangeProperty["DISPLAY_EXPANDED"] = $rangeProperty["MINIMAL_HTML_VALUE"] || $rangeProperty["MAXIMUM_HTML_VALUE"];
?>
<div class="bx_filter_parameters_box filter-range-property<?if ($rangeProperty["DISPLAY_EXPANDED"]):?> active<?endif?>">
<span class="bx_filter_container_modef"></span>
<div class="bx_filter_parameters_box_title" oncl ick="smartFilter.hideFilterProps(this)"><?=$rangeProperty["NAME"]?><i class="fa"></i></div>
<div class="bx_filter_block">
<div class="bx_filter_parameters_box_container">
<div class="bx_filter_parameters_box_container_block">
<div class="bx_filter_input_container">
<input
class="min-price"
type="text"
id="range-property-field-<?=$rangePropertyId?>-min"
value="<?=$rangeProperty["MINIMAL_HTML_VALUE"]?>"
data-max="<?=$rangeProperty["LEFT_VALUE_MAX"]?>"
data-real-id="<?=$rangeProperty["LEFT_VALUE_REAL_PROPERTY_ID"]?>"
/>
</div>
</div>
<div class="bx_filter_parameters_box_container_block">
<div class="bx_filter_input_container">
<input
class="max-price"
type="text"
id="range-property-field-<?=$rangePropertyId?>-max"
value="<?=$rangeProperty["MAXIMUM_HTML_VALUE"]?>"
data-min="<?=$rangeProperty["RIGHT_VALUE_MAX"]?>"
data-real-id="<?=$rangeProperty["RIGHT_VALUE_REAL_PROPERTY_ID"]?>"
/>
</div>
</div>
<div st yle="clear: both;"></div>
<div class="bx_ui_slider_track" id="drag_track_<?=$rangePropertyId?>">
<?
$value1 = $rangeProperty["MINIMAL_VALUE"];
$value2 = $rangeProperty["MINIMAL_VALUE"] + round(($rangeProperty["MAXIMUM_VALUE"] - $rangeProperty["MINIMAL_VALUE"])/4);
$value3 = $rangeProperty["MINIMAL_VALUE"] + round(($rangeProperty["MAXIMUM_VALUE"] - $rangeProperty["MINIMAL_VALUE"])/2);
$value4 = $rangeProperty["MINIMAL_VALUE"] + round((($rangeProperty["MAXIMUM_VALUE"] - $rangeProperty["MINIMAL_VALUE"])*3)/4);
$value5 = $rangeProperty["MAXIMUM_VALUE"];
?>
<div class="bx_ui_slider_part p1"><span><?=$value1?></span></div>
<div class="bx_ui_slider_part p2"><span><?=$value2?></span></div>
<div class="bx_ui_slider_part p3"><span><?=$value3?></span></div>
<div class="bx_ui_slider_part p4"><span><?=$value4?></span></div>
<div class="bx_ui_slider_part p5"><span><?=$value5?></span></div>
<div class="bx_ui_slider_pricebar_VD" st yle="left: 0;right: 0;" id="colorUnavailableActive_<?=$rangePropertyId?>"></div>
<div class="bx_ui_slider_pricebar_VN" st yle="left: 0;right: 0;" id="colorAvailableInactive_<?=$rangePropertyId?>"></div>
<div class="bx_ui_slider_pricebar_V" st yle="left: 0;right: 0;" id="colorAvailableActive_<?=$rangePropertyId?>"></div>
<div class="bx_ui_slider_range" id="drag_tracker_<?=$rangePropertyId?>" st yle="left: 0;right: 0;">
<a class="bx_ui_slider_handle left" style="left:0;" href="jav * ascript:void(0)" id="left_slider_<?=$rangePropertyId?>"></a>
<a class="bx_ui_slider_handle right" style="right:0;" href="jav * ascript:void(0)" id="right_slider_<?=$rangePropertyId?>"></a>
</div>
</div>
<?
$arJsParams = array(
"leftSlider" => 'left_slider_'.$rangePropertyId,
"rightSlider" => 'right_slider_'.$rangePropertyId,
"tracker" => "drag_tracker_".$rangePropertyId,
"trackerWrap" => "drag_track_".$rangePropertyId,
"minInputId" => "range-property-field-".$rangePropertyId."-min",
"maxInputId" => "range-property-field-".$rangePropertyId."-max",
"minPrice" => $rangeProperty["MINIMAL_VALUE"],
"maxPrice" => $rangeProperty["MAXIMUM_VALUE"],
"curMinPrice" => $rangeProperty["MINIMAL_HTML_VALUE"],
"curMaxPrice" => $rangeProperty["MAXIMUM_HTML_VALUE"],
"fltMinPrice" => intval($rangeProperty["MINIMAL_FILTERED_VALUE"]) ? $rangeProperty["MINIMAL_FILTERED_VALUE"] : $rangeProperty["MINIMAL_VALUE"],
"fltMaxPrice" => intval($rangeProperty["MAXIMUM_FILTERED_VALUE"]) ? $rangeProperty["MAXIMUM_FILTERED_VALUE"] : $rangeProperty["MAXIMUM_VALUE"],
"precision" => 0,
"colorUnavailableActive" => 'colorUnavailableActive_'.$rangePropertyId,
"colorAvailableActive" => 'colorAvailableActive_'.$rangePropertyId,
"colorAvailableInactive" => 'colorAvailableInactive_'.$rangePropertyId,
);
?>
<sc ript type="text/javascript">
BX.ready(function(){
window['trackBar<?=$rangePropertyId?>'] = new BX.Iblock.SmartFilter(<?=CUtil::PhpToJSObject($arJsParams)?>);
$("#range-property-field-<?=$rangePropertyId?>-min, #range-property-field-<?=$rangePropertyId?>-max")
.on("keyup change", function() {
var $realField = $("#" + $(this).data("real-id")),
value = parseInt($(this).val()),
max = parseInt($(this).data("max")),
min = parseInt($(this).data("min")),
newValue = !isNaN(max)
? Math.min(value, max)
: !isNaN(min)
? Math.max(value, min)
: "";
$realField.val(!isNaN(newValue) ? newValue : "");
smartFilter.keyup($realField[0]);
});
});
</sc ript>
</div>
<div class="clb"></div>
</div>
</div>
<?
unset($rangeProperty);
}
?> |
catalog.smart.filter – script.js:
1. В конец функции SmartFilter.prototype.recountMaxPrice добавляем
Код |
---|
$(this.maxInput).trigger("change"); |
2. В конец функции SmartFilter.prototype.recountMinPrice добавляем
Код |
---|
$(this.minInput).trigger("change"); |