Не пропусти свежие посты, подпишись:

Форма обратной связи — один из самых част встречающихся элементов на сайте и сейчас я хочу рассказать о том как сделать её на основе компонента, при этом не используя встроенный в битрикс модуля «Веб-формы» т.к. он доступен только начиная с лицензии «Стандарт», а подавляющее большинство сайтов не имеющих отношения к Интернет-торговле делаются на редакции «Старт». Так же мы учтём в форме один маленький лайфхак который я узнал на курсе Бизнес молодость ЦЕХ, который мне посчастливилось проходить летом 2019-го года. И так, поехали.

Подготовка компонента

Чтобы сэкономить время, предлагаю установить один прикольный модуль «Мастер создания компонента», он позволит быстро и без лишних телодвижений создать простой макет нашего компонента формы обратной связи. Устанавливаем компонент через страницу на маркетплейсе или через админку.

Затем переходим в раздел: Настройки -> Настройки продукта -> Список мастеров, тут ищем «Мастер создания компонента» и в контекстном меню напротив, выбираем пункт «Установить»:

Запуск мастера создания компонента


Для нашего компонента я выбрал следующие базовые настройки:

  • Тип компонента — простой
  • Пространство имён — custom
  • Идентификатор — emptyscript
  • Название — Пустой скрипт
  • Описание — Заготовка под кастомный компонент
  • Категория в списке компонентов — Custom
Базовые настройки будущего компонента

Почему пустой скрипт? Т.к. функциональность формы крайне простая мы будем описывать бизнес логику формы в файлах component_epilog.php или доп.файлах ajax.php в папке шаблона компонента. А сам компонент emptyscript послушит каркасом для ряда простых форм.

Опции шаблона компонента следующие:

Опции шаблона



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

Итоговые настройки мастера

Нажимаем «Создать», ждём пару секунд, готово! Компонент успешно создан! Можете поблагодарить автора компонента донатом, он действительно экономит кучу времени. Давайте создадим какой-нибудь раздел на сайте и разместим нашу заготовку.

Перейдём к описанию самой формы.

Шаблон формы обратной связи

Допустим вы фрилансер, вебмастер, у вас есть свой landing-page и вы хотите подвесить туда форму обратной связи. Как будет выглядеть наш шаблон? Какую информацию будем собирать о клиенте? Предлагаю собрать следующее:

  1. Имя
  2. Email
  3. Контактный телефон
  4. Сайт (если есть)
  5. Описание проблемы или задачи которую хочет решить клиент
  6. Уточнение способа связи (та самая фишка от БМ)
  7. Согласие с политикой конфиденциальности

Основываясь на этом списке, делаем форму:

Шаблон формы


Первые три поля обязательны, т.к. нам нужна эта информация чтобы дозвониться до клиента и обсудить проект, а если не дозвонились то отправить адресованное ему письмо с коммерческим предложением (КП) и т.д. в котором нужно обратиться по имени. Поля «Сайт» и «Описание проблемы или задачи» позволят вам лучше подготовиться к обработки заявки, сделать более адресное КП.

Блок «Как с вами связаться» очень важен. Есть категория клиентов которая не любит звонки им гораздо удобнее провести первичный контакт с исполнителем через WhatsApp или электронную почту. Этот блок позволяет узнать предпочтение клиента и связаться с ним, наиболее удобным для него способом.

И конечно же «Согласие с политикой конфиденциальности». Согласно закону 152-ФЗ «О персональных данных», вы как владелец веб-сайта обязаны запросить подобное согласие от клиента если собираете его персональные данные (имя, телефон и т.п.). Кстати быстро сгенерировать страницу для сайта с описание политики конфиденциальности поможет этот сервис.

С внешним видом определились, давайте верстать!


