AJAX-форма обратной связи на 1С-Битрикс — отправка без перезагрузки

8 мин чтения
Форму обратной связи на сайте под управлением 1С-Битрикс можно отправлять через AJAX без перезагрузки страницы, сохранять каждую заявку в информационный блок и одновременно отправлять уведомление администратору сайта.

Такой вариант подходит для формы обратного звонка, заявки на услугу, запроса коммерческого предложения и других подобных форм.

В результате получаем следующую схему:

  1. Пользователь заполняет форму.
  2. JavaScript отправляет данные через AJAX.
  3. PHP-обработчик проверяет полученные данные.
  4. Заявка сохраняется в информационный блок.
  5. Битрикс создаёт почтовое событие и отправляет уведомление.
  6. Пользователь получает сообщение об успешной отправке без перезагрузки страницы.

1. Создаём информационный блок для заявок

Первым делом создадим отдельный информационный блок, в котором будут храниться обращения пользователей.

Например, назовём его:


Заявки с сайта

В информационном блоке создадим следующие свойства:

  • NAME — имя пользователя;
  • PHONE — телефон;
  • EMAIL — электронная почта;
  • PAGE — страница, с которой была отправлена заявка.
Сам текст сообщения можно записывать в поле анонса элемента, поэтому отдельное свойство для него создавать необязательно.

После создания инфоблока запомните его ID. Он понадобится в PHP-обработчике.

Например, далее будем считать, что ID нашего инфоблока:


12

Разумеется, в рабочем проекте его необходимо заменить на ID своего инфоблока.

2. Создаём тип почтового события

Теперь необходимо создать почтовое событие, через которое администратор сайта будет получать уведомления о новых заявках.

В административной панели Битрикс переходим в раздел почтовых событий и создаём новый тип.

Например:


NEW_FEEDBACK

Для события можно определить следующие поля:


#NAME# - Имя
#PHONE# - Телефон
#EMAIL# - E-mail
#MESSAGE# - Сообщение
#PAGE# - Страница отправки

После этого создаём почтовый шаблон и привязываем его к событию NEW_FEEDBACK.

Например, текст письма может выглядеть так:


На сайте получена новая заявка.

Имя: #NAME#
Телефон: #PHONE#
E-mail: #EMAIL#

Сообщение:
#MESSAGE#

Страница:
#PAGE#

В поле получателя указываем адрес, на который должны приходить заявки.

3. Добавляем HTML-форму

Теперь создадим саму форму.

Она может находиться непосредственно на странице, в шаблоне сайта или внутри модального окна.

Пример формы:


<form id="feedback-form">

    <?=bitrix_sessid_post()?>

    <div class="form-group">
        <label for="feedback-name">Ваше имя</label>
        <input
            type="text"
            name="name"
            id="feedback-name"
            class="form-control"
            required
        >
    </div>

    <div class="form-group">
        <label for="feedback-phone">Телефон</label>
        <input
            type="text"
            name="phone"
            id="feedback-phone"
            class="form-control"
            required
        >
    </div>

    <div class="form-group">
        <label for="feedback-email">E-mail</label>
        <input
            type="email"
            name="email"
            id="feedback-email"
            class="form-control"
        >
    </div>

    <div class="form-group">
        <label for="feedback-message">Сообщение</label>
        <textarea
            name="message"
            id="feedback-message"
            class="form-control"
            rows="5"
        ></textarea>
    </div>

    <input
        type="hidden"
        name="page"
        id="feedback-page"
        value=""
    >

    <div class="form-group">
        <label>
            <input
                type="checkbox"
                name="agree"
                value="Y"
                required
            >
            Я согласен на обработку персональных данных
        </label>
    </div>

    <div class="feedback-result"></div>

    <button
        type="submit"
        class="feedback-submit"
    >
        Отправить
    </button>

</form>

Здесь используются стандартные HTML-атрибуты required и type="email", поэтому базовую проверку заполнения формы браузер выполнит самостоятельно.

Дополнительно в форму добавлен:


<?=bitrix_sessid_post()?>

Он добавляет идентификатор сессии Битрикс, который позже проверим на стороне сервера.

4. Отправляем форму через AJAX

В этом примере используем jQuery, который часто уже подключён на проектах 1С-Битрикс.

JavaScript-код будет перехватывать отправку формы и передавать её данные PHP-обработчику:


$(document).on('submit', '#feedback-form', function(e) {

    e.preventDefault();

    var $form = $(this);
    var $button = $form.find('.feedback-submit');
    var $result = $form.find('.feedback-result');

    $('#feedback-page').val(window.location.href);

    $result
        .removeClass('success error')
        .html('');

    $button.prop('disabled', true);

    $.ajax({
        url: '/local/ajax/feedback.php',
        type: 'POST',
        data: $form.serialize(),
        dataType: 'json'
    })
    .done(function(response) {

        if (response.status) {

            $result
                .addClass('success')
                .html(response.message);

            $form[0].reset();

        } else {

            $result
                .addClass('error')
                .html(response.message);
        }

    })
    .fail(function() {

        $result
            .addClass('error')
            .html('При отправке формы произошла ошибка. Попробуйте ещё раз.');

    })
    .always(function() {

        $button.prop('disabled', false);

    });

});

При отправке формы происходит следующее:

  1. Стандартная отправка формы блокируется через preventDefault().
  2. В скрытое поле записывается URL текущей страницы.
  3. Кнопка отправки временно блокируется.
  4. Данные формы передаются в PHP-файл через POST-запрос.
  5. Ответ сервера ожидается в формате JSON.
  6. При успешной отправке форма очищается.
  7. Пользователю выводится результат выполнения запроса.
Блокировка кнопки дополнительно защищает от случайного многократного нажатия во время выполнения AJAX-запроса.

5. Создаём PHP-обработчик формы

Создадим файл:


/local/ajax/feedback.php

В нём подключим ядро Битрикс, модуль информационных блоков, проверим данные и создадим новый элемент инфоблока.

Пример обработчика:


<?php

