Интересный вопрос и сейчас я его раскрою.
Дело в том, что в системе для того, чтобы сформировать данный ползунок нужно каким-то образом получить максимальную и минимальную цену в зависимости от категории и применённых фильтров. По умолчанию мы не поддерживаем такое получение и не возвращаем сведений, поэтому придётся немного поколдовать, чтобы получить данные.
Первое что надо сделать это получить данные во фронт контроллере списка товаров, т.к. именно в нём применяются все фильтры. Соответственно там мы и должны получать данные.
Нам надо сделать копию файла
/modules/catalog/controller/front/listproducts.inc.php с таким же именем, но окончанием .my.inc.php
т.е.
/modules/catalog/controller/front/listproducts.my.inc.php
Откроем его и посмотрим в метод actionIndex().
Нам надо заменить:
$basefilter = $this->api->applyBaseFilters();
$total = $this->api->getMultiDirCount();
$this->api->queryObj()->groupby($this->api->defAlias().'.id');
//Устанавливаем сортировку
$sort_field = $this->cur_sort == 'rank' ? $this->cur_sort : $this->api->defAlias().'.'.$this->cur_sort;
$this->api->setSortOrder($sort_field, $this->cur_n_sort);
На:
/**
* @var \RS\Orm\Request
*/
$minmaxQuery = clone $this->api->queryObj();
$basefilter = $this->api->applyBaseFilters();
$total = $this->api->getMultiDirCount();
//Добавим цены к запросу
$current_cost_type = \Catalog\Model\CostApi::getUserCost(); //Текущий тип цен
$current_cost_type = \Catalog\Model\CostApi::getInstance()->getManualType($current_cost_type);
$minmaxQuery->leftjoin(new \Catalog\Model\Orm\Xcost(), "A.id = XC.product_id AND XC.cost_id='{$current_cost_type}'", 'XC');
$minmaxQuery->orderby('');
$minmaxQuery->select = 'max(XC.cost_val) interval_to,min(XC.cost_val) interval_from';
$moneyArray = $minmaxQuery->exec()->fetchRow();
$moneyArray['step'] = 1;
$moneyArray['round'] = 1;
$moneyArray['unit'] = \Catalog\Model\CurrencyApi::getDefaultCurrency()->stitle;
$moneyArray['heterogeneity'] = $this->getHeterogeneity($moneyArray['interval_from'],$moneyArray['interval_to']);
$this->router->getCurrentRoute()->money_array = $moneyArray;
$this->api->queryObj()->groupby($this->api->defAlias().'.id');
$this->api->setSortOrder($this->api->defAlias().'.'.$this->cur_sort, $this->cur_n_sort);
В указанном выше кусочке кода мы получаем массив $moneyArray на основе запроса максимальной и минимальной цены для формирования данных, которые нам понадобятся в шаблоне.
Эти значения мы поместим в наш класс роута который будет доступен по данному url в любом блок контроллере с помощью
$this->router->getCurrentRoute()->money_array = $moneyArray;
Это нам понадобится, чтобы передать в блок контроллер фильтров данные значения. Т.к. первым отработает фронт контроллер, то после него отработают блок контроллеры из обёртки. А это позволит нам передать туда наши данные для дальнейшего помещения в шаблон.
Функция getHeterogeneity это функция, которая подготавливает массив для рисочек нашего ползунка.
Теперь добавим эту функцию в наш класс.
/**
* Получает риски для цен диапозона цен
*
* @return string
*/
function getHeterogeneity($min,$max){
$max = floatval($max);
$min = floatval($min);
//Проверим возможно ли это
if ($max==$min) return "";
$delta = $max-$min;
$d25 = ceil($min + (($delta/100)*25));
$d50 = ceil($min + (($delta/100)*50));
$d75 = ceil($min + (($delta/100)*75));
return '"25/'.$d25.'","50/'.$d50.'","75/'.$d75.'"';
}
С этой часть мы покончили. Теперь нам необходимо перейти к блок контроллеру фильтров в которых обработать наши сведения и поместить в шаблон фильтров дополнительные сведения.
Для этого делаем копию блок контроллера фильтров
/modules/catalog/controller/block/sidefilters.inc.php
и также
/modules/catalog/controller/block/sidefilters.my.inc.php
И заходим в класс SideFilters нашего нового файла в метод actionIndex().
Добавим в шаблон в массив через $this->view->assign новый элемента массива
$this->view->assign(array(
...
'moneyArray' => $this->router->getCurrentRoute()->money_array,
...
));
Троеточие используется для примера данных.
Теперь нам нужен шаблон "blocks/sidefilters/filters.tpl" (У каждой темы соответственно в своей папке).
Строки, которые отвечают у нас за отображение фильтра надо заменить на:
{if $param.show_cost_filter}
<div class="priceFilter typeInterval">
<span class="title">Цена:</span>
<div class="typeInterval fromToPrice">
<input type="hidden" class="textinp fromto" name="bfilter[cost][from]" value="{$basefilters.cost.from}" data-start-value="">
<input type="hidden" class="textinp fromto" name="bfilter[cost][to]" value="{$basefilters.cost.to}" data-start-value="">
</div>
<div class="priceInterval fromToLine">
<input type="hidden" data-slider='{ "from":{$moneyArray.interval_from}, "to":{$moneyArray.interval_to}, "step": "{$moneyArray.step}", "round": {$moneyArray.round}, "dimension": " {$moneyArray.unit}", "heterogeneity": [{$moneyArray.heterogeneity}] }' value="{$basefilters.cost.from|default:$moneyArray.interval_from};{$basefilters.cost.to|default:$moneyArray.interval_to}" class="pluginInput" data-closest=".fromToPrice" data-start-value="{$basefilters.cost.from|default:$moneyArray.interval_from};{$basefilters.cost.to|default:$moneyArray.interval_to}">
</div>
<input type="submit" value="Применить" class="onemore submitFilter" style="display:none;"/>
</div>
{/if}
html у нас готов теперь надо активировать js.
В примере я воспользуюсь нашим стандартным слайдером (jslider - jquery.slider.min.js), который есть во всех наших темах.
У нас это указано так.
<script type="text/javascript">
$(function() {
$('.typeInterval .pluginInput').each(function() {
var $this = $(this);
var fromTo = $($this.data('closest'));
fromTo.hide();
$this.jslider( $.extend( $(this).data('slider'), { callback: function(value) {
var values = value.split(';');
$('input[name$="[from]"]', fromTo).val(values[0]);
$('input[name$="[to]"]', fromTo).val(values[1]);
$this.trigger('change');
}}));
$('input[name$="[from]"], input[name$="[to]"]', fromTo).change(function() {
var from = $('input[name$="[from]"]', fromTo).val();
var to = $('input[name$="[to]"]', fromTo).val();
$this.jslider('value', from, to);
});
});
</script>