Форма обратной связи с отправкой на почту без перезагрузки страницы
Обратная связь – довольно востребованный, на мой взгляд, функционал, присутствующий, опять же по-моему скромному мнению, почти на каждом сайте. Под обратной связью я подразумеваю старую добрую форму для написания сообщений администрации сайта (пример именно такой формы мы будем здесь рассматривать), форму обратного звонка (она же «Перезвоните мне»), простой вариант подписки на новости и прочие подобные.
За свою «карьеру» мне довелось видеть разные реализации данного функционала. В каких-то случаях я не понимал, за чем всё так усложнять, а где-то, наоборот, недоумевал, почему не предусмотрели такой, казалось бы, банальный поворот событий. Шло время, и накопившееся возмущение с некоторым приобретенным опытом вылилось ни во что иное, как в своё решение, о котором я сегодня подробно расскажу.
Простая форма обратной связи для сайта на HTML+jQuery+PHP
Поскольку для отправки данных с формы требуется PHP, то, думаю, не стоит делать акцент на том, что на вашем хостинге должна быть его поддержка. Помимо этого, стоит упомянуть, что несколько раз я сталкивался с тем, что на хостинге по какой-то из причин не работала PHP-функция mail(), с помощью которой осуществляется отправка сообщений на указанную почту.
Чтобы удостовериться в том, что работа функции никак не ограничена, создайте в корне сайта PHP-файл со следующим содержимым:
<?php
var_dump(mail('Ваша почта', 'Test mail', 'Test'));
Откройте его в браузере, и если вы видите сообщение:
bool(true)
то значит отправка (в большинстве случаев) работает. Окончательно подтвердить это можно, проверив указанную (особенно папку спам) в скрипте почту (должно прийти письмо). Если же письма на почте нет, а указанное выше сообщение в браузере вы всё же увидели, то стоит обратиться в техническую поддержку вашего хостинга, чтобы они посмотрели, в чём может быть дело.
Итак, мы убедились, что PHP-функция mail() у нас отправляет тестовое письмо, значит, пора начинать формировать нашу форму обратной связи, и, как это ни странно, начнём мы с её верстки (HTML). Выглядит она следующим образом:
<input type="text" id="formName" value="" maxlength="100" placeholder="Ваше имя" />
<input type="text" id="formEmail" value="" maxlength="100" placeholder="Ваше e-mail *" />
<textarea id="formMessage" maxlength="1000" placeholder="Сообщение *"></textarea>
<div class="formResult"></div>
<button class="formSubmit">Отправить</button>
Я не поместил форму в логичный тег <form>, поскольку данные с неё я будут отправлять AJAX'ом (к слову, AJAX позволит нам отправлять форму без перезагрузки страницы), а потому не задействую некоторые ненужные, на мой взгляд, составляющие. Обязательность полей, в отличие от классической формы, забегая немного вперед, мы будем указывать в обработчике (PHP-скрипте). Допустимую длину полей указываем здесь и дополнительно в том же обработчике. Новые поля двух приведённых в примере типов (текст и текстовая область) добавляются по аналогии, уникальность поля задаётся через атрибут id (в нашем случае это formName, formEmail и formMessage).
Хорошо, с вёрсткой мне кажется всё более или менее понятно, идём дальше. Скрипт, который будет собирать и отправлять данные с нашей формы (необходимо наличие jQuery на вашем сайте):
$(document).ready(function() {
$(".formSubmit").on("click", function() {
$.ajax({
url: "/form.php", // Куда отправляем данные (обработчик)
type: "POST", // Тип запроса
dataType: "json",
data: {
"name": $("#formName").val(), // Имя
"email": $("#formEmail").val(), // E-mail
"message": $("#formMessage").val() // Сообщение
},
success: function(data) {
$(".formResult").html(data); // Выводим результат
}
});
});
});
Я считаю также понятным. Если нет – пишите в комментариях, постараюсь дать пояснения.
Завершающая часть (PHP), та, которая будет получать данные с формы, обрабатывать их и отправлять нужным адресатам (да-да, их здесь может быть несколько):
header('Content-Type: application/json; charset=utf-8');
$mailAdress = [
'Ваша почта'
]; // Массив получателей (E-mail)
$mailSubject = 'Письмо с обратной связи'; // Тема письма
/*
Массив полей:
code - название поля из AJAX
title - подпись
length - длина поля
required - обязательное или нет (true или false)
*/
$fieldsArr = [
[
'code' => 'name',
'title' => 'Имя',
'length' => 100,
'required' => false
], [
'code' => 'email',
'title' => 'E-mail',
'length' => 100,
'required' => true
], [
'code' => 'message',
'title' => 'Сообщение',
'length' => 1000,
'required' => true
]
];
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
$errorList = []; // Список ошибок
$mailBody = '';
foreach($fieldsArr as $field) {
if(!isset($_POST[$field['code']])) {
// Если одно из полей не передано (не путать с пустым значением) - останавливаем работу скрипта
die();
} elseif(trim($_POST[$field['code']]) == '' && $field['required']) {
// Если передано пустое поле и оно обязательное для заполнения - формируем сообщение об ошибке
$errorList[] = 'Поле <b>'.$field['title'].'</b> обязательно для заполнения.';
} else {
// Формируем сообщение отправляемое на почту
$mailBody .= '<p><b>'.$field['title'].':</b> '.mb_substr(strip_tags(trim($_POST[$field['code']])), 0, $field['length']).'</p>';
}
}
if(!empty($errorList)) {
// Если ошибки есть, выводим их
echo json_encode(implode('<br />', $errorList), JSON_UNESCAPED_UNICODE);
} else {
$domain = $_SERVER['HTTP_HOST'];
if(substr($domain, 0, 4) == 'www.') {
$domain = substr($_SERVER['HTTP_HOST'], 4);
}
$mailHeaders = 'MIME-Version: 1.0'."\r\n";
$mailHeaders .= 'Content-type: text/html; charset=utf-8'."\r\n";
$mailHeaders .= 'From: Система уведомлений <no-reply@'.$domain.'>'."\r\n";
foreach($mailAdress as $mail) {
mail($mail, $mailSubject, $mailBody, $mailHeaders);
}
echo json_encode('Сообщение успешно отправлено!', JSON_UNESCAPED_UNICODE);
}
} else {
die();
}
Здесь, я думаю, мне определенно стоит дать некоторые комментарии.
1. Как вы помните, адресатов (получателей) писем может быть несколько. Здесь все они пишутся в массиве. Пример нескольких адресатов:
$mailAdress = [
'E-mail 1',
'E-mail 2',
'E-mail 3'
]; // Массив получателей (E-mail)
2. Все письма с сайта отсылаются от лица no-reply@домен вашего сайта, поэтому, чтобы письма не попадали в спам и в принципе отсылались, создайте этот адрес (о том, как создать корпоративную почту для домена, читайте в других наших постах) или замените на другой.
3. В массиве полей должны быть указаны коды (code) тех полей, которые вы передаете в AJAX.
Если какое-то из описанных полей не передаётся, то обработчик (PHP-скрипт) остановит своё выполнение.
4. Текст отправляемого письма формируется автоматически на основе указанного массива полей.
Это, так скажем, самые важные моменты, остальное – не требует вашего участия.
Форма не идеальна, но вполне хорошая основа для будущих разработок. Буду рад почитать ваши мнения относительно неё. Чтобы сильно не раздувать пост, в комментариях дам несколько советов по тому, как эту форму можно доработать.
Форма (виджет) обратного звонка для сайта
Простой обратный звонок от формы обратной связи отличается лишь набором полей, поэтому такой функционал вы можете реализовать по примеру, описанному выше, исключив не нужные вам поля, дополнительно поместив форму в модальное окно.