Отправка сообщения






Ajax форма обратной связи на bitrix

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

Теперь давайте приступим непосредственно к примеру. Первым делом, что требуется нам сделать, это подготовить информационный блок, в который будут записываться данные, а также, создать почтовое событие + шаблон для отправки письма уведомления на почту.

Добавление инфоблока для записи заявок

Создаем информационный блок «Заявки», и добавляем свойства для информационного блока. В моём примере путь к созданию нового инфоблока следующий:
Контент > Инфоблоки > Типы инфоблоков > Каталог > Добавить инфоблок

Назначение полей свойств говорит само за себя, мы будет записывать ID элемента, с которого отправляется форма, имя пользователя, телефон, почтовый адрес, а также записывать URL страницы, с которой были отправлены данные.

Добавление почтового события и шаблона

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

Настройки > Настройки продукта > Почтовые события > Типы почтовых событий > Добавить тип

Тип почтового события я указал как NEW_USER_RESPONSE, в самом деле вы можете назвать его по-своему, это не так принципиально. Далее создаем почтовый шаблон, который будет использован для отправки писем на почту администрации сайта.
Путь к созданию нового почтового шаблона такой:

Настройки > Настройки продукта > Почтовые события > Почтовые шаблоны > Добавить шаблон

Выбираем в качестве почтового события запись с кодом NEW_USER_RESPONSE, далее, как показано на скриншоте:

После того как сохранили почтовый шаблон, можно приступать непосредственно к самой форме отправки. Сайт, который использовался в примере свёрстан с использованием bootstrap 4, этого не говорит о том, что вам необходимо его так же использовать. Вы можете реализовать эту форму самостоятельно, без использование сторонних фреймворков для верстки. В моём же примере используется модальные окна, которые хорошо описаны в документации по bootstrap 4.
Сам код формы я поместил в основной файл шаблона header.php, так как модальное окно с формой должно быть доступно по всему сайту.

<!--modal-->
<div class="modal" tabindex="-1" role="dialog" id="customer-response">
	<div class="modal-dialog" role="document">
		<div class="modal-content">
			<div class="modal-header">
				<h5 class="modal-title">Напишите нам</h5>
				<button type="button" class="close" data-dismiss="modal" aria-label="Close">
				<span aria-hidden="true">&times;</span>
				</button>
			</div>
			<div class="modal-body">
				<div class="md-resp-msg"></div>
				<form id="cust-resp-form" class="contact" name="contact" action="#" method="post">

					<input type="hidden" name="resp_item_id" id="resp_item_id" value="0">

					<div class="form-group">
						<label for="md-resp-name">Представьтесь<span class="red-text">*</span></label>
						<input type="text" id="md-resp-name" name="md-resp-name" class="form-control" placeholder="Иван Иванов" required="">
					</div>

					<div class="form-group">
						<label for="md-resp-phone">Телефон<span class="red-text">*</span></label>
						<input type="text" id="md-resp-phone" name="md-resp-phone" class="form-control" placeholder="+7(___)___-__-__" required="">
					</div>
					
					<div class="form-group">
						<label for="md-resp-email">Почта</label>
						<input type="text" id="md-resp-email" name="md-resp-email" class="form-control" placeholder="example@mail.ru">
					</div>

					<div class="form-group">
						<label for="md-resp-message">Описание заявки</label><br>
						<textarea name="md-resp-message" class="form-control" rows="5" id="md-resp-message"></textarea>
					</div>
					
					<div class="form-group">
						<p class="required-fields">* Обязательные поля для заполнения</p>
						<p class="user-agrement">Нажимая кнопку, я принимаю <a href="#">соглашение о конфиденциальности</a> и соглашаюсь с обработкой персональных данных</p>
					</div>
					
				</form>
				
			</div>
			<div class="modal-footer">
				<button type="button" class="md-resp-send">Отправить</button>
			</div>
		</div>
	</div>
</div>

Кнопка вызова модального окна так же располагается на странице, выглядит она таким образом:

<a href="javascript:void(0);" class="top-nav_callback" data-toggle="modal" data-target="#customer-response">Заказать обратный звонок</a>