define('NO_KEEP_STATISTIC', true);
define('NO_AGENT_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);

require_once(
    $_SERVER['DOCUMENT_ROOT']
    . '/bitrix/modules/main/include/prolog_before.php'
);

use Bitrix\Main\Application;
use Bitrix\Main\Loader;
use Bitrix\Main\Mail\Event;
use Bitrix\Main\Web\Json;

header('Content-Type: application/json; charset=UTF-8');

$result = [
    'status' => false,
    'message' => ''
];

try {

    if (!check_bitrix_sessid()) {
        throw new RuntimeException(
            'Сессия устарела. Обновите страницу и попробуйте ещё раз.'
        );
    }

    if (!Loader::includeModule('iblock')) {
        throw new RuntimeException(
            'Не удалось подключить модуль информационных блоков.'
        );
    }

    $request = Application::getInstance()
        ->getContext()
        ->getRequest();

    $name = trim((string)$request->getPost('name'));
    $phone = trim((string)$request->getPost('phone'));
    $email = trim((string)$request->getPost('email'));
    $message = trim((string)$request->getPost('message'));
    $page = trim((string)$request->getPost('page'));
    $agree = $request->getPost('agree');

    if ($name === '') {
        throw new RuntimeException(
            'Укажите ваше имя.'
        );
    }

    if ($phone === '') {
        throw new RuntimeException(
            'Укажите номер телефона.'
        );
    }

    if (
        $email !== ''
        && !filter_var($email, FILTER_VALIDATE_EMAIL)
    ) {
        throw new RuntimeException(
            'Укажите корректный e-mail.'
        );
    }

    if ($agree !== 'Y') {
        throw new RuntimeException(
            'Необходимо подтвердить согласие на обработку персональных данных.'
        );
    }

    $nameSafe = htmlspecialcharsbx($name);
    $phoneSafe = htmlspecialcharsbx($phone);
    $emailSafe = htmlspecialcharsbx($email);
    $messageSafe = htmlspecialcharsbx($message);
    $pageSafe = htmlspecialcharsbx($page);

    $properties = [
        'NAME' => $nameSafe,
        'PHONE' => $phoneSafe,
        'EMAIL' => $emailSafe,
        'PAGE' => $pageSafe
    ];

    $element = new CIBlockElement();

    $elementId = $element->Add([
        'IBLOCK_ID' => 12,
        'ACTIVE' => 'Y',
        'NAME' => 'Заявка от '
            . $nameSafe
            . ' '
            . date('d.m.Y H:i:s'),
        'PREVIEW_TEXT' => $messageSafe,
        'PROPERTY_VALUES' => $properties
    ]);

    if (!$elementId) {
        throw new RuntimeException(
            'Не удалось сохранить заявку: '
            . $element->LAST_ERROR
        );
    }

    Event::send([
        'EVENT_NAME' => 'NEW_FEEDBACK',
        'LID' => defined('SITE_ID') ? SITE_ID : 's1',
        'C_FIELDS' => [
            'NAME' => $nameSafe,
            'PHONE' => $phoneSafe,
            'EMAIL' => $emailSafe,
            'MESSAGE' => $messageSafe,
            'PAGE' => $pageSafe
        ]
    ]);

    $result = [
        'status' => true,
        'message' => 'Спасибо! Ваша заявка отправлена.'
    ];

} catch (Throwable $e) {

    $result = [
        'status' => false,
        'message' => $e->getMessage()
    ];

}

echo Json::encode($result);

die();

Обратите внимание на строку:


'IBLOCK_ID' => 12,

Здесь необходимо указать ID информационного блока, созданного для хранения заявок.

А коды:


NAME
PHONE
EMAIL
PAGE

должны совпадать с символьными кодами свойств вашего инфоблока.

6. Что делает PHP-обработчик?

Логика обработчика состоит из нескольких этапов:

  1. Подключается ядро 1С-Битрикс.
  2. Проверяется идентификатор сессии.
  3. Подключается модуль iblock.
  4. Получаются данные POST-запроса.
  5. Проверяются обязательные поля.
  6. Проверяется формат e-mail.
  7. Проверяется согласие пользователя.
  8. Создаётся новый элемент информационного блока.
  9. Запускается почтовое событие.
  10. Результат возвращается в JavaScript в формате JSON.
Ключевое поле ответа:


status

Если заявка успешно сохранена, оно получает значение:


true

При ошибке возвращается:


false

JavaScript на основании этого значения показывает соответствующее сообщение пользователю.

7. Отправка почтового уведомления

Для отправки сообщения используется метод:


Bitrix\Main\Mail\Event::send()

Ему передаётся код созданного ранее почтового события:


'EVENT_NAME' => 'NEW_FEEDBACK'

и массив данных:


'C_FIELDS' => [
    'NAME' => $nameSafe,
    'PHONE' => $phoneSafe,
    'EMAIL' => $emailSafe,
    'MESSAGE' => $messageSafe,
    'PAGE' => $pageSafe
]

Названия ключей должны соответствовать переменным, которые были добавлены в тип почтового события.

Например, значение:


'PHONE' => $phoneSafe

будет доступно в почтовом шаблоне как:


#PHONE#

8. Добавляем стили для результата отправки

Для сообщений об успешной отправке и ошибках можно добавить простые стили:


.feedback-result {
    margin: 15px 0;
}

.feedback-result.success {
    color: #198754;
}

.feedback-result.error {
    color: #dc3545;
}

.feedback-submit:disabled {
    opacity: 0.6;
    cursor: default;
}

Разумеется, внешний вид формы можно полностью изменить под дизайн проекта.

9. Проверяем работу формы

После настройки рекомендуется последовательно проверить:

  1. Отправляется ли AJAX-запрос.
  2. Возвращает ли PHP-обработчик корректный JSON.
  3. Создаётся ли новый элемент в инфоблоке.
  4. Записываются ли свойства элемента.
  5. Создаётся ли почтовое событие.
  6. Приходит ли письмо на указанный адрес.
Если элемент в инфоблоке создаётся, а письмо не приходит, необходимо отдельно проверять работу почтовых событий и отправки почты на сервере.

10. Что ещё стоит добавить в рабочий проект?

Для реальной формы обратной связи также имеет смысл предусмотреть:

  • защиту от спама и автоматических отправок;
  • ограничение частоты запросов;
  • маску или дополнительную проверку номера телефона;
  • логирование ошибок;
  • проверку длины передаваемых значений;
  • отдельную политику обработки персональных данных;
  • при необходимости — CAPTCHA.
Нельзя полагаться только на JavaScript-валидацию, так как запрос к PHP-обработчику можно отправить напрямую.

Поэтому обязательные проверки должны выполняться и на стороне сервера.

Итог

AJAX-форма обратной связи на 1С-Битрикс состоит из трёх основных частей:

  • HTML-форма, которую заполняет пользователь;
  • JavaScript, отправляющий данные без перезагрузки страницы;
  • PHP-обработчик, который проверяет данные, сохраняет заявку и создаёт почтовое событие.
Такую основу легко адаптировать под форму обратного звонка, заявку с карточки товара, заказ услуги, запрос коммерческого предложения или любую другую форму на сайте.
Вернуться к блогу