Как переделать checkbox в select в компоненте catalog.smart.filter (умный фильтр) ?, Попытка переделать стандартный checkbox в умном фильтре в выпадающий список select
Всем добрый день! Задача следующая, мне необходимо переделать стандартный checkbox http://myscreenshot.info/i/0003/413641396771985763416605721618.png в умном фильтре в выпадающий список select http://myscreenshot.info/i/0003/409631396772069264378699606169.png. Через firebug выяснил какие параметры филтр передаёт в обработчик, по сути это имя параметра по которому мы фильтруем и его значение Y (т.е. истина) http://myscreenshot.info/i/0003/946951396772483147925146920077.png. В данном примере я выбрал материал "Трикотаж" фильтр передал обработчику 2 параметра ajax = y (я так понял это постоянный параметр говорящий системе что включён режим ajax) и arrFilter_9_3012990210 = Y , где arrFilter_9_3012990210 - это значение атрибута name нашего чекбокса (см.скриншот). Вся эта чудо конструкция обрабатывается методом smartFilter.click(this) срабатывающим на событие onClick на нашем чекбоксе. Что такое метод click() объекта smartFilter ? Заглянем в дерево шаблона компонента catalog.smart.filter http://myscreenshot.info/i/0003/324131396772989738348415892929.png находим там файл script.js который собственно и содержит описание класса smartFilter с набором соответствующих методов. Вот что представляет собой метод click():
Код
JCSmartFilter.prototype.click = function(checkbox)
{
if(this.timer)
clearTimeout(this.timer);
this.timer = setTimeout(BX.delegate(function(){
this.reload(checkbox); //На сколько понял с задержкой в секунду метод вызывает (BX.delegate()) метод reload
}, this), 1000);
}
По все видимости именно gatherInputsValues() считывает значение выбранных пользователем чекбоксов которые затем передаются в loadJSON, смотрим:
Код
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': //ОПАЧКИ! Разработчики предусмотрели работу фильтра с полями типа select (т.е. выпадающий список)
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;
}
}
}
}
Я так понял что набор этих методов позволяет обрабатывать не только chechkbox но так же и select, однако я не как не додумаюсь как правильно сверстать этот список чтобы данный скрипт понял что выбирает пользователь в фильтре без лишних костылей. Уважаемые разработчики 1С Битрикс - подскажите как правильно переделать checkbox в <select><option>...</option>...</select> так чтобы данный набор методов меня понял?
На текущий момент удалось частично реализовать задуманное рядом костылей. Я скопировал методы click и reload и переименовал копии в clickSelect и clickReload в каждом из этих методов я заменил input-ы на select вот так http://myscreenshot.info/i/0003/691531396774316164675678922975.png . А в шаблоне компонента умного фильтра (естественно скопированном в шаблон сайта) переделал вёрстку вот так:
Но чтобы у select-а подставлялся нужный name пришлось ещё дописать такую jquery функцию, она получает id выбранного option и подставляет значение этого id в name тега select, после чего срабатывает метод smartFilter.clickSelect(this) реагирующий теперь на событие onChange:
В принципе работает, правда пока после отработки фильтра (нажатия на кнопку или ссылку "Показать" ) в select не сохраняются выбранные значения фильтрации. Нужно допиливать обработчик. Но всётаки хотелось бы узнать как можно сделать select по задумке разработчиков битрикса чтобы нормально трабатывал метод gatherInputsValues() и никаких костылей делать не пришлось.
не заметил сразу $ar["CHECKED"] - булевское значение показывающее выбран ли этот параметр на предыдущей фильтрации ли нет. Однако столкнулся с другой проблемкой, после выбора параметра из любого select-а на всех select-ах пропадают классы т.е. атрибут class - очищается и перестаёт работать моя jquery функция:
1) в файле script.js папки шаблона компонента catalog.smart.filter копируем и переименовываем 2 метода click и reload и слегка меняем их атрибуты (везде меняем input на select) :
3) и тут же ниже добавляем "генератор jquery обработчиков select-ов" с селектами они будут связаны по id значением которого выступает код элемента $arItem['CODE'] - это добавит коду универсальности, с появлением дополнительных свойств в виде selec-ов не придётся лезть в код и дописывать обработчики для новых свойств.
Код
<script>
$(document).ready(function(){
<? //Формируем дополнительные jquery обработчики для select-ов
foreach($arResult["ITEMS"] as $key=>$arItem) {
if(!empty($arItem["VALUES"]) && !isset($arItem["PRICE"])) {
?>
//Проставляем name select-ам с уже выбранными свойствами
setTimeout(function(){
var SelectOption = $("#<?=$arItem['CODE']; ?> option:selected").attr('id');
$("#<?=$arItem['CODE']; ?>").attr('name',SelectOption);
},1500);
//заполнение name с реакцией на change
$("#<?=$arItem['CODE']; ?>").on('change', function(){
var SelectOption = $("#<?=$arItem['CODE']; ?> option:selected").attr('id');
$("#<?=$arItem['CODE']; ?>").attr('name',SelectOption);
<?
}
}?>
});
</script>
Собственно и всё.
Но ОЧЕНЬ ХОЧЕТСЯ ПОСМОТРЕТЬ НА ТО ЧТО ПРЕДЛАГАЮТ САМИ РАЗРАБОТЧИКИ, раз уж в методе gatherInputsValues() изначально была предусмотрена обработка select-ов наверняка в этом направлении должны были вестись какие-нибудь работы.
Огромное спасибо! У вас в последнем скрипте не хватает закрывающих скобок для события change:
Код
<script>
$(document).ready(function(){
<?//Формируем дополнительные jquery обработчики для select-ов?>
<?foreach($arResult["ITEMS"] as $key=>$arItem):?>
<?if(!empty($arItem["VALUES"]) && !isset($arItem["PRICE"])):?>
<?//Проставляем name select-ам с уже выбранными свойствами?>
setTimeout(function(){
var SelectOption = $("#<?=$arItem['CODE']; ?> option:selected").attr('id');
$("#<?=$arItem['CODE']; ?>").attr('name',SelectOption);
},1500);
<?//заполнение name с реакцией на change?>
$("#<?=$arItem['CODE']; ?>").on('change', function(){
var SelectOption = $("#<?=$arItem['CODE']; ?> option:selected").attr('id');
$("#<?=$arItem['CODE']; ?>").attr('name',SelectOption);
})
<?endif?>
<?endforeach?>
});
</script>
При внесении данного кода в фильтре, появились дубли параметров в ссылках. К примеру выбрав 1 свойство отфильтровав и отменив фильтрацию по нему получаем ссылку
Заур Чавтараев пишет: При внесении данного кода в фильтре, появились дубли параметров в ссылках. К примеру выбрав 1 свойство отфильтровав и отменив фильтрацию по нему получаем ссылку