Работа с bitrix:smart.filter
Последние записи
Заменяем checkboxes
в bitrix:smart.filter
на select
Прямо использовать селект не рекомендую, ввиду танцев с бубном при его стилизации. Поэтому я использую обычный div
стилизованный под checkbox
В начале вашего шаблона добавьте иконку стрелочки
<svg style="display: none;">
<symbol version="1.1" id="arrowDown" x="0px" y="0px"
viewBox="0 0 255 255" style="enable-background:new 0 0 255 255;"
xml:space="preserve">
<polygon points="0,63.75 127.5,191.25 255,63.75"/>
</symbol>
</svg>
В template.php
вашего bitrix:smart.filter
находим блок выводящий в цикле свойства параметров. У меня это обычно (~534 строка)
default://CHECKBOXES
И для требуемых свойств по условию выставляем новый формат вывода. Например так:
<?if($arItem['CODE'] == 'BRAND'){?>
<p>Выберите <?=$arItem['NAME']?></p>
<div class="customSelector" data-attr="<?=$arItem['CODE']?>">
<div class="customSelectorTitle">
<?$check = false;
foreach($arItem["VALUES"] as $val => $ar) {
if($ar["CHECKED"]){echo $ar['VALUE'];$check = true;}
}
if(!$check) {echo $arItem["NAME"];}
?>
<svg class="icon"><use xlink:href="#arrowDown" /></svg>
</div>
<div class="customSelectorOptions">
<?foreach($arItem["VALUES"] as $val => $ar) { ?>
<label class="customSelect <?if ($ar["DISABLED"]){ ?>disabled<? }?>" data-attr="<?echo $ar["VALUE"];?>"><input type="checkbox" name="<?echo $ar["CONTROL_NAME"]?>" id="<?echo $ar["CONTROL_ID"]?>" value="Y" onchange="smartFilter.click(this)" data-attr="<?echo $ar["VALUE"];?>" <?echo $ar["CHECKED"]? 'checked="checked"': ''?> <?if ($ar["DISABLED"]){ ?>disabled<? }?>><?echo $ar["VALUE"];?></label>
<?}?>
</div>
</div>
<?}else{?>
<?foreach($arItem["VALUES"] as $val => $ar):?>
<label data-role="label_<?=$ar["CONTROL_ID"]?>" class="bx_filter_param_label <? echo $ar["DISABLED"] ? 'disabled': '' ?>" for="<? echo $ar["CONTROL_ID"] ?>">
<span class="bx_filter_input_checkbox">
<input
type="checkbox"
value="<? echo $ar["HTML_VALUE"] ?>"
name="<? echo $ar["CONTROL_NAME"] ?>"
id="<? echo $ar["CONTROL_ID"] ?>"
<? echo $ar["CHECKED"]? 'checked="checked"': '' ?>
onclick="smartFilter.click(this)"
/>
<span class="bx_filter_param_text" title="<?=$ar["VALUE"];?>"><?=$ar["VALUE"];?><?
if ($arParams["DISPLAY_ELEMENT_COUNT"] !== "N" && isset($ar["ELEMENT_COUNT"])):
?> (<span data-role="count_<?=$ar["CONTROL_ID"]?>"><? echo $ar["ELEMENT_COUNT"]; ?></span>)<?
endif;?></span>
</span>
</label>
<?endforeach;?>
Добавляем стили в style.css
шаблона
.customSelectorTitle .icon
{-moz-transition: all 0.5s;-webkit-transition: all 0.5s;-o-transition: all 0.5s;-ms-transition: all 0.5s}
.customSelectorTitle {background-color: #fff;border: 1px solid #eee;-ms-align-items: center;align-items: center;padding-left: 12px;font-size: 13px;max-width: 100%;line-height: 50px;cursor: pointer;vertical-align: middle;position: relative;white-space: nowrap;height: 50px;position: relative}
.customSelectorTitle:first-letter {text-transform: uppercase}
.customSelectorTitle .icon{position: absolute;right:10px;top:20px;width: 10px;height: 10px;transform: rotate(0)}
.customSelectorTitle.active .icon{transform: rotate(180deg)}
.customSelect {display: block;width: 100%;cursor: pointer;padding-left: 12px;margin-bottom: 0;line-height: 30px;font-size: 13px}
.customSelect.disabled {color: #fff;background-color: #e3e3e3}
.customSelect:hover {background-color: #e3e3e3}
.customSelect input {display: none;}
.customSelector{position: relative}
.customSelectorOptions {position: absolute;top: 50px;left:0;width: 100%;height: auto;background-color: #fff;border: 1px solid #eee;display: none;z-index: 10;font-size: 16px;}
.main-calculator__card.active{display: flex}
Добавляем jQuery
обработчик
(function($) {
$( document ).ready(function() {
$('body').on('click','.customSelectorTitle',function(){
var el = $(this);
if(el.hasClass('active')){
el.removeClass('active');
el.next().stop().slideUp(200);
}else{
$('.customSelectorTitle.active ~.customSelectorOptions').slideUp(200);
$('.customSelectorTitle.active').removeClass('active');
el.addClass('active');
el.next().stop().slideDown(200);
}
});
$('.customSelect input').on('change',function(){
var el = $(this);
el.parents('.customSelectorOptions').prev().text(el.attr('data-attr')).removeClass('active');
el.parents('.customSelectorOptions').find('input').not(el).prop('checked', false).val('N');
el.parents('.customSelectorOptions').stop().slideUp(200);
});
$(document).mouseup(function (e){ // событие клика по веб-документу
var div = $(".customSelector"); // тут указываем ID элемента
if (!div.is(e.target) // если клик был не по нашему блоку
&& div.has(e.target).length === 0) { // и не по его дочерним элементам
$('.customSelectorTitle.active ~.customSelectorOptions').slideUp(200);
$('.customSelectorTitle.active').removeClass('active');
}
});
});
})(jQuery);
AJAX обновление фильтров bitrix:smart.filter
в bitrix:catalog
без включенного AJAX_MODE=Y
В файле script.js
Вашего шаблона компонента bitrix:smart.filter
ищем функцию JCSmartFilter.prototype.postHandler
и в ней комментируем строки (~184 строка):
/*if (modef.style.display === 'none')
{
modef.style.display = 'inline-block';
}*/
Сразу после них добавляем:
$.get(
result.FILTER_AJAX_URL,
function (data) {
$('#catalogBlock').html($(data).find('#catalogBlock').html());
}
);
history.pushState(null, null, result.FILTER_AJAX_URL);
Ваш каталог должен быть обрамлен в div
c id="catalogBlock"
Чтобы сделать вашу пагинацию ajax
, то используйте аналогичный код
$(document).on("click", '#catalogBlock .pagination a', function (e) {
e.preventDefault();
var href=$(this).attr('href');
history.pushState(null, null, href);
$.get(
href,
function (data) {
$('#catalogBlock').html($(data).find('#catalogBlock').html());
}
);
});
Полный листинг скрипта script.js
компонента bitrix:smart.filter
с включенным ajax из примера выше, кастомным прелоадером и парой исправлений
Прелоадер берем отсюда
Плюс. поскольку у нас чекбоксы, то при выборе второго и далее вариантов bitrix:smart.filter
генерирует урл из всех включенных checbox
, что нас не устраивает, а потому ищем функцию JCSmartFilter.prototype.click
И вставляем обнуление значений всех выбранных ранее параметров из конкретного свойства
//Обнуляем значения других чекбоксов свойства
var clist = checkbox.closest(".customSelectorOptions").getElementsByTagName("input");
for (var i = 0; i < clist.length; ++i) {
if(clist[i] !== checkbox){
clist[i].checked = false;
}
}
Тогда полный листинг выглядит так:
function JCSmartFilter(ajaxURL, viewMode)
{
this.ajaxURL = ajaxURL;
this.form = null;
this.timer = null;
this.first = true;
this.cacheKey = '';
this.cache = [];
this.viewMode = viewMode;
}
JCSmartFilter.prototype.keyup = function(input)
{
if(!!this.timer)
{
clearTimeout(this.timer);
}
this.timer = setTimeout(BX.delegate(function(){
this.reload(input);
}, this), 500);
};
JCSmartFilter.prototype.click = function(checkbox)
{
if(!!this.timer)
{
clearTimeout(this.timer);
}
//Обнуляем значения других чекбоксов свойства
var clist = checkbox.closest(".customSelectorOptions").getElementsByTagName("input");
for (var i = 0; i < clist.length; ++i) {
if(clist[i] !== checkbox){
clist[i].checked = false;
}
}
BX.showWait();
this.timer = setTimeout(BX.delegate(function(){
this.reload(checkbox);
}, this), 1000);
};
JCSmartFilter.prototype.reload = function(input)
{
if (this.cacheKey !== '')
{
//Postprone backend query
if(!!this.timer)
{
clearTimeout(this.timer);
}
this.timer = setTimeout(BX.delegate(function(){
this.reload(input);
}, this), 1000);
return;
}
this.cacheKey = '|';
this.position = BX.pos(input, true);
this.form = BX.findParent(input, {'tag':'form'});
if (this.form)
{
var values = [];
values[0] = {name: 'ajax', value: 'y'};
this.gatherInputsValues(values, BX.findChildren(this.form, {'tag': new RegExp('^(input|select)$', 'i')}, true));
for (var i = 0; i < values.length; i++)
this.cacheKey += values[i].name + ':' + values[i].value + '|';
if (this.cache[this.cacheKey])
{
this.curFilterinput = input;
this.postHandler(this.cache[this.cacheKey], true);
}
else
{
this.curFilterinput = input;
BX.ajax.loadJSON(
this.ajaxURL,
this.values2post(values),
BX.delegate(this.postHandler, this)
);
}
}
};
JCSmartFilter.prototype.updateItem = function (PID, arItem)
{
if (arItem.PROPERTY_TYPE === 'N' || arItem.PRICE)
{
var trackBar = window['trackBar' + PID];
if (!trackBar && arItem.ENCODED_ID)
trackBar = window['trackBar' + arItem.ENCODED_ID];
if (trackBar && arItem.VALUES)
{
if (arItem.VALUES.MIN && arItem.VALUES.MIN.FILTERED_VALUE)
{
trackBar.setMinFilteredValue(arItem.VALUES.MIN.FILTERED_VALUE);
}
if (arItem.VALUES.MAX && arItem.VALUES.MAX.FILTERED_VALUE)
{
trackBar.setMaxFilteredValue(arItem.VALUES.MAX.FILTERED_VALUE);
}
}
}
else if (arItem.VALUES)
{
for (var i in arItem.VALUES)
{
if (arItem.VALUES.hasOwnProperty(i))
{
var value = arItem.VALUES[i];
var control = BX(value.CONTROL_ID);
if (!!control)
{
var label = document.querySelector('[data-role="label_'+value.CONTROL_ID+'"]');
if (value.DISABLED)
{
if (label)
BX.addClass(label, 'disabled');
else
BX.addClass(control.parentNode, 'disabled');
}
else
{
if (label)
BX.removeClass(label, 'disabled');
else
BX.removeClass(control.parentNode, 'disabled');
}
if (value.hasOwnProperty('ELEMENT_COUNT'))
{
label = document.querySelector('[data-role="count_'+value.CONTROL_ID+'"]');
if (label)
label.innerHTML = value.ELEMENT_COUNT;
}
}
}
}
}
};
JCSmartFilter.prototype.postHandler = function (result, fromCache)
{
var hrefFILTER, url, curProp;
var modef = BX('modef');
var modef_num = BX('modef_num');
if (!!result && !!result.ITEMS)
{
for(var PID in result.ITEMS)
{
if (result.ITEMS.hasOwnProperty(PID))
{
this.updateItem(PID, result.ITEMS[PID]);
}
}
if (!!modef && !!modef_num)
{
modef_num.innerHTML = result.ELEMENT_COUNT;
hrefFILTER = BX.findChildren(modef, {tag: 'A'}, true);
if (result.FILTER_URL && hrefFILTER)
{
hrefFILTER[0].href = BX.util.htmlspecialcharsback(result.FILTER_URL);
}
if (result.FILTER_AJAX_URL && result.COMPONENT_CONTAINER_ID)
{
BX.bind(hrefFILTER[0], 'click', function(e)
{
url = BX.util.htmlspecialcharsback(result.FILTER_AJAX_URL);
BX.ajax.insertToNode(url, result.COMPONENT_CONTAINER_ID);
return BX.PreventDefault(e);
});
}
if (result.INSTANT_RELOAD && result.COMPONENT_CONTAINER_ID)
{
url = BX.util.htmlspecialcharsback(result.FILTER_AJAX_URL);
BX.ajax.insertToNode(url, result.COMPONENT_CONTAINER_ID);
}
else
{
/*if (modef.style.display === 'none')
{
modef.style.display = 'inline-block';
}*/
$.get(
result.FILTER_AJAX_URL,
function (data) {
$('#catalogBlock').html($(data).find('#catalogBlock').html());
BX.closeWait();
}
);
history.pushState(null, null, result.FILTER_AJAX_URL);
if (this.viewMode == "vertical")
{
curProp = BX.findChild(BX.findParent(this.curFilterinput, {'class':'bx_filter_parameters_box'}), {'class':'bx_filter_container_modef'}, true, false);
curProp.appendChild(modef);
}
}
}
}
if (!fromCache && this.cacheKey !== '')
{
this.cache[this.cacheKey] = result;
}
this.cacheKey = '';
};
JCSmartFilter.prototype.gatherInputsValues = function (values, elements)
{
if(elements)
{
for(var i = 0; i < elements.length; i++)
{
var el = elements[i];
if (el.disabled || !el.type)
continue;
switch(el.type.toLowerCase())
{
case 'text':
case 'textarea':
case 'password':
case 'hidden':
case 'select-one':
if(el.value.length)
values[values.length] = {name : el.name, value : el.value};
break;
case 'radio':
case 'checkbox':
if(el.checked)
values[values.length] = {name : el.name, value : el.value};
break;
case 'select-multiple':
for (var j = 0; j < el.options.length; j++)
{
if (el.options[j].selected)
values[values.length] = {name : el.name, value : el.options[j].value};
}
break;
default:
break;
}
}
}
};
JCSmartFilter.prototype.values2post = function (values)
{
var post = [];
var current = post;
var i = 0;
while(i < values.length)
{
var p = values[i].name.indexOf('[');
if(p == -1)
{
current[values[i].name] = values[i].value;
current = post;
i++;
}
else
{
var name = values[i].name.substring(0, p);
var rest = values[i].name.substring(p+1);
if(!current[name])
current[name] = [];
var pp = rest.indexOf(']');
if(pp == -1)
{
//Error - not balanced brackets
current = post;
i++;
}
else if(pp == 0)
{
//No index specified - so take the next integer
current = current[name];
values[i].name = '' + current.length;
}
else
{
//Now index name becomes and name and we go deeper into the array
current = current[name];
values[i].name = rest.substring(0, pp) + rest.substring(pp+1);
}
}
}
return post;
};
JCSmartFilter.prototype.hideFilterProps = function(element)
{
var easing;
var obj = element.parentNode;
var filterBlock = BX.findChild(obj, {className:"bx_filter_block"}, true, false);
if(BX.hasClass(obj, "active"))
{
easing = new BX.easing({
duration : 300,
start : { opacity: 1, height: filterBlock.offsetHeight },
finish : { opacity: 0, height:0 },
transition : BX.easing.transitions.quart,
step : function(state){
filterBlock.style.opacity = state.opacity;
filterBlock.style.height = state.height + "px";
},
complete : function() {
filterBlock.setAttribute("style", "");
BX.removeClass(obj, "active");
}
});
easing.animate();
}
else
{
filterBlock.style.display = "block";
filterBlock.style.opacity = 0;
filterBlock.style.height = "auto";
var obj_children_height = filterBlock.offsetHeight;
filterBlock.style.height = 0;
easing = new BX.easing({
duration : 300,
start : { opacity: 0, height: 0 },
finish : { opacity: 1, height: obj_children_height },
transition : BX.easing.transitions.quart,
step : function(state){
filterBlock.style.opacity = state.opacity;
filterBlock.style.height = state.height + "px";
},
complete : function() {
}
});
easing.animate();
BX.addClass(obj, "active");
}
};
JCSmartFilter.prototype.showDropDownPopup = function(element, popupId)
{
var contentNode = element.querySelector('[data-role="dropdownContent"]');
BX.PopupWindowManager.create("smartFilterDropDown"+popupId, element, {
autoHide: true,
offsetLeft: 0,
offsetTop: 3,
overlay : false,
draggable: {restrict:true},
closeByEsc: true,
content: contentNode
}).show();
};
JCSmartFilter.prototype.selectDropDownItem = function(element, controlId)
{
this.keyup(BX(controlId));
var wrapContainer = BX.findParent(BX(controlId), {className:"bx_filter_select_container"}, false);
var currentOption = wrapContainer.querySelector('[data-role="currentOption"]');
currentOption.innerHTML = element.innerHTML;
BX.PopupWindowManager.getCurrentPopup().close();
};
BX.namespace("BX.Iblock.SmartFilter");
BX.Iblock.SmartFilter = (function()
{
var SmartFilter = function(arParams)
{
if (typeof arParams === 'object')
{
this.leftSlider = BX(arParams.leftSlider);
this.rightSlider = BX(arParams.rightSlider);
this.tracker = BX(arParams.tracker);
this.trackerWrap = BX(arParams.trackerWrap);
this.minInput = BX(arParams.minInputId);
this.maxInput = BX(arParams.maxInputId);
this.minPrice = parseFloat(arParams.minPrice);
this.maxPrice = parseFloat(arParams.maxPrice);
this.curMinPrice = parseFloat(arParams.curMinPrice);
this.curMaxPrice = parseFloat(arParams.curMaxPrice);
this.fltMinPrice = arParams.fltMinPrice ? parseFloat(arParams.fltMinPrice) : parseFloat(arParams.curMinPrice);
this.fltMaxPrice = arParams.fltMaxPrice ? parseFloat(arParams.fltMaxPrice) : parseFloat(arParams.curMaxPrice);
this.precision = arParams.precision || 0;
this.priceDiff = this.maxPrice - this.minPrice;
this.leftPercent = 0;
this.rightPercent = 0;
this.fltMinPercent = 0;
this.fltMaxPercent = 0;
this.colorUnavailableActive = BX(arParams.colorUnavailableActive);//gray
this.colorAvailableActive = BX(arParams.colorAvailableActive);//blue
this.colorAvailableInactive = BX(arParams.colorAvailableInactive);//light blue
this.isTouch = false;
this.init();
if ('ontouchstart' in document.documentElement)
{
this.isTouch = true;
BX.bind(this.leftSlider, "touchstart", BX.proxy(function(event){
this.onMoveLeftSlider(event)
}, this));
BX.bind(this.rightSlider, "touchstart", BX.proxy(function(event){
this.onMoveRightSlider(event)
}, this));
}
else
{
BX.bind(this.leftSlider, "mousedown", BX.proxy(function(event){
this.onMoveLeftSlider(event)
}, this));
BX.bind(this.rightSlider, "mousedown", BX.proxy(function(event){
this.onMoveRightSlider(event)
}, this));
}
BX.bind(this.minInput, "keyup", BX.proxy(function(event){
this.onInputChange();
}, this));
BX.bind(this.maxInput, "keyup", BX.proxy(function(event){
this.onInputChange();
}, this));
}
};
SmartFilter.prototype.init = function()
{
var priceDiff;
if (this.curMinPrice > this.minPrice)
{
priceDiff = this.curMinPrice - this.minPrice;
this.leftPercent = (priceDiff*100)/this.priceDiff;
this.leftSlider.style.left = this.leftPercent + "%";
this.colorUnavailableActive.style.left = this.leftPercent + "%";
}
this.setMinFilteredValue(this.fltMinPrice);
if (this.curMaxPrice < this.maxPrice)
{
priceDiff = this.maxPrice - this.curMaxPrice;
this.rightPercent = (priceDiff*100)/this.priceDiff;
this.rightSlider.style.right = this.rightPercent + "%";
this.colorUnavailableActive.style.right = this.rightPercent + "%";
}
this.setMaxFilteredValue(this.fltMaxPrice);
};
SmartFilter.prototype.setMinFilteredValue = function (fltMinPrice)
{
this.fltMinPrice = parseFloat(fltMinPrice);
if (this.fltMinPrice >= this.minPrice)
{
var priceDiff = this.fltMinPrice - this.minPrice;
this.fltMinPercent = (priceDiff*100)/this.priceDiff;
if (this.leftPercent > this.fltMinPercent)
this.colorAvailableActive.style.left = this.leftPercent + "%";
else
this.colorAvailableActive.style.left = this.fltMinPercent + "%";
this.colorAvailableInactive.style.left = this.fltMinPercent + "%";
}
else
{
this.colorAvailableActive.style.left = "0%";
this.colorAvailableInactive.style.left = "0%";
}
};
SmartFilter.prototype.setMaxFilteredValue = function (fltMaxPrice)
{
this.fltMaxPrice = parseFloat(fltMaxPrice);
if (this.fltMaxPrice <= this.maxPrice)
{
var priceDiff = this.maxPrice - this.fltMaxPrice;
this.fltMaxPercent = (priceDiff*100)/this.priceDiff;
if (this.rightPercent > this.fltMaxPercent)
this.colorAvailableActive.style.right = this.rightPercent + "%";
else
this.colorAvailableActive.style.right = this.fltMaxPercent + "%";
this.colorAvailableInactive.style.right = this.fltMaxPercent + "%";
}
else
{
this.colorAvailableActive.style.right = "0%";
this.colorAvailableInactive.style.right = "0%";
}
};
SmartFilter.prototype.getXCoord = function(elem)
{
var box = elem.getBoundingClientRect();
var body = document.body;
var docElem = document.documentElement;
var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
var clientLeft = docElem.clientLeft || body.clientLeft || 0;
var left = box.left + scrollLeft - clientLeft;
return Math.round(left);
};
SmartFilter.prototype.getPageX = function(e)
{
e = e || window.event;
var pageX = null;
if (this.isTouch && event.targetTouches[0] != null)
{
pageX = e.targetTouches[0].pageX;
}
else if (e.pageX != null)
{
pageX = e.pageX;
}
else if (e.clientX != null)
{
var html = document.documentElement;
var body = document.body;
pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0);
pageX -= html.clientLeft || 0;
}
return pageX;
};
SmartFilter.prototype.recountMinPrice = function()
{
var newMinPrice = (this.priceDiff*this.leftPercent)/100;
newMinPrice = (this.minPrice + newMinPrice).toFixed(this.precision);
if (newMinPrice != this.minPrice)
this.minInput.value = newMinPrice;
else
this.minInput.value = "";
smartFilter.keyup(this.minInput);
};
SmartFilter.prototype.recountMaxPrice = function()
{
var newMaxPrice = (this.priceDiff*this.rightPercent)/100;
newMaxPrice = (this.maxPrice - newMaxPrice).toFixed(this.precision);
if (newMaxPrice != this.maxPrice)
this.maxInput.value = newMaxPrice;
else
this.maxInput.value = "";
smartFilter.keyup(this.maxInput);
};
SmartFilter.prototype.onInputChange = function ()
{
var priceDiff;
if (this.minInput.value)
{
var leftInputValue = this.minInput.value;
if (leftInputValue < this.minPrice)
leftInputValue = this.minPrice;
if (leftInputValue > this.maxPrice)
leftInputValue = this.maxPrice;
priceDiff = leftInputValue - this.minPrice;
this.leftPercent = (priceDiff*100)/this.priceDiff;
this.makeLeftSliderMove(false);
}
if (this.maxInput.value)
{
var rightInputValue = this.maxInput.value;
if (rightInputValue < this.minPrice)
rightInputValue = this.minPrice;
if (rightInputValue > this.maxPrice)
rightInputValue = this.maxPrice;
priceDiff = this.maxPrice - rightInputValue;
this.rightPercent = (priceDiff*100)/this.priceDiff;
this.makeRightSliderMove(false);
}
};
SmartFilter.prototype.makeLeftSliderMove = function(recountPrice)
{
recountPrice = (recountPrice === false) ? false : true;
this.leftSlider.style.left = this.leftPercent + "%";
this.colorUnavailableActive.style.left = this.leftPercent + "%";
var areBothSlidersMoving = false;
if (this.leftPercent + this.rightPercent >= 100)
{
areBothSlidersMoving = true;
this.rightPercent = 100 - this.leftPercent;
this.rightSlider.style.right = this.rightPercent + "%";
this.colorUnavailableActive.style.right = this.rightPercent + "%";
}
if (this.leftPercent >= this.fltMinPercent && this.leftPercent <= (100-this.fltMaxPercent))
{
this.colorAvailableActive.style.left = this.leftPercent + "%";
if (areBothSlidersMoving)
{
this.colorAvailableActive.style.right = 100 - this.leftPercent + "%";
}
}
else if(this.leftPercent <= this.fltMinPercent)
{
this.colorAvailableActive.style.left = this.fltMinPercent + "%";
if (areBothSlidersMoving)
{
this.colorAvailableActive.style.right = 100 - this.fltMinPercent + "%";
}
}
else if(this.leftPercent >= this.fltMaxPercent)
{
this.colorAvailableActive.style.left = 100-this.fltMaxPercent + "%";
if (areBothSlidersMoving)
{
this.colorAvailableActive.style.right = this.fltMaxPercent + "%";
}
}
if (recountPrice)
{
this.recountMinPrice();
if (areBothSlidersMoving)
this.recountMaxPrice();
}
};
SmartFilter.prototype.countNewLeft = function(event)
{
var pageX = this.getPageX(event);
var trackerXCoord = this.getXCoord(this.trackerWrap);
var rightEdge = this.trackerWrap.offsetWidth;
var newLeft = pageX - trackerXCoord;
if (newLeft < 0)
newLeft = 0;
else if (newLeft > rightEdge)
newLeft = rightEdge;
return newLeft;
};
SmartFilter.prototype.onMoveLeftSlider = function(e)
{
if (!this.isTouch)
{
this.leftSlider.ondragstart = function() {
return false;
};
}
if (!this.isTouch)
{
document.onmousemove = BX.proxy(function(event) {
this.leftPercent = ((this.countNewLeft(event)*100)/this.trackerWrap.offsetWidth);
this.makeLeftSliderMove();
}, this);
document.onmouseup = function() {
document.onmousemove = document.onmouseup = null;
};
}
else
{
document.ontouchmove = BX.proxy(function(event) {
this.leftPercent = ((this.countNewLeft(event)*100)/this.trackerWrap.offsetWidth);
this.makeLeftSliderMove();
}, this);
document.ontouchend = function() {
document.ontouchmove = document.touchend = null;
};
}
return false;
};
SmartFilter.prototype.makeRightSliderMove = function(recountPrice)
{
recountPrice = (recountPrice === false) ? false : true;
this.rightSlider.style.right = this.rightPercent + "%";
this.colorUnavailableActive.style.right = this.rightPercent + "%";
var areBothSlidersMoving = false;
if (this.leftPercent + this.rightPercent >= 100)
{
areBothSlidersMoving = true;
this.leftPercent = 100 - this.rightPercent;
this.leftSlider.style.left = this.leftPercent + "%";
this.colorUnavailableActive.style.left = this.leftPercent + "%";
}
if ((100-this.rightPercent) >= this.fltMinPercent && this.rightPercent >= this.fltMaxPercent)
{
this.colorAvailableActive.style.right = this.rightPercent + "%";
if (areBothSlidersMoving)
{
this.colorAvailableActive.style.left = 100 - this.rightPercent + "%";
}
}
else if(this.rightPercent <= this.fltMaxPercent)
{
this.colorAvailableActive.style.right = this.fltMaxPercent + "%";
if (areBothSlidersMoving)
{
this.colorAvailableActive.style.left = 100 - this.fltMaxPercent + "%";
}
}
else if((100-this.rightPercent) <= this.fltMinPercent)
{
this.colorAvailableActive.style.right = 100-this.fltMinPercent + "%";
if (areBothSlidersMoving)
{
this.colorAvailableActive.style.left = this.fltMinPercent + "%";
}
}
if (recountPrice)
{
this.recountMaxPrice();
if (areBothSlidersMoving)
this.recountMinPrice();
}
};
SmartFilter.prototype.onMoveRightSlider = function(e)
{
if (!this.isTouch)
{
this.rightSlider.ondragstart = function() {
return false;
};
}
if (!this.isTouch)
{
document.onmousemove = BX.proxy(function(event) {
this.rightPercent = 100-(((this.countNewLeft(event))*100)/(this.trackerWrap.offsetWidth));
this.makeRightSliderMove();
}, this);
document.onmouseup = function() {
document.onmousemove = document.onmouseup = null;
};
}
else
{
document.ontouchmove = BX.proxy(function(event) {
this.rightPercent = 100-(((this.countNewLeft(event))*100)/(this.trackerWrap.offsetWidth));
this.makeRightSliderMove();
}, this);
document.ontouchend = function() {
document.ontouchmove = document.ontouchend = null;
};
}
return false;
};
return SmartFilter;
})();
(function($) {
$( document ).ready(function() {
$('body').on('click','.customSelectorTitle',function(){
var el = $(this);
if(el.hasClass('active')){
el.removeClass('active');
el.next().stop().slideUp(200);
}else{
$('.customSelectorTitle.active ~.customSelectorOptions').slideUp(200);
$('.customSelectorTitle.active').removeClass('active');
el.addClass('active');
el.next().stop().slideDown(200);
}
});
$('.customSelect input').on('change',function(){
var el = $(this);
el.parents('.customSelectorOptions').prev().text(el.attr('data-attr')).removeClass('active');
el.parents('.customSelectorOptions').find('input').not(el).prop('checked', false).val('N');
el.parents('.customSelectorOptions').stop().slideUp(200);
});
$(document).mouseup(function (e){ // событие клика по веб-документу
var div = $(".customSelector"); // тут указываем ID элемента
if (!div.is(e.target) // если клик был не по нашему блоку
&& div.has(e.target).length === 0) { // и не по его дочерним элементам
$('.customSelectorTitle.active ~.customSelectorOptions').slideUp(200);
$('.customSelectorTitle.active').removeClass('active');
}
});
});
})(jQuery);
var lastWait = [];
/* non-xhr loadings */
BX.showWait = function (node, msg)
{
node = BX(node) || document.body || document.documentElement;
msg = msg || BX.message('JS_CORE_LOADING');
var container_id = node.id || Math.random();
var obMsg = node.bxmsg = document.body.appendChild(BX.create('DIV', {
props: {
id: 'wait_' + container_id,
className: 'bx-core-waitwindow'
},
text: msg
}));
setTimeout(BX.delegate(_adjustWait, node), 10);
$('.pWrap').show();
lastWait[lastWait.length] = obMsg;
return obMsg;
};
BX.closeWait = function (node, obMsg)
{
$('.pWrap').hide();
if (node && !obMsg)
obMsg = node.bxmsg;
if (node && !obMsg && BX.hasClass(node, 'bx-core-waitwindow'))
obMsg = node;
if (node && !obMsg)
obMsg = BX('wait_' + node.id);
if (!obMsg)
obMsg = lastWait.pop();
if (obMsg && obMsg.parentNode)
{
for (var i = 0, len = lastWait.length; i < len; i++)
{
if (obMsg == lastWait[i])
{
lastWait = BX.util.deleteFromArray(lastWait, i);
break;
}
}
obMsg.parentNode.removeChild(obMsg);
if (node)
node.bxmsg = null;
BX.cleanNode(obMsg, true);
}
};
function _adjustWait()
{
if (!this.bxmsg)
return;
var arContainerPos = BX.pos(this),
div_top = arContainerPos.top;
if (div_top < BX.GetDocElement().scrollTop)
div_top = BX.GetDocElement().scrollTop + 5;
this.bxmsg.style.top = (div_top + 5) + 'px';
if (this == BX.GetDocElement())
{
this.bxmsg.style.right = '5px';
}
else
{
this.bxmsg.style.left = (arContainerPos.right - this.bxmsg.offsetWidth - 5) + 'px';
}
}
Ajax фильтрация catalog.smart.filter
при submit
формы
Идем в script.js
вашего шаблона фильтра и перед строкой if (result.INSTANT_RELOAD && result.COMPONENT_CONTAINER_ID)
вставляем
if (result.FILTER_AJAX_URL && result.COMPONENT_CONTAINER_ID)
{
BX.bind(document.querySelector('#set_filter'), 'click', function(e) //где set_filter это id вашей кнопки submit
{
url = BX.util.htmlspecialcharsback(result.FILTER_AJAX_URL);
BX.ajax.insertToNode(url, result.COMPONENT_CONTAINER_ID);
return BX.PreventDefault(e);
});
}
Находим функцию JCSmartFilter.prototype.bindUrlToButton
и комментируем строки:
BX.bind(button, 'click', proxy(url, function(url)
{
window.location.href = url;
return false;
}));
Фильтруем каталог по свойству типа список
Размещаем код перед вызовом bitrix:catalog.section
//Фильтруем каталог по свойству типа список
if ($sGetSort = $request->getQuery("set")) {
switch($sGetSort) {
case '5':
$arrFilter['=PROPERTY_SET'] = '193';
break;
case '10':
$arrFilter['=PROPERTY_SET'] = '194';
break;
}
}
//Где PROPERTY_SET - код фильтруемого свойства
//, а 193\194 - ID фильтруемых свойств
Выводим фильтр по параметру
Размещаем в файле result_modifier.php
дополнительный массив с нашим параметром. Решение "грязное", но рабочее
$arResult['ITEMS'][778] = [
'ID' => 778,
'IBLOCK_ID' => 9,
'CODE' => 'SET',
'NAME' => 'Сет',
'PROPERTY_TYPE' => 'L',
'DISPLAY_TYPE' => 'P',
'DISPLAY_EXPANDED' => 'N',
'VALUES' => [
'779' => [
'CONTROL_ID' => 'set_3390377895',
'CONTROL_NAME' => 'set_3390377895',
'CONTROL_NAME_ALT' => 'set',
'HTML_VALUE_ALT' => '5',
'HTML_VALUE' => 'Y',
'VALUE' => '5 товаров в наборе',
'SORT' => '100',
'UPPER' => '5 ТОВАРОВ В НАБОРЕ',
'URL_ID' => rand(32),
],
'780' => [
'CONTROL_ID' => 'set_778_3390377895',
'CONTROL_NAME' => 'set_3390377895',
'CONTROL_NAME_ALT' => 'set',
'HTML_VALUE_ALT' => '10',
'HTML_VALUE' => 'Y',
'VALUE' => '10 товаров в наборе',
'SORT' => '200',
'UPPER' => '10 ТОВАРОВ В НАБОРЕ',
'URL_ID' => rand(32),
],
]
];
Комментарии