Итак, действие с открыванием и закрыванием модального окна выполняется самим фреймворком bootstrap, и большого интереса для нашего поста это не представляет. Для нас интересна сама отправка данных с формы. Начинать проверку полей и отправку мы будем при нажатии на кнопке «отправить».
Код написан на js + jquery, выполняет валидацию заполнения полей, а также отправку данных на сервер:

// ----------- callback response ---------------

$(".md-resp-send").on("click",function(e){
	e.preventDefault();
	
	$(".md-resp-msg").hide();
	$(".md-resp-msg").html('');
	
	var err=0;

	// person name
	if ( $("#md-resp-name").val() == '' ){
		err++
		$("#md-resp-name").addClass("hasError");
	} else {
		$("#md-resp-name").removeClass("hasError");
	}
	
	// phone
	if ( $("#md-resp-phone").val() == '' ){
		err++
		$("#md-resp-phone").addClass("hasError");
	} else {
		$("#md-resp-phone").removeClass("hasError");
	}

	// email
	if ( $("#md-resp-email").val() != '' ){
		var pattern = /\S+@\S+\.\S+/;
		if ( !pattern.test( $("#md-resp-email").val() )){
			err++
			$("#md-resp-email").addClass("hasError");
		} else {
			$("#md-resp-email").removeClass("hasError");
		}
	} else {
		$("#md-resp-email").removeClass("hasError");
	}

	var resp_type = '';
	if ( $("#resp_item_id").val() == 0 ){
		resp_type = '?action=call';
	}

	if (err == 0){
		
		$.ajax({
			type: "POST",
			url: '/ajax.customer-response.php'+resp_type,
			data: {
				'item_id': $("#resp_item_id").val(), // set in catalog.js
				'name': $("#md-resp-name").val(),
				'phone': $("#md-resp-phone").val(),
				'email': $("#md-resp-email").val(),
				'message': $("#md-resp-message").val()
			},
			dataType: "json",
			success: function(data){

				if (data.status == true){
					$("#md-resp-name").val('');
					$("#md-resp-phone").val('');
					$("#md-resp-email").val('');
					$("#md-resp-message").val('');
				}
				
				if (data.msg && data.msg.length > 0){
					$(".md-resp-msg").fadeIn();
					$.each( data.msg, function( key,field ) {
						if (field.type == true){
							$(".md-resp-msg").append('<p class="md-true">'+field.text+'</p>');
						} else {
							$(".md-resp-msg").append('<p class="md-error">'+field.text+'</p>');
						}
					});
				}

			}
		});
	}

});

Хотелось бы немного пояснить по коду js. В коде объявляется переменная err, которая по сути является счётчиком ошибок при валидации. Если ошибок проверки полей не возникало, то значение счётчика соответственно равно 0. Это означает что после проверки полей, будет выполняться отправка данных на сервер, посредством ajax-запроса. В случае успешной отправки, значения полей будет очищаться. Если сервер отправил сообщение об ошибке или успешной отправке, они будут записываться в блок с классом .md-resp-msg, с указанием дополнительного класса для типа сообщения .md-true или .md-error. Это используется для стилизации цвета текста сообщения.

В корне сайта создаем ajax.customer-response.php который будет выполнять код на стороне сервера, при ajax-запросе.

