Добавляем в блок к объектами дополнительные атрибуты:
<?php $products = $this->macros('catalog', 'getSmartCatalogCustom', array('', PAGE_ID, CATALOG_PER_PAGE, false, 10, SORT_FIELD, IS_ASC_DIRECTION, OBJECT_TYPE_ID)); $total = getArrayKey($products, 'total'); ?> <ul id="objects" data-total="<?=$total?>" data-module="catalog" data-category_id="<?=PAGE_ID;?>" data-type_id="<?=OBJECT_TYPE_ID;?>">
В шаблоне категории вызываем шаблон фильтра:
<?= $this->render($variables,'modules/catalog/blocks/category/filter'); ?>
Шаблон фильтра:
<?php /** @var umiTemplaterPHP|ViewPhpExtension|AjaxExtension|DemomarketPhpExtension|UpmixExtension $this */?> <?php /** @var array $variables */?> <!-- noindex --> <div id="filter" style="display:none"></div> <!-- /noindex -->
Создаем файл:
templates/xxx/php/ajax/templates/catalog/filter.phtml
Содержимое:
<?php /** @var umiTemplaterPHP|ViewPhpExtension|AjaxExtension|DemomarketPhpExtension|UpmixExtension $this */?> <?php /** @var array $variables */?> <?php $filter = $this->macros('catalog', 'getSmartFiltersCustom', array('default', PAGE_ID, 0, 15, OBJECT_TYPE_ID)); ?> <form class="catalog_filter"> <?= $this->render($filter,'modules/catalog/blocks/category/getSmartFiltersCustom'); ?> <div class="filter-buttons"> <input class="filtr-btn" type="submit" value="Показать" /> <input class="reset-btn" type="reset" value="Сбросить фильтр" /> </div> </form> <div class="goods-num" id="js_count_block"> <div class="top-triangle"></div> <div class="bottom-triangle"></div> <div class="clear-after goods-count-wp" > <div class="goods-count">Найдено товаров: <span id="js_filtered_count"></span></div> <div class="show-btn-wp"><span id="js_show_objects" class="btn-order">Показать</span></div> </div> <div class="form-btn-wp"><span class="js_close_filter">Скрыть фильтр</span><span class="js_reset_filter_mobile">Сбросить фильтр</span></div> </div>
Создаем файл
templates/xxx/php/modules/catalog/blocks/category/getSmartFiltersCustom.phtml
Содержимое:
<?php /** @var umiTemplaterPHP|ViewPhpExtension|AjaxExtension|DemomarketPhpExtension|UpmixExtension $this */?> <?php /** @var array $variables */?> <?php $filter = $variables; $groups = $filter["group"] ?? null; if (!empty($groups)){ foreach ($groups as $group){ //if ($group['name'] == 'tovar_dnya' || $group['name'] == 'manage_options') continue; //можно убрать некоторые группы из фильтра $filterGroup[$group['name']] = $group['field']; foreach ($filterGroup[$group['name']] as $field){ $key = $field["name"]; //убираем физ фильтра ненужные поля if ($key=='razmer_lista' and ROOT_TYPE!='plitka') continue; //размер листа только в плитке if ($key=='common_quantity') continue; //количество не показываем if ($key=='tip') continue; //тип в фильтре не нужен if ($key=='diler' and !USER_IS_SV) continue; //поставщик для админа if ($key == 'price_rur_filter' or $key == 'cvet' or $key == 'material' or $key == 'forma_chipa' or $key == 'osobennosti'){ $filterGroupFirst[$group['name']][$key] = $field; } else { $filterGroupSecond[$group['name']][$key] = $field; } } } } ?> <?php if(!empty($filterGroupFirst)):?> <?php foreach ($filterGroupFirst as $keyGroup=>$group):?> <?php foreach ($group as $keyField=>$field):?> <?php if($keyField == 'price_rur_filter'):?> <?php if(isset($field['minimum'])):?> <?php echo($this->render(array('field' => $field), 'modules/catalog/blocks/category/filter/range')); ?> <?php endif;?> <?php else:?> <?php echo($this->render(array('field' => $field), 'modules/catalog/blocks/category/filter/checkbox')); ?> <?php endif;?> <?php endforeach;?> <?php endforeach;?> <?php endif;?> <?php if(!empty($filterGroupSecond)):?> <?php foreach ($filterGroupSecond as $keyGroup=>$group):?> <?php foreach ($group as $keyField=>$field):?> <?php if(!USER_IS_SV and $keyField=="diler") continue;?> <?php echo($this->render(array('field' => $field), 'modules/catalog/blocks/category/filter/checkbox')); ?> <?php endforeach;?> <?php endforeach;?> <?php endif;?>
Создаем файл для фильтров типа чекбокс:
templates/xxx/php/modules/catalog/blocks/category/filter/checkbox.phtml
Содержимое:
<?php /** @var umiTemplaterPHP|ViewPhpExtension|AjaxExtension|DemomarketPhpExtension|UpmixExtension $this */?> <?php /** @var array $variables */?> <?php $field = getArrayKey($variables, 'field'); $title = getArrayKey($variables, 'name') ?? $field['title']; $name = $field['name']; $tip = getArrayKey($field, 'tip') ?? false; $filter = getRequest('filter'); $sqlType = 'or'; if (isset($filter[$name])){ reset($filter[$name]); $sqlType = key($filter[$name]); if ($sqlType === 0){ //для старых ссылок filter[cvet][] $sqlType = 'or'; } } ?> <?php if(isset($field['item'])):?> <div class="clear-after filter-wp<?php if (isset($filter[$name])) echo ' open'?>"> <div class="filter-title-js"><span class="filtr-title"><?=$title?> <?php if($tip):?><i data-tooltip-content="#tooltip_content_<?=$name?>" class="tooltip fas fa-question-circle"></i><?php endif;?> <i class="<?php if (isset($filter[$name])) echo 'hidden '?>fas fa-chevron-down"></i><i class="<?php if (!isset($filter[$name])) echo 'hidden '?>fas fa-chevron-up"></i></span></div> <?php if($tip):?> <div class="tooltip_templates"> <span id="tooltip_content_<?=$name?>"> <?=$tip?> </span> </div> <?php endif;?> <?php if (count($field['item'])>7):?> <div class="filter-search"><input class="js_search" placeholder="поиск по свойствам" type="search"/></div> <?php endif;?> <?php //для некоторых фльтров делаем возможным искать сразу не нескольким характеритикам, например товары у которых есть сразу 2 цвета: белый и зеленый ?> <?php if($name=='cvet' or $name=='osobennosti' or $name=='primenenie' or $name=='material' or $name=='sort_kamnya'):?> <div class="checkbox-mode"> <span>Искать cвойства вместе</span> <span class="switch"> <span id="c_<?=$name?>_mode" data-name="<?=$name?>" data-value="<?=$sqlType?>" class="slider round mode_selector<?php if($sqlType=='and') echo(' checked')?>"></span> </span> </div> <?php endif;?> <div class="filter-box<?php if (count($field['item'])>7):?> scroll-pane<?php endif;?>" id="<?=$name?>"> <?php foreach($field["item"] as $key=>$item):?> <?php if (!isset($item['value'])) continue; $checkedKey = false; $id = $this->translitStr($item["value"]); $value = $item["value"]; if (isset($filter[$name])){ if (!empty($filter[$name][$sqlType])){ $checkedKey = array_search($value,$filter[$name][$sqlType]); } else { $checkedKey = array_search($value,$filter[$name]); //для старых ссылок filter[cvet][] } } ?> <div class="checkbox"> <input data-name="<?=$name?>" type="checkbox" id="c_<?=$name?>_<?=$id?>" name="filter[<?=$name?>][<?=$sqlType?>][<?=$key?>]" value="<?=$value?>" <?php if(isset($filter[$name]) and $checkedKey!==false) echo ' checked'?>> <label class="label" for="c_<?=$name?>_<?=$id?>"><?=$value?></label> </div> <?php endforeach;?> </div> </div> <?php endif?>
Создаем файл для фильтров типа ползунки:
templates/xxx/php/modules/catalog/blocks/category/filter/range.phtml
Содержимое:
<?php /** @var umiTemplaterPHP|ViewPhpExtension|AjaxExtension|DemomarketPhpExtension|UpmixExtension $this */?> <?php /** @var array $variables */?> <?php $field = getArrayKey($variables, 'field'); $title = getArrayKey($variables, 'name'); $name = $field["name"]; $filter = getRequest('filter'); $umiHierarchy = umiHierarchy::getInstance(); /* @var iUmiHierarchyElement $page */ $page = $umiHierarchy->getElement(PAGE_ID); $valueMin = $page->getValue('minimum_price') ?? $field["min"]; $valueMax = $page->getValue('maximum_price') ?? $field["max"]; $valueCurMin = $filter[$name]['from'] ?? $valueMin; $valueCurMax = $filter[$name]['to'] ?? $valueMax; $range = 'range_'.$name; ?> <div class="price-filtr filter-wp"> <?php if(!empty($title)):?><div><?=$title?></div><?php endif;?> <input type="hidden" id="<?= $range;?>" class="js_range_slider" data-min="<?= $valueMin;?>" data-max="<?= $valueMax;?>" data-curmin="<?= $valueCurMin;?>" data-curmax="<?= $valueCurMax;?>"> <div> <input type="text" maxlength="6" class="js_<?= $range;?>_from js_input_from" name="filter[<?= $name;?>][from]" value="<?php echo($valueCurMin);?>"> <label>₽<?=FILTER_EDIZM?></label> </div> <div class="right-align"> <input type="text" maxlength="6" class="js_<?= $range;?>_to js_input_to" name="filter[<?= $name;?>][to]" value="<?php echo($valueCurMax);?>"> <label>₽<?=FILTER_EDIZM?></label> </div> </div>
Создаем файл:
templates/xxx/js/custom/category/category.js
var $objectBlock = $('#objects'), //блок с объектами $filter = $('#filter'), //фильтр preloader = '<div id="js_loader" class="wait_for"><img src="/templates/xxx/images/loading.gif"/></div>', pageId = $objectBlock.data('category_id'), //ID категории typeId = $objectBlock.data('type_id'); //Тип товаров в категории $(document).ready(function() { if ($filter.length > 0) { reloadFilter(); } initInputFilters(); }); //изменение или добавление GET параметра function changeParam(sParam, paramValue) { var queryParameters = {}, queryString = location.search.substring(1), re = /([^&=]+)=([^&]*)/g, m; while (m = re.exec(queryString)) { queryParameters[decodeURIComponent(m[1])] = decodeURIComponent(m[2]); } queryParameters[sParam] = paramValue; return '?' + $.param(queryParameters); } //удаление GET параметра из строки запроса "p=1&filter[cena]=100" function removeParam(sParam) { var urlQueue = window.location.search.substring(1), rtn, param, params_arr = []; if (urlQueue !== "") { params_arr = urlQueue.split("&"); for (var i = params_arr.length - 1; i >= 0; i -= 1) { param = params_arr[i].split("=")[0]; if (param === sParam) { params_arr.splice(i, 1); } } rtn = params_arr.join("&"); if (rtn !== "") { rtn = '?' + rtn; } } else { rtn = ""; } return rtn; } //получение GET параметра function getUrlParameter(sParam) { var urlQueue = window.location.search.substring(1), sURLVariables = urlQueue.split('&'), sParameterName, i; for (i = 0; i < sURLVariables.length; i++) { sParameterName = sURLVariables[i].split('='); if (sParameterName[0] === sParam) { return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); } } } //пересчет количества товаров при выборе фильтров function recalcFiltredCount(element) { var $countBlock = $('#js_count_block'); //блок: выбрано 10 товаров. Показать var url_q = $filter.find('input[type!=hidden]').filter(function() { if (this.value !== "" && this.value !== '0') { //если значение не пустое-используем в расчете if ($(this).attr('name')==='filter[price_rur_filter][from]'){ //для слайдера if (this.value != $('#range_price_rur_filter').data('min')){ //если не изменялась минимальная цена - не учитываем return this.value; } } else if ($(this).attr('name')==='filter[price_rur_filter][to]'){ //если не изменялась максимальная цена - не учитываем if (this.value != $('#range_price_rur_filter').data('max')){ return this.value; } } else { return this.value; } } }).serialize(); if (url_q !== ''){ var url = "?" + url_q; } //запрос количества товаров $.ajax(url, { dataType: 'json', async:true, type: "POST", data: { template: 'catalog/filter-count', r: Math.random() }, success: function(response) { $('#js_show_objects').attr('href', '?' + url_q); //ссылка показать $('#js_filtered_count').text(response); //блок с количеством товара //расположение блока if ($(window).width() > 767) { if (typeof (element) !== "undefined"){ var Y = element.offset().top-210; var X = element.closest('.filter-wp').offset().left+239-$filter.offset().left; $countBlock.css('top', Y+'px'); $countBlock.css('left', X+'px'); $countBlock.show(); } } }, //конец успешной отправки error: function(xhr, ajaxOptions, thrownError) { console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); } }); } //показ фильтра function reloadFilter() { urlQueue = removeParam('p'); //убираем пагинацию $.ajax({ url: urlQueue, type: 'POST', async: true, data: { template: 'catalog/filter', r: Math.random() }, success: function (html) { $filter.html(html); $('#js_filtered_count').text($objectBlock.data('total')); $filter.fadeIn(700); initFilter(); }, error: function (xhr, ajaxOptions, thrownError) { console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); } }); } //инициализация слайдера с ценами и других range слайдеров function initFilter() { $('.js_range_slider').each(function() { var sliderName = $(this).attr('id'), $slider = $("#"+sliderName), $inputFrom = $(".js_"+sliderName+"_from"), $inputTo = $(".js_"+sliderName+"_to"), instance, min = $(this).data('min'), max = $(this).data('max'), from = $(this).data('curmin'), to = $(this).data('curmax'); $slider.ionRangeSlider({ skin: "round", type: "double", //postfix : 'm2', min: min, max: max, from: from, to: to, grid: false, onFinish: function (data) { $($inputFrom).val(data.from); $($inputTo).val(data.to); recalcFiltredCount($inputTo); processFilters($inputTo); } }); instance = $slider.data("ionRangeSlider"); $inputFrom.inputFilter(function(value) { return /^\d*$/.test(value); }); $inputFrom.on("input", function (e) { var val = $(this).prop("value"); if (val < min) { val = min; } else if (val > to) { val = to; } instance.update({ from: val }); recalcFiltredCount($inputTo); processFilters($(this)); }); $inputTo.inputFilter(function(value) { return /^\d*$/.test(value); }); $inputTo.on("input", function (e) { var val = $(this).prop("value"); if (val < from) { val = from; } else if (val > max) { val = max; } instance.update({ to: val }); recalcFiltredCount($inputTo); processFilters($(this)); }); }); $('.scroll-pane').jScrollPane({contentWidth: '0px'}); $('.tooltip').tooltipster({ theme: 'tooltipster-light', trigger: 'custom', triggerOpen: { mouseenter: true, touchstart: true }, triggerClose: { click: true, scroll: true, tap: true } }); } //пересчет фильтров - делаем значения неактивными, если они неприменимы function processFilters(e) { var name = e.data('name'); var url_q = $filter.find('input[type!=hidden]').filter(function() { if (this.value !== "" && this.value !== '0') { //если значение не пустое-используем в расчете return this.value; } }).serialize(); if (url_q !== '') url_q = '?' + url_q; var url = "/udata/catalog/getSmartFiltersCustom//"+pageId+"/0/15/"+typeId+"/.json" + url_q; $.getJSON(url, function(data){ $filter.find('.checkbox').find('input:not(:checked)').each(function(){ if ($(this).attr('name').indexOf(name) !== -1){ if($(this).attr('name').indexOf('[or]') === -1){ //если AND $(this).attr('disabled', true); $(this).parent().addClass('disabled'); } } else { $(this).attr('disabled', true); $(this).parent().addClass('disabled'); } }); $.each(data.group, function() { $.each(this.field, function() { var name = this.name; var items = this.item; $.each(items, function() { var value = this.value; $('#'+name).find('input').each(function(index, element){ if (this.value === value){ $(this).attr('disabled', false); $(this).parent().removeClass('disabled'); } }); }); }); }); }); } //изменение значений фильтра $filter.on('change', '.checkbox input', function (e) { processFilters($(this)); recalcFiltredCount($(this)); $(this).toggleClass('checked'); }); //Нажатие кнопки "показать" $filter.on('click', '#js_show_objects', function (e) { e.preventDefault(); var url = $(this).attr('href'); if ($(window).width() < 768) { $('.js_get_popup').trigger('click'); } else { $('#js_count_block').fadeOut(100); } processObjects(url, 'replace'); reloadFilter(); return false; }); //Галочка выбирать несколько $filter.on('click', '.mode_selector', function (e) { e.preventDefault(); $(this).toggleClass('checked'); var mode = $(this).data('value')==='or'?'and':'or'; $(this).data('value', mode); $(this).parents('.checkbox-mode').siblings('.filter-box').find('input').each(function() { $(this).attr('name', function(index, name) { if(mode==='or'){ return name.replace('[and]', '[or]'); } else { return name.replace('[or]', '[and]'); } }); $(this).attr('disabled', false); $(this).parent().removeClass('disabled'); }); processFilters($(this)); recalcFiltredCount($(this)); return false; }); //раскрытие-закрытие фильтра $filter.on('click', '.filter-title-js', function () { var $this = $(this); var $parent = $this.parent('div'); $parent.toggleClass('open'); $this.find('.fa-chevron-up').toggleClass('hidden'); $this.find('.fa-chevron-down').toggleClass('hidden'); $('.scroll-pane').jScrollPane({contentWidth: '0px'}); }); //перемещение выбранного значения вверх $filter.on('change', '.scroll-pane .checkbox input', function () { var $this = $(this); var $parent = $this.parent('div'); $parent.prependTo($parent.parent()); var api = $this.closest('.scroll-pane').data('jsp'); api.scrollToElement($this); }); //поиск по значениям фильтра $filter.on("keyup", '.js_search', function() { var value = $(this).val().toLowerCase(); $(this).parent().siblings('.scroll-pane').find("label").filter(function() { $(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1) }); }); //очистка строки поиска по фильтру $filter.on("click", '.js_clear', function() { var $input = $(this).siblings('input'); $input.val(''); $(this).parent().siblings('.scroll-pane').find('.checkbox').each(function() { $(this).fadeIn(); }); }); //обнуление фильтра $filter.on('click', '.reset-btn', function (e) { processObjects('', 'replace'); reloadFilter(); }); //скрытие фильтра на мобиле $filter.on('click', '.js_reset_filter_mobile', function (e) { $('.js_get_popup').trigger('click'); processObjects('', 'replace'); reloadFilter(); }); //обнуление фильтра на мобиле $filter.on('click', '.js_close_filter', function (e) { $('.js_get_popup').trigger('click'); }); // $('#show_filter').click(function () { $('#sidebar').slideToggle(300); $('.scroll-pane').jScrollPane({contentWidth: '0px'}); });
Создаем файл шаблона вывода количества отфильтрованных объектов
templates/xxx/php/ajax/templates/catalog/filter-count.phtml
Содержимое:
<?php /** @var umiTemplaterPHP|ViewPhpExtension|AjaxExtension|DemomarketPhpExtension|UpmixExtension $this */?> <?php /** @var array $variables */?> <?php $countArray = $this->macros('catalog', 'getSmartCatalogCustom', array('', PAGE_ID, 99999, 1, 15, '', '', OBJECT_TYPE_ID, 1)); $count = getArrayKey($countArray, 'total') ?? 0; echo ($count); ?>
Подключаем плагины:
http://ionden.com/a/plugins/ion.rangeSlider/ – для ползунков
http://jscrollpane.kelvinluck.com/examples/ – прокрутка в блоке с чекбоксами
https://iamceege.github.io/tooltipster/ – всплывающие подсказки
FontAwesome – понадобится brands и solid. Нет смысла все подключать.
Примерный CSS
.price-filtr{padding:20px 10px 40px 10px;} #slider{background-color:#e6e6e6;height:5px;} .filtr-title{color:#000;font-size:14px;font-weight:700;display:block;padding:10px;position:relative;cursor:pointer;line-height: 22px} .price-filtr label{color:#000;font-size:13px;font-weight:500;margin-left:3px;} .price-filtr div {width: 50%;float: left} .price-filtr input{width:50%;height:26px;border: 1px solid #b2b2b2;text-align:center;color:#000;font-size:13px;} .flex_price{display:flex;} .flex_price_body{display:flex;justify-content:space-between;align-items:center;} .slider-num{padding:17px 0 0 0;margin:0 0 12px 0;} .num1,.num2,.num3{color:#808080;font-size:12px;float:left;display:block;position:relative;top:-10px;} .num2{margin:0 0 0 111px;} .num3{float:right;} .checkbox-choice{position:relative;min-height:17px;margin:0 0 18px 10px;} .checkbox-choice label{color:#000;font-size:14px;} .checkbox-box{display:inline;position:relative;} .color-filtr{border-bottom:1px solid #dadada;} .filter-title-js{padding-right:10px;} .hided_more{margin-bottom:10px;} .cat-menu .more-cat-menu{padding:0;} .filtr-btn{width:122px;height:38px;border:none;background-color:#e6e6e6;cursor:pointer;color:#4b4b4b;font-size:14px;margin:42px 16px 0 0;} .reset-btn{border:none;background:none;cursor:pointer;color:#818181;font-size:13px;border-bottom:1px dashed #818181;padding:0;margin:54px 0 0 0;} .filtr-btn:hover{background-color:#C6BFBF;} .reset-btn:hover{border:none;} :focus::-moz-placeholder{color:transparent;} :focus:-moz-placeholder{color:transparent;} :focus:-ms-input-placeholder{color:transparent;} .scrollbar-inner{max-height:200px;display:none;} .open .scrollbar-inner{display:block;padding:10px 0;} .reset-btn{margin:17px auto 8px;display:block;} .filtr-btn{margin:42px auto 0;display:block;} @media screen and (max-width: 767px) { .goods-num { position: fixed; bottom: 0; z-index: 99999; width: 100%; background-color: #ffffff; border: 1px solid #9c9c9c; box-sizing: border-box; } .goods-count { float:left; width:calc(100% - 130px); padding: 0 0 0 10px; height: 60px; line-height: 60px; font-size:14px; font-weight: 700; } } .goods-count span{ color: #e35222; font-size:17px; font-weight: 700; } .form-btn-wp{ padding:10px 0; } .sidebar #filter { padding: 0 0 140px 0; } .form-btn-wp span{ display: inline-block; width: 50%; text-align: center; text-decoration: underline; cursor: pointer; } .form-btn-wp span:hover, .form-btn-wp span:active{ text-decoration: none; } .show-btn-wp { float:left; width:100px; margin:0 10px; } .filter-box { display: none; } .open .filter-box { display: block; } .scroll-pane { width: 100%; height: 200px; overflow: auto; padding: 7px 0; } .fa-times-circle { position: absolute; font-size: 20px; right: 20px; cursor: pointer; padding-top: 5px; color:#b2b2b2; } .hidden.fas {display: none} .filtr-title .fas{font-size: 22px;float:right;color:#0077c6} .filter-search {width:100%;height: 30px;border-bottom: 1px solid #b2b2b2;border-top: 1px solid #b2b2b2;display:none;background-color:#e9e9e9;} .checkbox-mode{display: none; text-align: center;padding:3px 0;} .open .filter-search, .open .checkbox-mode{display: block} .filter-search input {padding: 0 0 0 10px;width: calc(100% - 10px);height: 90%;border: none;background-color:#e9e9e9;} /* The switch - the box around the slider */ .switch { position: relative; display: inline-block; width: 60px; height: 34px; vertical-align: middle; } /* The slider */ .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #b2b2b2; -webkit-transition: .4s; transition: .4s; } .slider:before { position: absolute; content: ""; height: 26px; width: 26px; left: 4px; bottom: 4px; background-color: white; -webkit-transition: .4s; transition: .4s; } .slider.checked { background-color: #0077c6; } .slider:focus { box-shadow: 0 0 1px #0077c6; } .slider.checked:before { -webkit-transform: translateX(26px); -ms-transform: translateX(26px); transform: translateX(26px); } /* Rounded sliders */ .slider.round { border-radius: 34px; } .slider.round:before { border-radius: 50%; } .filter-wp { border-top: 1px solid #b2b2b2; } .checkbox { margin: 0 0 7px 10px; } .checkbox input{ width: 20px; height: 20px; vertical-align: middle; } .checkbox label{ display: inline-block; width:calc(100% - 30px); } .checkbox.disabled label{ color:#b2b2b2; } .jspTrack{ background-color: #e9e9e9; } .jspDrag { background-color: #b2b2b2; } .irs-from, .irs-to, .irs-single { background-color: #0077c6; } .irs-bar { height: 10px; top: 33px; border-top: 1px solid #0077c6; border-bottom: 1px solid #0077c6; background: #0077c6; background: linear-gradient(to top, rgba(0,119,198,1) 0%,rgba(129,195,231,1) 100%); /* W3C */ } .irs-bar-edge { height: 10px; top: 33px; width: 14px; border: 1px solid #0077c6; border-right: 0; background: #0077c6; background: linear-gradient(to top, rgba(0,119,198,1) 0%,rgba(129,195,231,1) 100%); /* W3C */ border-radius: 16px 0 0 16px; -moz-border-radius: 16px 0 0 16px; } .tooltip_templates { display: none; } .filtr-title i.tooltip { color:#b2b2b2; font-size: 16px; vertical-align: text-top; float:none; } #filter form .filter-search input { margin:0; } .jspPane .checkbox:first-child{ padding: 10px 0 0 0; } @media screen and (min-width: 768px){ .goods-num { position: absolute; z-index: 99999; display: none; } .form-btn-wp { display: none; } .goods-count-wp { border-top: 2px solid #0053a4; border-right: 2px solid #0053a4; border-bottom: 2px solid #0053a4; border-radius: 4px; width: 260px; height: 32px; margin-left: 18px; background-color: #fff; } .goods-count { float: left; font-size: 13px; line-height: 32px; padding: 0 0 0 10px; } .show-btn-wp { float: right; margin: 0; width: auto; } .goods-count-wp .btn-order { padding: 0 8px; height: 26px; margin: 2px 7px 0 5px; line-height: 26px; } .top-triangle { top: 3px; left: 3px; display: inline-block; width: 0; height: 0; border-style: solid; border-width: 15px 17px 15px 0; border-color: transparent #fff transparent transparent; position: absolute; z-index: 99999999; } .bottom-triangle { display: inline-block; width: 0; height: 0; border-style: solid; border-width: 18px 20px 18px 0; border-color: transparent #0053a4 transparent transparent; position: absolute; z-index: 99999998; } }
В файле
templates/xxx/classes/modules/catalog/FilterQueriesMakerCustom.php
Cоздаем функцию parseFiltersCustom:
public function parseFiltersCustom() { $allFilteredFields = $this->getAllFilteredFields(); $filters = getRequest('filter'); $event = new umiEventPoint('parse_filter'); $event->setMode('before'); $event->addRef('raw_filter', $filters); $event->setParam('queries_maker', $this); $event->call(); if (!$filters || !is_array($filters)) { return $this->setFilters([]); } $isNeedToShowSelectedValues = $this->isNeedToShowSelectedValues(); foreach ($filters as $key => $value) { //$type = array_key_first($value); //PHP 7.3 reset($value); $sqlType = key($value); if (!isset($allFilteredFields[$key])) { unset($filters[$key]); continue; } /* @var iUmiField $field */ $field = $allFilteredFields[$key]; if ($field->getDataType() == 'date') { foreach ($value as $type => $date) { if (!is_numeric($date) && is_string($date)) { $value[$type] = strtotime($date); } } } if ($sqlType === 'and' or $sqlType === 'or'){ $condition = $this->getCondition($field, $key, $value[$sqlType]); $condition = str_replace('OR', strtoupper($sqlType), $condition); } elseif($sqlType === 0) { // если заходят по старым ссылкам filter[cvet][] $condition = $this->getCondition($field, $key, $value[$sqlType]); } else { $condition = $this->getCondition($field, $key, $value); } if ($condition === null) { unset($filters[$key]); } else { $filters[$key] = $condition; } if (!$isNeedToShowSelectedValues) { continue; } $val = array(); if (is_array($value[$sqlType])) { $value = array_map('htmlspecialchars', $value[$sqlType]); } else { $value = [htmlspecialchars($value[$sqlType])]; } $val[$sqlType] = $value; $this->pushSelectedFilterValue($key, $val); } $event->setMode('after'); $event->addRef('processed_filter', $filters); $event->call(); return $filters; }
Добавляем в lib/extensions/UpmixExtension.php
public function translitStr($s) { $s = (string)$s; // преобразуем в строковое значение $s = strip_tags($s); // убираем HTML-теги $s = str_replace(array("\n", "\r"), " ", $s); // убираем перевод каретки $s = preg_replace("/\s+/", ' ', $s); // удаляем повторяющие пробелы $s = trim($s); // убираем пробелы в начале и конце строки $s = function_exists('mb_strtolower') ? mb_strtolower($s) : strtolower($s); // переводим строку в нижний регистр (иногда надо задать локаль) $s = strtr($s, array('а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'e', 'ж' => 'j', 'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'shch', 'ы' => 'y', 'э' => 'e', 'ю' => 'yu', 'я' => 'ya', 'ъ' => '', 'ь' => '')); $s = preg_replace("/[^0-9a-z-_ ]/i", "", $s); // очищаем строку от недопустимых символов $s = str_replace(" ", "-", $s); // заменяем пробелы знаком минус return $s; // возвращаем результат }
Добавляем файл: templates/xxx/php/ajax/templates/catalog/objects.phtml
Содержимое:
<?php $html = $this->render($variables, 'modules/catalog/category/blocks/object-list'); $response = $this->prepareAjaxResponseForTemplate($html); $this->sendAjaxResponse($response); ?>
Добавить комментарий