<form action="<?=$templateFolder;?>/ajax.php" class="bg-white rounded pb_form_v1 ajax_form" method="POST">
	<input type="hidden" name="FORM" value="MAIN_FEEDBACK">
	<h2 class="mb-4 mt-0 text-center">Оставьте заявку.</h2>
	<div class="sub_title">и получите аудит вашего сайта бесплатно</div>
	<div class="form-group">
		<input type="text" name="USER_NAME" class="form-control pb_height-50 reverse" placeholder="Ваше имя *" required="">
	</div>
	<div class="form-group">
		<input type="text" name="USER_EMAIL" class="form-control pb_height-50 reverse" placeholder="Email *" required="">
	</div>
	<div class="form-group">
		<input type="text" name="USER_PHONE" class="form-control pb_height-50 reverse" placeholder="Телефон *" required="">
	</div>
	<div class="form-group">
		<input type="text" name="USER_WEBSITE" class="form-control pb_height-50 reverse" placeholder="Сайт, если он уже есть">
	</div>
	<div class="form-group">
		<textarea name="USER_MESSAGE" class="form-control pb_height-110 reverse" placeholder="Пару слов о ваших проблемах и задачах..."></textarea>
	</div>
	<div class="form-group">
		<label>Как нам с вами связаться?</label>
		<div class="radio_block">
			<div class="custom-control custom-radio">
            	<input type="radio" class="custom-control-input" id="phoneCall" name="CONNECT_TYPE" value="Позвонить по телефону" checked="">
            	<label class="custom-control-label" for="phoneCall">Позвонить по телефону</label>
        	</div>
			<div class="custom-control custom-radio">
            	<input type="radio" class="custom-control-input" id="whatsapp" name="CONNECT_TYPE" value="Написать в WhatsApp">
            	<label class="custom-control-label" for="whatsapp">Написать в WhatsApp</label>
        	</div>
			<div class="custom-control custom-radio">
            	<input type="radio" class="custom-control-input" id="sendEmail" name="CONNECT_TYPE" value="Написать на почту">
            	<label class="custom-control-label" for="sendEmail">Написать на почту</label>
        	</div>
		</div>
	</div>
    <div class="form-group politika custom-control custom-radio">
        <input type="checkbox" id="policy_full" name="policy" value="y" class="form-control reverse custom-control-input" required="required">
        <label class="custom-control-label" for="policy_full">Согласен с <a href="#" target="_blank">политикой конфиденциальности</a></label>
    </div>
	<div class="form-group">
		<input type="submit" class="btn btn-primary btn-lg btn-block pb_btn-pill  btn-shadow-blue" value="Написать">
	</div>
</form>

Для валидации используем стандартный HTML5, однако при желании можно подключить jQuery Validate или аналогичный плагин.

Большая часть стилей, это стандартный Bootstrap 4, однако для некоторых элементов формы стиля я всё же приведу (это scss):


.pb_form_v1 {
	padding: 50px;
	@include pb_box-shadow(1px, 11px, 68px, -20px, rgba($black,.75));
	@include media-breakpoint-down(md) {
		padding: 30px;
	}
}

// inputs
input, select, textarea {
	font-weight: 300;
	color: rgba($black, .7);
}
.pb_select-wrap {
	position: relative;
	&:before {
		@include Ionicons;
		content: "\f3d0";
		position: absolute;
		right: 20px;
		top: 50%;
		transform: translateY(-50%);
		font-size: 26px;
	}
	select {
		appearance: none;
	}
}
// select {
.form-control {
	&.reverse {
		background: lighten($black, 95%);
		transition: .3s all ease;
		border-color: lighten($black, 95%);
		&:focus, &:active {
			background: none;
			border-color: theme-color('primary')!important;
		}
	}
}

.form-control-outline {
	background: none;
	&:focus, &:active {
		background: none;
	}
	&.light {
		color: $white;
		border-color: rgba($white, .4);
		&:focus, &:active {
			border-color: rgba($white, 1);
		}
		&::placeholder {
			color: rgba($white, .5);
		}
	}
	&.dark {
		color: $body-color;
	}
}

// buttons
.btn {
	&:focus, &:active {
		box-shadow: none!important;
		outline: none!important;
	}
}
.btn-shadow-blue {
	@include pb_box-shadow(0px, 15px, 28px, -5px, rgba($blue,.45));
}
.pb_btn-pill {
	border-radius: 50px;
	padding-left: 40px;
	padding-right: 40px;
}
.pb_outline-light {
	border: 1px solid rgba(255,255,255,.2);
	text-transform: uppercase;
	background: none;
	color: #ffffff;
	&:hover, &:active, &:focus {
		outline: none;
		background: $white!important;
		border: 1px solid #ffffff;
		color: $black;
	}
}
.pb_outline-dark {
	border: 1px solid rgba(0,0,0,.2);
	text-transform: uppercase;
	color: #000000;
	background: none;
	&:hover, &:active, &:focus {
		outline: none;
		background: $black!important;
		border: 1px solid #000000;
		color: $white;
	}
}

