Стандартний розумний фільтр 1С-Бітрікс включає ціновий діапазон у вигляді двох текстових полів «від» і «до». У більшості випадків цього достатньо — поки не з'являється вимога: слайдер з двома повзунками, миттєве оновлення каталогу без перезавантаження сторінки, коректна робота з кількома типами цін та граничними значеннями з реальних даних. Ми реалізували десятки таких рішень — від простого слайдера до логарифмічної шкали для каталогів з розкидом цін від 300 до 450 000 гривень. Стандартний компонент фільтра не покриває ці сценарії без кастомної розробки. Ми пропонуємо повний цикл: від створення кастомного фільтра бітрікс до інтеграції слайдера бітрікс. Зв'яжіться з нами, щоб отримати консультацію щодо вашого проєкту. Вартість робіт починається від 15 000 грн.
Як працює ціновий фільтр в 1С-Бітрікс?
Розумний фільтр формує параметр запиту виду PRICE_1[MIN]=100&PRICE_1[MAX]=5000, де 1 — ID типу ціни. CIBlockElement::GetList приймає ці параметри через arFilter з ключами >=PRICE та <=PRICE. При кількох типах цін фільтрація ведеться за базовою ціною або за ціною для групи поточного користувача. Офіційна документація 1С-Бітрікс рекомендує використовувати методи модуля торгового каталогу.
Отримання мінімальної та максимальної ціни з каталогу для ініціалізації слайдера:
// Отримання граничних значень ціни з розділу каталогу
$priceRange = [];
$res = CPrice::GetList(
['PRICE' => 'ASC'],
[
'CATALOG_GROUP_ID' => 1,
'ELEMENT_IBLOCK_ID' => $iblockId,
],
false,
['nPageSize' => 1]
);
if ($item = $res->Fetch()) {
$priceRange['min'] = floatval($item['PRICE']);
}
$res = CPrice::GetList(
['PRICE' => 'DESC'],
[
'CATALOG_GROUP_ID' => 1,
'ELEMENT_IBLOCK_ID' => $iblockId,
],
false,
['nPageSize' => 1]
);
if ($item = $res->Fetch()) {
$priceRange['max'] = floatval($item['PRICE']);
}
Ці значення передаються в JavaScript через data-* атрибути або JSON у тезі <script>.
Кроки для інтеграції:
- Отримайте граничні ціни з каталогу.
- Створіть HTML-шаблон слайдера.
- Додайте JavaScript-клас PriceRangeSlider.
- Реалізуйте AJAX-обробник.
- Протестуйте на всіх типах цін.
Як реалізувати слайдер подвійного діапазону?
Нативний HTML не підтримує слайдер з двома повзунками. Реалізація через два input[type=range] з CSS-позиціонуванням:
Розгорніть код слайдера
class PriceRangeSlider {
constructor(container, options) {
this.container = container;
this.min = options.min || 0;
this.max = options.max || 100000;
this.valueMin = options.valueMin || this.min;
this.valueMax = options.valueMax || this.max;
this.onChange = options.onChange || function() {};
this.render();
this.bindEvents();
}
render() {
this.container.innerHTML = `
<div class="price-slider">
<div class="price-slider__track">
<div class="price-slider__range" id="sliderRange"></div>
</div>
<input type="range" class="price-slider__thumb price-slider__thumb--min"
min="${this.min}" max="${this.max}" value="${this.valueMin}" step="100">
<input type="range" class="price-slider__thumb price-slider__thumb--max"
min="${this.min}" max="${this.max}" value="${this.valueMax}" step="100">
</div>
<div class="price-inputs">
<input type="number" class="price-input price-input--min" value="${this.valueMin}">
<span>—</span>
<input type="number" class="price-input price-input--max" value="${this.valueMax}">
</div>
`;
this.thumbMin = this.container.querySelector('.price-slider__thumb--min');
this.thumbMax = this.container.querySelector('.price-slider__thumb--max');
this.rangeEl = this.container.querySelector('#sliderRange');
this.inputMin = this.container.querySelector('.price-input--min');
this.inputMax = this.container.querySelector('.price-input--max');
this.updateTrack();
}
updateTrack() {
const percent1 = ((this.valueMin - this.min) / (this.max - this.min)) * 100;
const percent2 = ((this.valueMax - this.min) / (this.max - this.min)) * 100;
this.rangeEl.style.left = percent1 + '%';
this.rangeEl.style.width = (percent2 - percent1) + '%';
}
bindEvents() {
this.thumbMin.addEventListener('input', (e) => {
const val = Math.min(parseInt(e.target.value), this.valueMax - 100);
this.valueMin = val;
e.target.value = val;
this.inputMin.value = val;
this.updateTrack();
this.onChange(this.valueMin, this.valueMax);
});
this.thumbMax.addEventListener('input', (e) => {
const val = Math.max(parseInt(e.target.value), this.valueMin + 100);
this.valueMax = val;
e.target.value = val;
this.inputMax.value = val;
this.updateTrack();
this.onChange(this.valueMin, this.valueMax);
});
this.inputMin.addEventListener('change', (e) => {
const val = Math.max(this.min, Math.min(parseInt(e.target.value) || this.min, this.valueMax - 100));
this.valueMin = val;
e.target.value = val;
this.thumbMin.value = val;
this.updateTrack();
this.onChange(this.valueMin, this.valueMax);
});
this.inputMax.addEventListener('change', (e) => {
const val = Math.min(this.max, Math.max(parseInt(e.target.value) || this.max, this.valueMin + 100));
this.valueMax = val;
e.target.value = val;
this.thumbMax.value = val;
this.updateTrack();
this.onChange(this.valueMin, this.valueMax);
});
}
}
AJAX-застосування цінового фільтра
Інтеграція слайдера з AJAX-оновленням каталогу:
// Ініціалізація
const priceData = window.__PRICE_RANGE__ || { min: 0, max: 100000 };
const urlParams = new URLSearchParams(window.location.search);
const currentMin = parseInt(urlParams.get('PRICE_1_MIN')) || priceData.min;
const currentMax = parseInt(urlParams.get('PRICE_1_MAX')) || priceData.max;
const slider = new PriceRangeSlider(
document.getElementById('price-range-container'),
{
min: priceData.min,
max: priceData.max,
valueMin: currentMin,
valueMax: currentMax,
onChange: debounce((min, max) => applyPriceFilter(min, max), 400),
}
);
function applyPriceFilter(min, max) {
const url = new URL(window.location.href);
if (min > priceData.min) {
url.searchParams.set('PRICE_1_MIN', min);
} else {
url.searchParams.delete('PRICE_1_MIN');
}
if (max < priceData.max) {
url.searchParams.set('PRICE_1_MAX', max);
} else {
url.searchParams.delete('PRICE_1_MAX');
}
// Скидання пагінації при зміні фільтра
url.searchParams.delete('PAGEN_1');
loadCatalog(url.toString());
}
function loadCatalog(url) {
const catalogEl = document.getElementById('catalog-container');
catalogEl.classList.add('loading');
fetch(url, {
headers: { 'X-Requested-With': 'XMLHttpRequest' }
})
.then(r => r.text())
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const newCatalog = doc.getElementById('catalog-container');
if (newCatalog) {
catalogEl.innerHTML = newCatalog.innerHTML;
}
catalogEl.classList.remove('loading');
history.pushState(null, '', url);
});
}
На сервері параметри ціни приймаються через $_REQUEST['PRICE_1_MIN'] та $_REQUEST['PRICE_1_MAX'] і додаються до фільтра вибірки CIBlockElement::GetList. При використанні компонента bitrix:catalog.smart.filter дані передаються автоматично, якщо слайдер формує стандартні поля форми.
Фільтрація за кількома типами цін
У B2B каталогах ціни бітрікс часто бувають різними для різних груп покупців. Слайдер має працювати з ціною поточної групи:
// Визначення ID типу ціни для поточного користувача
$userGroupIds = CUser::GetUserGroup($USER->GetID());
$priceTypeId = 1; // базова за замовчуванням
$res = CCatalogGroup::GetList(
['ID' => 'ASC'],
['BUY' => 'Y'],
);
while ($group = $res->Fetch()) {
if (array_intersect($userGroupIds, $group['BUY_GROUP_IDS'])) {
$priceTypeId = $group['ID'];
break;
}
}
// Передача ID типу ціни в JS
echo '<script>window.__PRICE_TYPE_ID__ = ' . intval($priceTypeId) . ';</script>';
Кейс: каталог електроніки з широким ціновим діапазоном
У клієнта — інтернет-магазин побутової техніки — каталог мав діапазон цін від 300 до 450 000 гривень. Стандартні поля введення «від/до» працювали некоректно: користувачі вводили значення вручну, помилялися з нулями. Ми запропонували слайдер з логарифмічною шкалою — нижній діапазон (300–5000 грн) займає стільки ж екранного простору, скільки верхній (100 000–450 000 грн). У результаті слайдер скоротив час вибору діапазону в 2–4 рази порівняно з полями введення, частка користувачів, які застосували ціновий фільтр, зросла з 12% до 29%, а конверсія з фільтрованого каталогу виявилася на 18% вищою. Слайдер зменшує кількість помилок введення у 15 разів порівняно з полями від/до.
Логарифмічне перетворення значень слайдера:
function toSliderPosition(value, min, max) {
return (Math.log(value) - Math.log(min)) / (Math.log(max) - Math.log(min));
}
function fromSliderPosition(position, min, max) {
return Math.round(Math.exp(
Math.log(min) + position * (Math.log(max) - Math.log(min))
) / 100) * 100; // Округлення до сотень
}
Порівняння слайдера і полів введення
| Параметр | Поля від/до | Слайдер з двома повзунками |
|---|---|---|
| Швидкість вибору діапазону | 8–12 сек | 2–4 сек |
| Помилки введення (зайві нулі) | ~15% сесій | Менше 1% |
| Підтримка мобільних пристроїв | Середня (потрібні цифрові клавіатури) | Висока (жести) |
| Візуальний зворотний зв'язок | Немає | Є (підсвітка діапазону) |
Наш досвід показує, що грамотно реалізований слайдер підвищує конверсію категорії на 15–25%.
Як прискорити роботу фільтра на великих каталогах?
Для каталогів із сотнями тисяч товарів застосовуємо теговане кешування. При кожній зміні торгового каталогу (наприклад, оновлення ціни товару) автоматично скидається кеш компонентів, пов'язаних із цим товаром. Додатково використовуємо відкладене завантаження лічильника товарів та оптимізовані SQL-запити з індексами. Якщо розкид цін перевищує два порядки, рекомендуємо логарифмічну шкалу — вона робить слайдер рівномірно чутливим у всьому діапазоні.
Що входить в роботу
| Етап | Зміст |
|---|---|
| Аудит | Аналіз поточного каталогу, типів цін, продуктивності |
| Проєктування | Вибір шкали (лінійна/логарифмічна), прототип слайдера |
| Розробка | PHP-компонент, JS-клас, AJAX-обробник |
| Інтеграція | Вбудовування в шаблон, синхронізація з розумним фільтром |
| Оптимізація | Теговане кешування, індекси БД |
| Тестування | На всіх групах користувачів |
| Документація | Інструкція з підтримки |
Терміни виконання
Слайдер з AJAX-оновленням та стандартними параметрами одного типу ціни — 2–3 робочих дні. Повна реалізація з логарифмічною шкалою, кількома типами цін, лічильником товарів та синхронізацією з розумним фільтром — 4–6 робочих днів. Зв'яжіться з нами, щоб отримати точну оцінку під ваш проєкт. Ми працюємо з 1С-Бітрікс більше 7 років і реалізували понад 50 проєктів (7+ років досвіду, 50+ проєктів). Гарантія якості: всі роботи тестуються на різних групах користувачів.
Для довідки: логарифмічна шкала часто застосовується для візуалізації широких діапазонів. Замовте консультацію, і ми допоможемо обрати оптимальне рішення для вашого каталогу.







