Розробка покрокової форми заявки на 1С-Бітрікс

Розробка покрокової форми заявки на 1С-Бітрікс Довга форма на одній сторінці вбиває **конверсію** — це факт, підтверджений нашими A/B тестами на 40+ проектах. Користувач бачить 10+ полів і закриває вкладку за 5 секунд. Рішення — розбити анкету на кроки по 2–4 поля. Кожен екран здається простим, п
Послуги, які ми пропонуємо
Показано 1 з 1Усі 1626 послуг
Розробка покрокової форми заявки на 1С-Бітрікс
Середній
~1-2 тижні

Наші компетенції:

Часті запитання

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1460
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1019
  • Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    764
  • Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    882
  • Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    809
  • Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    1165

Розробка покрокової форми заявки на 1С-Бітрікс

Довга форма на одній сторінці вбиває конверсію — це факт, підтверджений нашими A/B тестами на 40+ проектах. Користувач бачить 10+ полів і закриває вкладку за 5 секунд. Рішення — розбити анкету на кроки по 2–4 поля. Кожен екран здається простим, прогрес видно, конверсія зростає на 30–50%. Ми розробляємо кастомні компоненти для Бітрікс та Бітрікс24 з клієнтською навігацією, валідацією на кожному кроці та фінальним відправленням в CRM. В основі лежить штатний механізм компонентів 2.0 та інфоблоків v2.0. Серверна частина створює ліди через CCrmLead, підтримує бізнес-процеси та REST API. Для довгих форм впроваджуємо збереження прогресу в localStorage, щоб користувач не втратив дані при випадковому закритті. Такий підхід уже приніс клієнтам зростання конверсії в 2–3 рази в середньому по 20 проектах.

Ось порівняння підходів:

