Розробка мультикрокової форми зворотного зв'язку 1С-Бітрікс
Ситуації, коли мультикрокова форма незамінна — розробка мультикрокової форми
Ми не раз стикалися з ситуацією: клієнт просить «форму зворотного зв'язку», а після релізу з'ясовується, що потрібно збирати контекст — тип проблеми, номер замовлення, прикріплювати скріншоти. Звичайна форма не справляється: поля або всі видно одразу, або користувач плутається. Мультикрокова з умовною логікою — єдиний спосіб отримати структуроване звернення без перевантаження користувача. Наприклад, в одному проекті для інтернет-магазину ми реалізували форму з 5 типами звернень, кожен зі своїм набором полів. Після впровадження кількість неповних звернень знизилася на 40%.
Що відрізняє її від покрокової форми-воронки?
Мета — не продаж, а збір технічної інформації. Тип звернення визначає наступні кроки. Це вже не просто форма, а mini-Service Desk.
Як працює умовна логіка?
Користувач обирає тип звернення на першому кроці: «Технічне питання», «Питання щодо оплати», «Скарга» або «Інше». Після вибору динамічно підвантажуються релевантні поля. Наприклад, при виборі «Технічне питання» з'являються поля «Продукт», «Опис помилки» та завантаження скріншоту. При виборі «Питання щодо оплати» — поля «Номер замовлення», «Сума» та тип проблеми. Конфігурація кроків задається в JSON – це дозволяє змінювати логіку без переписування коду:
{
"steps": [
{
"id": "type",
"fields": [{"name": "type", "type": "select", "options": [...]}]
},
{
"id": "technical",
"showWhen": {"field": "type", "value": "technical"},
"fields": [{"name": "product", "type": "text"}, {"name": "error", "type": "textarea"}]
}
]
}
Реалізація на JavaScript — проста, без зовнішніх бібліотек. Нижче — контролер ConditionalMultistepForm, який розраховує шлях кроків на основі відповідей.
class ConditionalMultistepForm {
constructor(config) {
this.config = config;
this.answers = {};
this.stepsPath = this.calculatePath();
this.currentIndex = 0;
}
calculatePath() {
return this.config.steps.filter(step => {
if (!step.showWhen) return true;
const {field, value} = step.showWhen;
const answer = this.answers[field];
return Array.isArray(value) ? value.includes(answer) : answer === value;
});
}
handleAnswer(fieldName, value) {
this.answers[fieldName] = value;
this.stepsPath = this.calculatePath();
}
get currentStep() {
return this.stepsPath[this.currentIndex] ?? null;
}
get totalSteps() {
return this.stepsPath.length;
}
canGoNext() {
const step = this.currentStep;
if (!step) return false;
return step.fields
.filter(f => f.required)
.every(f => !!this.answers[f.name]);
}
next() {
if (!this.canGoNext()) return false;
if (this.currentIndex < this.stepsPath.length - 1) {
this.currentIndex++;
return true;
}
return false;
}
prev() {
if (this.currentIndex > 0) {
this.currentIndex--;
}
}
isLastStep() {
return this.currentIndex === this.stepsPath.length - 1;
}
getSubmitData() {
return {
type: this.answers.type,
answers: this.answers,
};
}
}
Конфігурація кроків задається в JSON — це дозволяє змінювати логіку без переписування коду.
Чому варто довірити розробку нашим інженерам?
У нас за плечима 10+ років досвіду розробки на Бітрікс та Бітрікс24. Ми реалізували десятки мультикрокових форм для інтернет-магазинів, техпідтримки та корпоративних порталів. Кожна форма — це не просто код, а продумана архітектура: резервне копіювання, теговане кешування, обробка помилок. Ми гарантуємо, що форма працюватиме при високих навантаженнях. Наприклад, для одного клієнта з каталогом із 50 000 товарів форма обробляє до 200 звернень на день без сповільнень.
Що входить у роботу?
| Етап | Склад | Результат |
|---|---|---|
| Аналіз | Інтерв'ю з вами, вивчення типів звернень | Технічне завдання з описом кроків та умов |
| Проектування | JSON-конфіг, прототип інтерфейсу | UX-макет та архітектура даних |
| Розробка | Бекенд: PHP-обробники, інтеграція з CRM; фронтенд: JS-контролер, верстка | Робоча форма з умовною логікою |
| Інтеграція | Підключення до 1С (якщо потрібно), налаштування сповіщень | Форма записує дані в CRM або пошту |
| Тестування | Перевірка всіх сценаріїв, включаючи граничні | Звіт про тестування |
| Документація | Інструкція з налаштування полів та умов | PDF-документ |
Як обробляються файли?
Користувач може прикріпити скріншот. Ми реалізували завантаження на сервер одразу при виборі файлу — це зручніше, ніж завантажувати все в кінці. Файл зберігається через CFile::SaveFile, повертається file_id, який передається при фінальному відправленні.
// /local/ajax/upload_temp_file.php
if (!$_FILES['file'] || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
echo json_encode(['error' => 'Помилка завантаження']);
exit;
}
$allowedMime = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
if (!in_array($_FILES['file']['type'], $allowedMime)) {
echo json_encode(['error' => 'Неприпустимий тип файлу']);
exit;
}
$fileId = \CFile::SaveFile([
'name' => $_FILES['file']['name'],
'size' => $_FILES['file']['size'],
'tmp_name' => $_FILES['file']['tmp_name'],
'type' => $_FILES['file']['type'],
], 'feedback_forms');
echo json_encode(['file_id' => $fileId]);
Як дані потрапляють у CRM?
Залежно від типу звернення створюється угода або лід у Бітрікс24. Ми використовуємо REST API для надійної інтеграції.
- Технічне питання → угода у воронці «Підтримка»
- Питання щодо оплати → лід із прив'язкою до замовлення
- Скарга → лід із позначкою
switch ($type) {
case 'technical':
$deal = new \CCrmDeal(false);
$deal->Add([
'TITLE' => 'Тех. звернення: ' . $data['answers']['product'] ?? '',
'CATEGORY_ID' => CRM_SUPPORT_PIPELINE_ID,
'STAGE_ID' => 'C' . CRM_SUPPORT_PIPELINE_ID . ':NEW',
'COMMENTS' => $data['answers']['error_text'] ?? '',
'CONTACT_ID' => $this->findOrCreateContact($data),
]);
break;
// ... інші типи
}
Як налаштувати сповіщення?
При створенні звернення відповідальний менеджер отримує лист через поштову подію FEEDBACK_NEW_TICKET. Шаблон листа налаштовується в адміністративній панелі Бітрікс.
\Bitrix\Main\Mail\Event::send([
'EVENT_NAME' => 'FEEDBACK_NEW_TICKET',
'LID' => SITE_ID,
'C_FIELDS' => [
'TYPE' => $typeLabel,
'NAME' => $data['answers']['name'],
'EMAIL' => $data['answers']['email'],
'TEXT' => json_encode($data['answers'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
],
'TO_EMAIL' => FEEDBACK_MANAGER_EMAIL,
]);
Порівняння: умовна форма проти звичайної
| Параметр | Звичайна форма | Мультикрокова з умовами |
|---|---|---|
| Кількість полів на екрані | Всі одразу | Тільки релевантні |
| Ризик покинути заповнення | Високий (довга форма) | Низький (покроково) |
| Якість даних | Низька (обов'язкові поля пропускають) | Висока (контекст зібрано) |
| Час на розробку | 1–2 дні | 3–10 днів |
Терміни розробки
| Варіант | Склад | Термін |
|---|---|---|
| Базова мультикрокова | 2–3 кроки, тип звернення, лід у CRM | 3–5 днів |
| З умовною логікою | Різні поля за типом, завантаження файлів | 6–10 днів |
| Повний Service Desk | + Особистий кабінет, статуси звернень, SLA | 15–25 днів |
Приклад JSON-конфігурації кроків
{
"steps": [
{
"id": "type",
"fields": [
{
"name": "type",
"type": "select",
"options": [
{"value": "technical", "label": "Технічне питання"},
{"value": "payment", "label": "Питання щодо оплати"},
{"value": "complaint", "label": "Скарга"}
]
}
]
},
{
"id": "technical",
"showWhen": {"field": "type", "value": "technical"},
"fields": [
{"name": "product", "type": "text", "label": "Продукт", "required": true},
{"name": "error", "type": "textarea", "label": "Опис помилки", "required": true},
{"name": "screenshot", "type": "file", "label": "Скріншот"}
]
},
{
"id": "payment",
"showWhen": {"field": "type", "value": "payment"},
"fields": [
{"name": "order_id", "type": "text", "label": "Номер замовлення", "required": true},
{"name": "amount", "type": "number", "label": "Сума", "required": true},
{"name": "issue", "type": "select", "label": "Тип проблеми", "options": [
{"value": "refund", "label": "Повернення"},
{"value": "delay", "label": "Затримка"}
]}
]
}
]
}
Якщо у вас залишилися питання — зв'яжіться з нами, ми безкоштовно оцінимо ваш проект і запропонуємо оптимальне рішення. Отримайте консультацію — напишіть нам, і ми покажемо, як це працює на вашому проекті.