И стили для чекбоксов блока «Как нам с вами связаться?»:

.custom-control {
  position: relative;
  display: -webkit-inline-box;
  display: -webkit-inline-flex;
  display: -ms-inline-flexbox;
  display: inline-flex;
  min-height: 1.8rem;
  padding-left: 1.5rem;
  margin-right: 1rem; }

.custom-control-input {
  position: absolute;
  z-index: -1;
  opacity: 0; }
  .custom-control-input:checked ~ .custom-control-indicator {
    color: #fff;
    background-color: #007bff; 
}
  .custom-control-input:focus ~ .custom-control-indicator {
    -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 3px #007bff;
    box-shadow: 0 0 0 1px #fff, 0 0 0 3px #007bff; 
}
  .custom-control-input:active ~ .custom-control-indicator {
    color: #fff;
    background-color: #b3d7ff; 
}
  .custom-control-input:disabled ~ .custom-control-indicator {
    background-color: #e9ecef; 
}
  .custom-control-input:disabled ~ .custom-control-description {
    color: #868e96; 
}

.custom-control-indicator {
  position: absolute;
  top: 0.4rem;
  left: 0;
  display: block;
  width: 1rem;
  height: 1rem;
  pointer-events: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  background-color: #ddd;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: 50% 50%; }

.custom-checkbox .custom-control-indicator {
  border-radius: 0.25rem; }

.custom-checkbox .custom-control-input:checked ~ .custom-control-indicator {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"); 
}

.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-indicator {
  background-color: #007bff;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E"); 
}

.custom-radio .custom-control-indicator {
  border-radius: 50%;
}

.custom-radio .custom-control-input:checked ~ .custom-control-indicator {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E");
}

.captcha-wrapper {
    padding-left: 15px;
}



Давайте так же подключим плагин для всплывающих окон, чтобы показывать пользователю результат. Я предпочитаю magnificPopup , подключите плагин, стили и jQuery (если ещё не сделали этого):

<!-- Magnific Popup core CSS file -->
<link rel="stylesheet" href="magnific-popup/magnific-popup.css">

<!-- jQuery 1.7.2+ or Zepto.js 1.0+ -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<!-- Magnific Popup core JS file -->
<script src="magnific-popup/jquery.magnific-popup.js"></script>

И создайте внизу страницы (после формы) блок для показа всплывающего окна:

<div class="white-popup mfp-hide" id="js_contact_form_popup"></div>

Мы будем подставлять в него ответ сервера и показывать пользователю popup.

Форма готова!

Подключаем проверку Google

Перейдите на страницу Google reCaptcha (у вас должен быть аккаунт на Google), нажмите кнопку «Создать» и введите следующие настройки:

Настройка Google reCaptcha

Указываем тип капчи «Я не робот»:

Тип капчи Я не робот

После сохранения настроек, вы получите пару ключей, а именно «Ключ сайта» и «Секретный ключ»:

Ключи Google reCaptcha


Их лучше сразу сохранить в константах сайта. Обычно это файл init.php или отдельный файл constants.php подключаемый в начале init.php.


<?

//Ключ сайта Google капчи
define('GOOGLE_CAPTCHA_SITE_KEY', '---тут ваш ключ---');

//Секретный ключ Google капчи
define('GOOGLE_CAPTCHA_SECRET_KEY', '---тут ваш секретный ключ---');

Добавим блок капчи в вёрстку формы, вот так (можно вставить его перед согласием с политикой конфиденциальности):


<div class="row form-group">
    <div class="captcha-wrapper">
        <div class="g-recaptcha" data-sitekey="<?=GOOGLE_CAPTCHA_SITE_KEY;?>"></div>	
    </div>
</div>

Так же необходимо подключить js скрипта api Goolge reCaptcha, делается это в файле header.php шаблона сайта:

<?
//Подключаем Google reCaptcha API
Asset::getInstance()->addString('<script src="https://www.google.com/recaptcha/api.js"></script> ');

Проверка ввода капчи

Для верификации ввода капчи нам потребуется дополнительный php класс ReCaptcha, его можно найти на GitHub. Скачиваем и подключаем его в наш компонент. Т.к. для обработки формы я собираюсь использовать ajax.php подключим этот класс туда (ajax.php это доп.файл в лежащий в папке с шаблоном компонента и отвечающий за серверную обработку запроса с формы).


<?

//Подключаем ядро 1С Битрикс
require($_SERVER["DOCUMENT_ROOT"] . '/bitrix/modules/main/include/prolog_before.php');
//Подключаем класс Google для проверки ввода капчи
require($_SERVER['DOCUMENT_ROOT'] . '/local/php_interface/recaptchalib.php');

if($_POST['FORM'] == 'MAIN_FEEDBACK_QUICK'){

    //ответ
    $response = false;
    //проверка секретного ключа
    $reCaptcha = new ReCaptcha(GOOGLE_CAPTCHA_SECRET_KEY);

    if ($_POST["g-recaptcha-response"]) {
        $response = $reCaptcha->verifyResponse(
            $_SERVER["REMOTE_ADDR"],
            $_POST["g-recaptcha-response"]
        );
    }

    //Проверяем ответ Google 
    if ($response->success) {
        //Отправляем форму, записываем данные в инфоблок ...
		
		echo json_encode(['success'=>'y', 'message'=>'Заявка успешно отправлена! Мы скоро свяжемся с вами.']);
    } else {
        echo json_encode(['success'=>'n', 'message'=>'Вы не прошли проверку Google reCaptcha']);
    }
}

Как видите здесь мы создаём экземпляр класса ReCaptcha() подставляя ранее полученный «секретный ключ», Google по средствам своего API сам проверит валидность капчи и вернёт соответствующий ответ в переменную  $response.  Проверка $response->success сообщает нам об успешной проверки пользователя или же о провале.

Давайте добавим JavaScript обработчик нашей форме, чтобы удостовериться что всё работает:


//Отправка формы
$('.ajax_form').submit(function(event) {
	event.preventDefault();
	var form = $(this);
	
	$.ajax({
		url: form.attr('action'),
		method: 'POST',
		data: form.serialize(),
		beforeSend: function () { /* здесь можно задать визуальный эффект отправки формы*/},
		success: function (data) {
			var formResponse = $.parseJSON(data);
			if(formResponse.success == 'y'){
				$('#js_contact_form_popup').html('<span>Спасибо!</span><br/> Ваша заявка успешно отправлена.<br/> Мы скоро свяжемся с вами для уточнения деталей.');
				form[0].reset();
			} else {
				$('#js_contact_form_popup').html('<span>Ошибка!</span><br/>' + formResponse.message);
			}

			//Показываем всплывающее окно с сообщением от сервера
			$.magnificPopup.open({
				items: {
					src: $('#js_contact_form_popup'),
					type: 'inline',
					mainClass: 'mfp-fade',
					removalDelay: 300,
				}
			});
        }
    });
});



Подробнее о том как работать с jQuery Ajax можно прочитать в этой статье. Проверим работу капчи:

Проверка работы капчи

Шаблон письма

Шаблон письма до безобразия прост, в нём мы отразим только самую необходимую информацию:


<h2>Новая заявка</h2>
<ul>
	<li><b>Имя:&nbsp;</b>#USER_NAME#</li>
	<li><b>Телефон:&nbsp;</b>#USER_PHONE#</li>
	<li><b>Email:&nbsp;</b>#USER_EMAIL#</li>
	<li><b>Сайт:&nbsp;</b>#USER_WEBSITE#</li>
	<li><b><span style="color: #ee1d24;">Способ связи:&nbsp;</span></b>#CONNECT_TYPE# <i>(предпочтительный способ связи с клиентом)</i></li>
</ul>
 <br>
 <b>Текст сообщения:</b>&nbsp;#USER_MESSAGE#<br>
 <br>
 Сообщение сгенерировано автоматически, на него <b>не нужно</b> отвечать.<br>

Осталось дополнить наш ajax.php чтобы в случае успешной проверки капчи он отправлял данные на почту:

<? 

//Подключаем ядро 1С Битрикс
require($_SERVER["DOCUMENT_ROOT"] . '/bitrix/modules/main/include/prolog_before.php');
//Подключаем класс Google для проверки ввода капчи
require($_SERVER['DOCUMENT_ROOT'] . '/local/php_interface/recaptchalib.php');

if($_POST['FORM'] == 'MAIN_FEEDBACK_QUICK'){

    //ответ
    $response = false;
    //проверка секретного ключа
    $reCaptcha = new ReCaptcha(GOOGLE_CAPTCHA_SECRET_KEY);

    if ($_POST["g-recaptcha-response"]) {
        $response = $reCaptcha->verifyResponse(
            $_SERVER["REMOTE_ADDR"],
            $_POST["g-recaptcha-response"]
        );
    }

    //Проверяем ответ Google 
    if ($response->success) {
        //Отправляем форму
        $arrFields = [
            'USER_NAME'    => strip_tags($_POST['USER_NAME']),
            'USER_EMAIL'   => strip_tags($_POST['USER_EMAIL']),
            'USER_PHONE'   => strip_tags($_POST['USER_PHONE']),
            'USER_MESSAGE' => strip_tags($_POST['USER_MESSAGE']),
            'USER_WEBSITE' => strip_tags($_POST['USER_WEBSITE']),
            'CONNECT_TYPE' => strip_tags($_POST['CONNECT_TYPE']),
        ];

        if(CEvent::Send('CUSTOM_FORM', SITE_ID, $arrFields, 'N', 10)){
            echo json_encode(['success'=>'y', 'message'=>'Заявка успешно отправлена! Мы скоро свяжемся с вами.']);
        }

    } else {
        echo json_encode(['success'=>'n', 'message'=>'Вы не прошли проверку Google reCaptcha']);
    }
}

Метод CEvent::Send() отвечает за отправку письма, число 10 в параметрах метода — это идентификатор почтового шаблона который мы подготовили ранее, у вам он может отличаться. Если вы всё сделали правильно, в результате вам на почту будет приходить такое вот письмо:
Заявка с сайта

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

Заключение

На первый взгляд внедрение такого функционала может показаться сложным, но если всё разложить на последовательные логические шаги и использовать пару спец.инструментов задача становится значительно проще! Если у вас остались вопросы — пишите их в комментариях. Желаю удачи!

Не пропусти свежие посты, подпишись:
Полезная статья?
(Голосов: 4, Рейтинг: 3.23)
Курсы от партнёров
Хотите освоить востребованную профессию? Воспользуйтесь предложениями от наших партнёров. Пройдите учебный курс по одному из популярных IT направлений.

Все курсы партёнров
Вам также могут понравиться
Кем можно работать в сфере веб-разработки

Кем можно работать в сфере веб-разработки

Хотите начать работать в сфере веб-разработки, но не знаете с чего можно начать? Читайте описание самых популярных веб-профессий, с их описанием, обязанностями и ориентировочными зарплатами.

CSS курсоры

CSS курсоры

В статье рассмотрены возможности изменения курсоров пользователя при помощи CSS

Работа с регистром строк в php

Работа с регистром строк в php

В статье рассмотрены примеры работы с регистром строк в языке PHP, проверка регистра, изменение, инверсия


Комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
25.11.2020 | Rum

Здравствуйте, а как в битриксе правильно подключить scss? И с всплывающим окном не до конца понятно.

Комментировать | 0  
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
Закрыть
25.11.2020 | maler1988

Scss/sass напрямую не подключается, используйте gulp или webpack для сборки scss и конвертации в css. Что конкретно не получается со всплывающим окном?

Комментировать | 0  
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
Закрыть
26.11.2020 | Rum

Попробовал, но при конвертации получаю ошибку Error: Undefined mixin. Скорее всего пока не разобрался как правильно, но а почему бы не выложить уже сконвертированный код в css если битрикс не поддерживает scss, статья же для битрикса написана?

Комментировать | 0  
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
Закрыть
04.12.2020 | maler1988

Логично. Добавлю )

Комментировать | 0  
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
Закрыть