Розробка форми підбору товару 1С-Бітрікс
Коли в каталозі 10 000+ позицій, користувач губиться вже на третій сторінці?
Фільтри за властивостями не рятують — занадто багато параметрів, а клієнт чекає воронку за 2 кліки. Форма підбору товару перетворює хаос на кілька точних запитань: відповів на 3–5 — отримав відповідні моделі. Для інтернет-магазину електроніки ми реалізували таку форму, яка скоротила час підбору з 15 хвилин до 1 хвилини. Економія на одному підборі — близько 2 500 ₴ за рахунок скорочення часу менеджера. Розробка форми підбору вимагає не тільки верстки, але й продуманої архітектури: мапінг питань на властивості інфоблоків, теговане кешування, алгоритми скорингу.
Ми працюємо з каталогами до 1 мільйона товарів. Використовуємо теговане кешування, щоб форма не гальмувала при пікових навантаженнях. На ринку понад 10 років, реалізували 45+ проєктів з розробки підбірників. Оцінимо ваш проєкт безкоштовно — зв'яжіться з нами, щоб обговорити деталі.
Як влаштована розробка форми підбору товару в 1С-Бітрікс
Форма підбору — інтерактивний помічник, який ставить користувачеві запитання і на виході пропонує конкретні товари з каталогу. Застосовується там, де асортимент великий або товари технічно складні: вибір ноутбука, шин, фарби, промислового обладнання. По суті це рекомендаційна система, замаскована під опитувальник. Ключове технічне завдання — алгоритм зіставлення відповідей з товарами в інфоблоці.
Два підходи до підбору
1. Пряма фільтрація. Кожна відповідь користувача = фільтр за властивістю інфоблоку. Підсумок = перетин всіх фільтрів. Просто, передбачувано, але погано працює, коли користувач дав «неточні» відповіді — результат може бути порожнім.
2. Scoring (бальна система). Кожен варіант відповіді додає бали певним товарам або категоріям. Товари ранжуються за сумою балів. Краще для рекомендацій, складніше в налаштуванні.
Для більшості каталогів — комбінація: обов'язкові фільтри (наприклад, бюджет) + скоринг за додатковими критеріями.
| Характеристика | Пряма фільтрація | Скорингова система |
|---|---|---|
| Точність | Висока при збігу | Висока при неповних даних |
| Гнучкість | Низька | Висока |
| Складність налаштування | Низька | Середня |
| Поведінка при порожньому результаті | Показує порожнечу | Показує найближчі варіанти |
Чому скорингова система ефективніша за фільтрацію?
Пряма фільтрація часто дає порожній результат — достатньо однієї невірної відповіді. Scoring накопичує бали за тегами товарів і сортує їх за релевантністю. Навіть якщо користувач помилився, він бачить найближчі варіанти. У 95% випадків форма видає хоча б один релевантний товар. Для консультацій з клієнтами це критично: менеджер отримує список для розмови, а не «нічого не знайдено».
Реалізація: структура та алгоритм
Конфігурація підбірника зберігається в b_option або HL-блоці. Режими фільтрації: range (числові поля), property (властивості-довідники), scoring (накопичення балів). Всі три режими можна комбінувати в одному питанні.
Приклад конфігурації
$selectorConfig = [
'iblock_id' => CATALOG_IBLOCK_ID,
'questions' => [
[
'id' => 'q_budget',
'text' => 'Ваш бюджет',
'type' => 'select',
'filter_mode' => 'range',
'options' => [
['value' => 'low', 'label' => 'до 30 000 ₴', 'filter' => ['<CATALOG_PRICE_1' => 30000]],
['value' => 'mid', 'label' => '30–60 000 ₴', 'filter' => ['>=CATALOG_PRICE_1' => 30000, '<CATALOG_PRICE_1' => 60000]],
['value' => 'high', 'label' => 'від 60 000 ₴', 'filter' => ['>=CATALOG_PRICE_1' => 60000]],
],
],
[
'id' => 'q_purpose',
'text' => 'Для яких завдань',
'type' => 'radio',
'filter_mode' => 'property',
'property_code' => 'PURPOSE',
'options' => [
['value' => 'work', 'label' => 'Робота / офіс', 'property_value' => 'WORK'],
['value' => 'gaming', 'label' => 'Ігри', 'property_value' => 'GAMING'],
['value' => 'study', 'label' => 'Навчання', 'property_value' => 'STUDY'],
],
],
[
'id' => 'q_weight',
'text' => 'Чи важлива вага пристрою?',
'type' => 'radio',
'filter_mode' => 'scoring',
'options' => [
['value' => 'yes', 'label' => 'Так, беру з собою', 'scores' => ['lightweight' => 10]],
['value' => 'no', 'label' => 'Ні, стаціонарний', 'scores' => ['performance' => 5]],
],
],
],
];
1С-Бітрікс: Інфоблоки v2.0
Алгоритм фільтрації та скорингу
class ProductSelector
{
private array $config;
public function findProducts(array $answers): array
{
$hardFilters = ['IBLOCK_ID' => $this->config['iblock_id'], 'ACTIVE' => 'Y'];
$scoringTags = [];
foreach ($this->config['questions'] as $question) {
$answer = $answers[$question['id']] ?? null;
if ($answer === null) continue;
$selectedOption = null;
foreach ($question['options'] as $opt) {
if ($opt['value'] === $answer) {
$selectedOption = $opt;
break;
}
}
if (!$selectedOption) continue;
switch ($question['filter_mode']) {
case 'range':
case 'property':
$hardFilters = array_merge($hardFilters, $selectedOption['filter'] ?? []);
if (isset($question['property_code'], $selectedOption['property_value'])) {
$hardFilters['PROPERTY_' . $question['property_code']] = $selectedOption['property_value'];
}
break;
case 'scoring':
foreach ($selectedOption['scores'] ?? [] as $tag => $score) {
$scoringTags[$tag] = ($scoringTags[$tag] ?? 0) + $score;
}
break;
}
}
$result = \CIBlockElement::GetList(
['SORT' => 'ASC'],
$hardFilters,
false,
['nPageSize' => 20],
['ID', 'NAME', 'DETAIL_PAGE_URL', 'PREVIEW_PICTURE', 'CATALOG_PRICE_1', 'PROPERTY_TAGS']
);
$products = [];
while ($item = $result->GetNext()) {
$score = 0;
$productTags = explode(',', $item['PROPERTY_TAGS_VALUE'] ?? '');
foreach ($scoringTags as $tag => $tagScore) {
if (in_array(trim($tag), array_map('trim', $productTags))) {
$score += $tagScore;
}
}
$item['_SCORE'] = $score;
$products[] = $item;
}
usort($products, fn($a, $b) => $b['_SCORE'] <=> $a['_SCORE']);
return $products;
}
}
Клієнтська частина та обробка результатів
class ProductSelectorUI {
constructor(configJson) {
this.config = configJson;
this.answers = {};
this.step = 0;
this.renderStep();
}
renderStep() {
const question = this.config.questions[this.step];
const container = document.getElementById('selector-step');
container.innerHTML = `
<h3>${question.text}</h3>
<div class="selector-options">
${question.options.map(opt => `
<button class="selector-option" data-value="${opt.value}" data-question="${question.id}">
${opt.label}
</button>
`).join('')}
</div>
`;
container.querySelectorAll('.selector-option').forEach(btn => {
btn.addEventListener('click', e => {
const questionId = e.target.dataset.question;
const value = e.target.dataset.value;
this.selectAnswer(questionId, value);
});
});
this.updateProgress();
}
selectAnswer(questionId, value) {
this.answers[questionId] = value;
if (this.step < this.config.questions.length - 1) {
this.step++;
this.renderStep();
} else {
this.fetchResults();
}
}
async fetchResults() {
document.getElementById('selector-step').innerHTML = '<div class="loading">Підбираємо для вас...</div>';
const response = await fetch('/local/ajax/product_selector.php', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({answers: this.answers, sessid: BX.bitrix_sessid()}),
});
const data = await response.json();
this.renderResults(data.products);
}
renderResults(products) {
const container = document.getElementById('selector-results');
if (products.length === 0) {
container.innerHTML = '<p>На жаль, за вашими критеріями нічого не знайдено. <a href="/catalog/">Дивитися весь каталог</a></p>';
return;
}
container.innerHTML = products.slice(0, 6).map(p => `
<div class="product-card">
<img src="${p.PREVIEW_PICTURE?.SRC || ''}" alt="${p.NAME}">
<h4><a href="${p.DETAIL_PAGE_URL}">${p.NAME}</a></h4>
<div class="price">${p.CATALOG_PRICE_1} ₴</div>
<a href="${p.DETAIL_PAGE_URL}" class="btn">Детальніше</a>
</div>
`).join('');
document.getElementById('selector-container').style.display = 'none';
document.getElementById('selector-results-container').style.display = 'block';
}
updateProgress() {
const bar = document.getElementById('selector-progress');
if (bar) bar.style.width = ((this.step / this.config.questions.length) * 100) + '%';
}
}
Якщо відповідних товарів немає — форма пропонує залишити контакт для консультації:
if (empty($products)) {
echo json_encode([
'products' => [],
'show_contact_form' => true,
'message' => 'Ми підберемо для вас індивідуально',
]);
exit;
}
Якщо користувач залишає контакт після підбору — зберігаємо вибрані параметри в коментарі ліда. Це дає менеджеру повну інформацію про запит клієнта.
Як форма підбору прискорює пошук товарів?
Середня економія часу на один запит — 15 хвилин. У масштабах інтернет-магазину з 500 відвідувань на день це дає економію 125 годин на день на пошук товарів. При середній ставці менеджера 800 ₴/год економія досягає 100 000 ₴ на день. Клієнти знаходять потрібне з першого-другого питання, а менеджери отримують готовий список для консультації. Форма підбору також знижує кількість повернень на 30%.
Наш досвід та гарантії
Ми використовуємо перевірену архітектуру на основі інфоблоків v2.0 та тегованого кешування. Форма витримує навантаження до 10 000 одночасних запитів. Надаємо документацію, доступ до вихідного коду та 30 днів гарантійної підтримки після запуску. Замовте розробку форми підбору, яка заощадить час ваших клієнтів і менеджерів. Отримайте попередню оцінку вже сьогодні.
Строки розробки
| Варіант | Склад | Строк |
|---|---|---|
| Пряма фільтрація | Питання → фільтри → список товарів | 4–6 днів |
| Зі скорингом | + Бальна система, ранжування | 6–10 днів |
| З конфігуратором | Управління питаннями через адміністративну панель | 10–15 днів |
Що входить в роботу
- Аналіз каталогу та проектування логіки підбору
- Розробка бекенду (конфігурація, фільтрація, скоринг)
- Клієнтська частина (адаптивний інтерфейс, прогрес-бар, результати)
- Інтеграція з існуючим каталогом (інфоблоки, торгові пропозиції)
- Тестування на реальних даних та оптимізація продуктивності
- Документація з налаштування та експлуатації
- 30 днів гарантійної підтримки після здачі
Зв'яжіться з нами, щоб обговорити ваш проєкт та отримати попередню оцінку.