// подключаем пролог, для использования Bitrix API без подключения шаблона
require_once($_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/include/prolog_before.php");

// поключаем модуль инфоблоков
CModule::IncludeModule('iblock');

$arResult = array('status' => false); // переменная для результата
$err = 0; // счётчик ошибок
$PROP = array(); // данные для полей элемента инфоблока



// если передан ID элемента, то заявка отправлена со страницы карточки товара
if (isset($_POST['item_id']) && $_POST['item_id'] > 0){
	$PROP['ITEM_ID'] = (int)$_POST['item_id'];
}

// имя пользователя
if (isset($_POST['name']) && !empty($_POST['name'])){
	$PROP['PERSON_NAME'] = htmlspecialchars( $_POST['name'], ENT_QUOTES );
} else {
	$err++;
	$arResult['msg'][] = array(
						'text' =>'Вы не указали Ваше имя.',
						'type' => false
					);
}

// указываем тему отклика, в зависимости от передаваемого типа
if (isset($_POST['action']) && $_POST['action'] == 'call'){
	$TITLE = 'Новая заявка звонка с сайта: '.$PROP['PERSON_NAME'].' от '.date("d.m.Y H:i:s");
} else {
	$TITLE = 'Новая заявка: '.$PROP['PERSON_NAME'].' от '.date("d.m.Y H:i:s");
}

// номер телефона
if (isset($_POST['phone']) && !empty($_POST['phone'])){
	$PROP['PHONE'] = htmlspecialchars( $_POST['phone'], ENT_QUOTES );
} else {
	$err++;
	$arResult['msg'][] = array(
						'text' =>'Вы не указали номер телефона.',
						'type' => false
					);
}

// почтовый адрес
if (isset($_POST['email']) && filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
	$PROP['EMAIL'] = htmlspecialchars( $_POST['email'], ENT_QUOTES );
}

// сообщение от пользователя
if (isset($_POST['message']) && !empty($_POST['message'])){
	$PREVIEW_TEXT = htmlspecialchars( $_POST['message'], ENT_QUOTES );
}

// страница, с которой был отправлен запрос
$PROP['HTTP_REFERER'] = $_SERVER['HTTP_REFERER'];

if ($err == 0){

	$el = new CIBlockElement;
	// массив полей для нового элемента
	$arElem = Array(
				"IBLOCK_SECTION_ID" => false,
				"IBLOCK_ID"      => 9,
				"PROPERTY_VALUES"=> $PROP,
				"NAME"           => $TITLE,
				"ACTIVE"         => "Y",
				"PREVIEW_TEXT"   => $PREVIEW_TEXT
			);


	if ($PRODUCT_ID = $el->Add($arElem)){
		// устанавливаем статус
		$arResult['status'] = true;
		$arResult['msg'][] = array(
								'text' =>'Ваши данные отправлены успешно!<br>Ожидайте звонка наших операторов.',
								'type' => true
							);
	
		// подготавливаем поля для почтового события
		$arEventFields = array(
						'ITEM_ID' => $PROP['ITEM_ID'],
						'PERSON_NAME' => $PROP['PERSON_NAME'],
						'PERSON_MAIL' => $PROP['EMAIL'],
						'PERSON_PHONE' => $PROP['PHONE'],
						'HTTP_REFERER' => $PROP['HTTP_REFERER'],
						'RESPONSE_THEME' => $TITLE
					);

		// отправка почты
		CEvent::Send("NEW_USER_RESPONSE", "s1", $arEventFields);
	
	} else {

		$arResult['msg'][] = array(
					'text' =>'Не удалось сохранить запись. ' . $el->LAST_ERROR,
					'type' => false
				);
	}

}

echo json_encode($arResult);

Код на стороне сервера довольно прост, не смотря на его объем. Первое что выполняется – проверка отправленных полей, количество ошибок записывается в переменную $err, как вы, наверное, уже поняли с примером на js, если количество ошибок равно нулю, создается элемент в инфоблоке, а после вызывается почтовое событие, которому передаются ключевые поля для почтового шаблона. В качестве результата скрипт возвращает массив полей, конвертированный в строку json. Ключевой параметр в массиве, обозначающий успешность выполнения операции называется «status», по умолчанию он равен false, при успешном выполнении параметр переводится в значение true. Параллельно с ним, так же отправляются сообщения посредством поля msg. Сообщение формируется из двух полей, text – текст сообщения, type – обозначает тип сообщения, может быть true – успех, false – ошибка. Вот в целом собственно и всё. Если остались какие-либо вопросы, вы можете писать их в комментарии. Разумеется, форму можно переделать под ваши нужды, к примеру, добавить полей, или наоборот убрать их. Всё зависит от ваших задач.

Добавил: htmaker, 16.09.2019 г.
 
нравится (Пока оценок нет)
Загрузка...

Комментарии

  1. Михаил пишет:

    Добрый день. Расскажите как подключить гугл капчу к данной форме? Заранее благодарен.

  2. htmaker пишет:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Наверх