Работа с bitrix:smart.filter
Rus
Eng
Работа с 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());
		}
	);
});

Источник bitrix ajax обновление списка bitrix:catalog по фильтрам без стандартного ajax включенного AJAX_MODE=Y

Полный листинг скрипта 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),
            ],
    ]
];

Комментарии

Комментариев еще нет, Вы можете стать первым кто его оставит

Оставьте комментарий

На сайте используется система премодерирования комментариев, поэтому ваше сообщение будет опубликовано лишь после одобрения модератором

Вы отвечаете на комментарий пользователя

Отправить

ОБРАТНАЯ СВЯЗЬ

Напишите мне

Вы разрабатываете новый сервис, вносите доработки в существующий и хотите лучше чем у конкурентов? Вы обратились по адресу. Предлагаю вам комплексную разработку сайтов студийного уровня. У меня вы можете заказать дизайн, верстку, програмированние, разработку нетрадиционного функционала, реализацию связи между CMS, CRM и Data Analitics, а так же все остальное касаемое сайтов, кроме продвижения.

Обращайтесь, я всегда проконсультирую по всем вопросам и помогу подобрать наиболее эффективное решение для Вашего бизнеса. Я занимаюсь созданием сайтов в Новосибирске и в других регионах России, также работаю со странами СНГ. Вы останетесь довольны нашим сотрудничеством

Во время отправки произошла ошибка, пожалуйста попробуйте еще раз через некоторое время
Сообщение отправлено успешно

Телефоны

+7(993) 007-18-96

Email

info@tichiy.ru

Адрес

Россия, г. Москва

Отправляя форму Вы автоматически подтверждаете, что ознакомились и принимаете Политику конфиденциальности сайта

Написать мне
Отправить
Отправляя форму Вы автоматически подтверждаете, что ознакомились и принимаете Политику конфиденциальности сайта
Отправка успешна!
Thank you for your feedback. I will answer you within the next working hours
Отправка не удалась
Во время отправки запроса произошла ошибка. Пожалуйста, подождите и попробуйте снова через некоторое время или свяжитесь со мной