Разработка мультишаговой формы обратной связи 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": "Задержка"}
]}
]
}
]
}
Если у вас остались вопросы — свяжитесь с нами, мы бесплатно оценим ваш проект и предложим оптимальное решение. Получите консультацию — напишите нам, и мы покажем, как это работает на вашем проекте.







