Разработка квиз-формы на 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка квиз-формы на 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    813
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка квиз-формы на 1С-Битрикс

Квиз-форма — это опросник с вопросами, который в конце предлагает пользователю получить результат (персональное предложение, расчёт, рекомендацию) в обмен на контактные данные. Конверсия квизов часто выше обычных форм в 2–5 раз: пользователь уже вложил время в ответы и хочет получить результат. На 1С-Битрикс квиз реализуется как кастомный компонент с хранением состояния через сессию или localStorage.

Архитектура квиза

Квиз — последовательность шагов. Каждый шаг — вопрос с одним или несколькими вариантами ответа. Данные структурированы в инфоблоке или HL-блоке:

Инфоблок quizzes — квизы (один элемент = один квиз):

Свойство Код Тип
Заголовок результата RESULT_TITLE Строка
Текст CTA на форме CTA_TEXT Строка
Получатель заявок NOTIFY_EMAIL Строка
Тег лида в CRM CRM_TAG Строка
Изображение обложки COVER_IMAGE Файл

HL-блок b_hl_quiz_questions — вопросы:

class QuizQuestionTable extends \Bitrix\Main\ORM\Data\DataManager
{
    public static function getTableName(): string { return 'b_hl_quiz_questions'; }

    public static function getMap(): array
    {
        return [
            new IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
            new IntegerField('QUIZ_ID'),
            new IntegerField('SORT'),
            new StringField('TEXT'),              // Текст вопроса
            new StringField('TYPE'),              // single | multiple | image_choice
            new TextField('OPTIONS_JSON'),        // JSON: [{id, text, image?, weight?}]
            new BooleanField('IS_REQUIRED', ['values' => [false, true]]),
            new StringField('HINT'),              // Подсказка к вопросу (опционально)
        ];
    }
}

PHP-компонент квиза

// /local/components/local/quiz/class.php
namespace Local\Quiz;

class QuizComponent extends \CBitrixComponent
{
    public function executeComponent(): void
    {
        $quizId = (int)$this->arParams['QUIZ_ID'];

        // Загрузить квиз и вопросы
        $quiz      = \CIBlockElement::GetByID($quizId)->GetNext();
        $questions = QuizQuestionTable::getList([
            'filter' => ['QUIZ_ID' => $quizId],
            'order'  => ['SORT' => 'ASC'],
        ])->fetchAll();

        foreach ($questions as &$q) {
            $q['OPTIONS'] = json_decode($q['OPTIONS_JSON'], true) ?? [];
        }

        $this->arResult = [
            'QUIZ'      => $quiz,
            'QUESTIONS' => $questions,
            'TOTAL'     => count($questions),
        ];

        $this->includeComponentTemplate();
    }
}

Фронтенд: состояние и навигация

Квиз — SPA-подобный UI на одной странице. Состояние хранится в JS-объекте:

const quizState = {
    currentStep: 0,       // Текущий вопрос (0-indexed)
    answers: {},          // {questionId: [selectedOptionIds]}
    contactData: null,    // Данные из финальной формы
    startTime: Date.now(),
};

function goToStep(step) {
    document.querySelectorAll('.quiz-step').forEach(el => el.classList.remove('active'));
    document.querySelector(`.quiz-step[data-step="${step}"]`)?.classList.add('active');
    quizState.currentStep = step;
    updateProgressBar();
}

function selectOption(questionId, optionId, isMultiple) {
    if (!quizState.answers[questionId]) {
        quizState.answers[questionId] = [];
    }

    if (isMultiple) {
        const idx = quizState.answers[questionId].indexOf(optionId);
        if (idx === -1) {
            quizState.answers[questionId].push(optionId);
        } else {
            quizState.answers[questionId].splice(idx, 1);
        }
    } else {
        quizState.answers[questionId] = [optionId];
        // Автоматически переходим к следующему вопросу
        setTimeout(() => nextStep(), 300);
    }
}

function updateProgressBar() {
    const total    = parseInt(document.getElementById('quiz-total').value);
    const progress = ((quizState.currentStep) / total) * 100;
    document.getElementById('quiz-progress-fill').style.width = progress + '%';
}

Финальная форма и отправка

После последнего вопроса показываем форму с контактными данными. Отправка — AJAX:

async function submitQuiz(formData) {
    const payload = {
        quiz_id:    document.getElementById('quiz-id').value,
        answers:    quizState.answers,
        name:       formData.get('name'),
        phone:      formData.get('phone'),
        email:      formData.get('email'),
        time_spent: Math.round((Date.now() - quizState.startTime) / 1000),
        sessid:     BX.bitrix_sessid(),
    };

    const response = await fetch('/local/ajax/quiz_submit.php', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(payload),
    });

    const result = await response.json();
    if (result.success) {
        goToStep('result'); // Показать страницу результата
    }
}

Обработчик на сервере

// /local/ajax/quiz_submit.php

$data   = json_decode(file_get_contents('php://input'), true);
$quizId = (int)($data['quiz_id'] ?? 0);
$name   = htmlspecialchars($data['name'] ?? '');
$phone  = htmlspecialchars($data['phone'] ?? '');

// Сохранить ответы в HL-блок
QuizResponseTable::add([
    'QUIZ_ID'    => $quizId,
    'USER_IP'    => $_SERVER['REMOTE_ADDR'],
    'ANSWERS'    => json_encode($data['answers']),
    'TIME_SPENT' => (int)($data['time_spent'] ?? 0),
    'NAME'       => $name,
    'PHONE'      => $phone,
    'CREATED_AT' => new \Bitrix\Main\Type\DateTime(),
]);

// Создать лид в CRM
if (\Bitrix\Main\Loader::includeModule('crm')) {
    $quiz = \CIBlockElement::GetByID($quizId)->GetNext();
    $lead = new \CCrmLead(false);
    $lead->Add([
        'TITLE'              => 'Квиз: ' . $quiz['NAME'] . ' — ' . $name,
        'NAME'               => $name,
        'PHONE'              => [['VALUE' => $phone, 'VALUE_TYPE' => 'WORK']],
        'SOURCE_ID'          => 'WEB',
        'SOURCE_DESCRIPTION' => 'Квиз: ' . $quiz['NAME'],
        'COMMENTS'           => 'Ответы: ' . json_encode($data['answers'], JSON_UNESCAPED_UNICODE),
    ]);
}

echo json_encode(['success' => true]);

Аналитика квиза

HL-блок b_hl_quiz_stats хранит агрегированную статистику:

  • Сколько пользователей начали квиз.
  • На каком шаге бросают (позволяет улучшить слабые вопросы).
  • Конверсия: начали → завершили → оставили контакт.
// Зафиксировать начало квиза
QuizStatsTable::add([
    'QUIZ_ID'    => $quizId,
    'SESSION_ID' => session_id(),
    'STEP'       => 0,
    'EVENT'      => 'start',
    'CREATED_AT' => new \Bitrix\Main\Type\DateTime(),
]);

Сроки разработки

Вариант Состав Срок
Один квиз (статичный) Компонент, вопросы в коде, лид в CRM 3–5 дней
Квиз с управлением Инфоблок/HL-блок, управление вопросами через админку 5–8 дней
Полноценный конструктор Несколько квизов, ветвление, аналитика, A/B 12–18 дней