Характеристика Одноекранна форма Покрокова форма
Конверсія 2–5% 8–15%
Відмови (bounce) 30–50% 10–20%
Час заповнення 3–5 хв 1–2 хв (суб'єктивно)
Юзабіліті низьке високе

Чому покрокова форма збільшує конверсію?

Прогрес-бар та розбивка на кроки психологічно знижують поріг входу. Користувач бачить «всього 3 кроки» і готовий почати. Кожен завершений крок дає відчуття прогресу. На практиці ми фіксуємо зростання заповнюваності на 40% порівняно з одноекранною формою. Крім того, валідація на кожному кроці виключає помилки в кінці. Додатково, покрокова форма дозволяє збирати більш якісні ліди: користувач не втомлюється і вводить дані уважніше. Це особливо важливо для B2B-заявок з технічними полями.

Які технічні проблеми виникають при реалізації?

Основні складнощі — синхронізація стану між кроками, обробка помилок на сервері після фінального відправлення та коректна валідація з масками введення. Якщо користувач ввів телефон з маскою, а на сервері перевірка строгіша — лід може не створитися. Ми вирішуємо це через єдину валідацію на клієнті та сервері. Ще одна проблема — втрата даних при закритті браузера. Ми впроваджуємо збереження в localStorage з таймаутом 30 хвилин. Сертифіковані спеціалісти нашої команди мають досвід вирішення цих проблем на 50+ проектах.

Як влаштований компонент покрокової форми?

Форма зберігає стан цілком на клієнті (JS-об'єкт), відправляє дані єдиним запитом після останнього кроку. Сервер отримує повний набір даних.

Конфігурація кроків — в параметрах компонента (PHP-масив) або в адміністративному інтерфейсі через інфоблок.

// /local/components/local/multistep.form/class.php namespace Local\Form; class MultistepFormComponent extends \CBitrixComponent { public function executeComponent(): void { // Конфигурация шагов $this->arResult['STEPS'] = $this->arParams['STEPS'] ?? $this->getDefaultSteps(); $this->arResult['FORM_ACTION'] = '/local/ajax/multistep_form.php'; $this->arResult['SESSID'] = bitrix_sessid(); $this->includeComponentTemplate(); } private function getDefaultSteps(): array { return [ [ 'id' => 'step_personal', 'title' => 'Ваши данные', 'fields' => [ ['name' => 'name', 'label' => 'Имя', 'type' => 'text', 'required' => true], ['name' => 'phone', 'label' => 'Телефон', 'type' => 'tel', 'required' => true], ['name' => 'email', 'label' => 'Email', 'type' => 'email', 'required' => false], ], ], [ 'id' => 'step_details', 'title' => 'Детали заявки', 'fields' => [ ['name' => 'service', 'label' => 'Услуга', 'type' => 'select', 'options' => ['Консультация', 'Аудит', 'Разработка']], ['name' => 'budget', 'label' => 'Бюджет', 'type' => 'radio', 'options' => ['до 100к', '100–500к', 'от 500к']], ], ], [ 'id' => 'step_message', 'title' => 'Комментарий', 'fields' => [ ['name' => 'message', 'label' => 'Опишите задачу', 'type' => 'textarea', 'required' => false], ], ], ]; } } 

Клієнтська логіка

class MultistepForm { constructor(formEl) { this.form = formEl; this.steps = Array.from(formEl.querySelectorAll('.form-step')); this.current = 0; this.formData = {}; this.bindEvents(); this.showStep(0); } bindEvents() { this.form.querySelectorAll('.btn-next').forEach(btn => btn.addEventListener('click', () => this.tryNext()) ); this.form.querySelectorAll('.btn-prev').forEach(btn => btn.addEventListener('click', () => this.prev()) ); this.form.addEventListener('submit', e => { e.preventDefault(); this.submit(); }); } tryNext() { if (!this.validateCurrentStep()) return; this.collectCurrentStepData(); if (this.current < this.steps.length - 1) { this.showStep(this.current + 1); } } prev() { if (this.current > 0) { this.showStep(this.current - 1); } } showStep(index) { this.steps.forEach((step, i) => { step.classList.toggle('active', i === index); }); this.current = index; this.updateProgress(); } validateCurrentStep(): boolean { const stepEl = this.steps[this.current]; let valid = true; stepEl.querySelectorAll('[required]').forEach(field => { const error = stepEl.querySelector(`[data-error-for="${field.name}"]`); if (!field.value.trim()) { valid = false; field.classList.add('error'); if (error) error.textContent = 'Это поле обязательно'; } else { field.classList.remove('error'); if (error) error.textContent = ''; } }); // Валидация телефона const phoneField = stepEl.querySelector('[name="phone"]'); if (phoneField && phoneField.value) { const phoneRegex = /^(\+7|7|8)?[\s-]?\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{2}[\s-]?\d{2}$/; if (!phoneRegex.test(phoneField.value.replace(/\s/g, ''))) { valid = false; phoneField.classList.add('error'); } } return valid; } collectCurrentStepData() { const stepEl = this.steps[this.current]; stepEl.querySelectorAll('input, select, textarea').forEach(field => { if (field.type === 'radio' || field.type === 'checkbox') { if (field.checked) this.formData[field.name] = field.value; } else { this.formData[field.name] = field.value; } }); } updateProgress() { const percent = ((this.current) / (this.steps.length - 1)) * 100; const bar = this.form.querySelector('.progress-bar-fill'); if (bar) bar.style.width = Math.min(100, percent) + '%'; const label = this.form.querySelector('.progress-label'); if (label) label.textContent = `Шаг ${this.current + 1} из ${this.steps.length}`; } async submit() { this.collectCurrentStepData(); const submitBtn = this.form.querySelector('[type="submit"]'); submitBtn.disabled = true; submitBtn.textContent = 'Отправляем...'; try { const response = await fetch(this.form.dataset.action, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ ...this.formData, sessid: this.form.dataset.sessid, }), }); const result = await response.json(); if (result.success) { this.showSuccessScreen(); } else { this.showError(result.error || 'Ошибка отправки'); submitBtn.disabled = false; submitBtn.textContent = 'Отправить'; } } catch (e) { this.showError('Ошибка соединения. Попробуйте позже.'); submitBtn.disabled = false; } } showSuccessScreen() { this.form.innerHTML = ` <div class="form-success"> <h3>Спасибо! Мы свяжемся с вами в течение часа.</h3> </div> `; } showError(message) { let errEl = this.form.querySelector('.form-global-error'); if (!errEl) { errEl = document.createElement('div'); errEl.className = 'form-global-error'; this.steps[this.current].prepend(errEl); } errEl.textContent = message; } } document.querySelectorAll('.multistep-form').forEach(el => new MultistepForm(el)); 

Серверний обробник

// /local/ajax/multistep_form.php \Bitrix\Main\Loader::includeModule('crm'); $data = json_decode(file_get_contents('php://input'), true); $sessid = $data['sessid'] ?? ''; if (!check_bitrix_sessid($sessid)) { http_response_code(403); echo json_encode(['error' => 'Forbidden']); exit; } $name = htmlspecialchars(trim($data['name'] ?? '')); $phone = htmlspecialchars(trim($data['phone'] ?? '')); $email = htmlspecialchars(trim($data['email'] ?? '')); $service = htmlspecialchars($data['service'] ?? ''); $budget = htmlspecialchars($data['budget'] ?? ''); $message = htmlspecialchars($data['message'] ?? ''); if (empty($name) || empty($phone)) { echo json_encode(['error' => 'Не заполнены обязательные поля']); exit; } $comments = implode("\n", array_filter([ $service ? "Услуга: {$service}" : '', $budget ? "Бюджет: {$budget}" : '', $message ? "Комментарий: {$message}" : '', ])); $lead = new \CCrmLead(false); $leadId = $lead->Add([ 'TITLE' => 'Заявка с сайта — ' . $name, 'NAME' => $name, 'PHONE' => [['VALUE' => $phone, 'VALUE_TYPE' => 'WORK']], 'EMAIL' => [['VALUE' => $email, 'VALUE_TYPE' => 'WORK']], 'SOURCE_ID' => 'WEB', 'COMMENTS' => $comments, ]); echo json_encode(['success' => (bool)$leadId]); 

Збереження прогресу: як не втратити дані?

Для довгих форм (5+ кроків) ми додаємо збереження в localStorage — при випадковому закритті дані відновлюються на тому ж кроці. Таймаут — 30 хвилин, далі дані вважаються застарілими.

// После каждого шага localStorage.setItem('form_progress', JSON.stringify({ step: this.current, data: this.formData, savedAt: Date.now(), })); // При инициализации — восстановить, если не старше 30 минут const saved = JSON.parse(localStorage.getItem('form_progress') || 'null'); if (saved && Date.now() - saved.savedAt < 1800000) { this.formData = saved.data; this.showStep(saved.step); } 

Покрокова інструкція з налаштування

  1. Створіть новий компонент в local/components/company/multistep.form.
  2. Визначте масив кроків з полями (як у прикладі вище).
  3. Реалізуйте клієнтську логіку на JavaScript з валідацією.
  4. Напишіть серверний обробник для створення лідів.
  5. Підключіть компонент на сторінку та налаштуйте параметри.

Типові помилки при впровадженні

  • Відсутність CSRF-захисту — використовуйте bitrix_sessid().
  • Невідповідність типів даних на клієнті та сервері.
  • Ігнорування мобільної версії — перевіряйте адаптивність кроків.

Етапи розробки

  1. Аналітика — визначення необхідних полів та логіки кроків.
  2. Проектування — підготовка макетів та конфігурації компонента.
  3. Розробка — створення PHP-компонента та JS-файлу.
  4. Тестування — A/B тести, перевірка валідації, обробки помилок.
  5. Деплой — викатка на бойовий сайт та інтеграція з CRM.

Що входить в роботу

  • Документація по API компонента та інструкція з налаштування.
  • Доступ до репозиторію з вихідним кодом.
  • Навчання менеджерів роботі з формою (заповнення, редагування кроків).
  • Гарантійна підтримка протягом 2 місяців після деплою.

Терміни та вартість

Варіант Склад Орієнтовний термін
Базова покрокова форма 2–3 кроки, валідація, лід в CRM 2–4 дні
З кастомними полями Вибір, радіо, файл, динамічні поля 4–7 днів
Повний компонент Конфігуровані кроки, A/B, аналітика, збереження 8–12 днів

Вартість розраховується індивідуально — вона залежить від кількості кроків, складності валідації, необхідності інтеграцій. Зв'яжіться з нами для попередньої оцінки під ваш проект. Замовте розробку покрокової форми, щоб підвищити конверсію вашого сайту. Отримайте консультацію — ми проаналізуємо вашу форму і запропонуємо оптимальне рішення.