Привет, друзья. Сегодня хочу рассказать вам о том, как сейчас я создаю формы обратной связи для получения контактных данных пользователя.
Статья давно на сайте, но пришло время актуализировать ее, ведь с момента написания прошло более 5 лет, что-то устарело, за некоторые моменты откровенно стыдно, а что-то не так доходчиво разжевано.
С этого момента обновления статей буду делать максимально полными и подробными, чтобы вам не приходилось ничего искать на других ресурсах. Это статья, изначально, была ориентирована на форму с перебросом на страницу благодарности после нажатия кнопки «отправить».
Мы реализуем как такой вариант, так и возможность вывода сообщения об успешной отправке без перезагрузки страницы.
Создание формы обратной связи – HTML разметка
Обычно? мне хватает двух-трех полей, так как нет смысла требовать от посетителя большего и раздражать его. Продажа, обычно, случается после разговора с консультантом или менеджером, а значит все детали можно узнать по телефону.
Больше на эту тему можно почитать в статье с вредными советами, которые помогут испортить ваш landing page.
Но, как и обещал, в этой статье мы сделаем практически все возможные варианты полей. Сначала просто получим имя, телефон и почту, а потом будем постепенно усложнять, добавляя текстовую область, чекбокс и прикрепление файла.
В большинстве случаев, для создания формы обратной связи я использую такую разметку:
<form class="contact-form" id="contact-form_1" method="POST" enctype="multipart/form-data"> <p class="contact-form__title">Оставьте заявку на расчет стоимости</p> <p class="contact-form__description"></p> <div class="contact-form__input-wrapper"> <input name="name" type="text" class="contact-form__input contact-form__input_name" placeholder="Введите ваше имя"> <div class="contact-form__error contact-form__error_name"></div> </div> <div class="contact-form__input-wrapper"> <input name="tel" type="tel" class="contact-form__input contact-form__input_tel" placeholder="Введите ваш телефон"> <div class="contact-form__error contact-form__error_tel"></div> </div> <div class="contact-form__input-wrapper"> <input name="email" type="email" class="contact-form__input contact-form__input_email" placeholder="Введите ваш email"> <div class="contact-form__error contact-form__error_email"></div> </div> <button class="contact-form__button" type="submit"> Узнать стоимость </button> </form>
Знаю, что заголовок формы не согласован с кнопкой, но лень переделывать все скриншоты. Суть же не в этом совсем. Правда?
Давайте, кратко объясню, что тут к чему. В теге 'form' я размещаю два параграфа. В одном будет заголовок формы, а второй послужит для вывода сообщений и уведомлений, возникающих при отправке формы. Например, о том, что сообщение успешно отправлено в варианте, когда все происходит без перезагрузки.
Под каждым полем создаю 'div' для вывода уведомлений об ошибках при валидации '.contact-form__error'.
Параметр 'enctype' в теге 'form' нужен для того, чтобы отправлять файл. Пока можете его не писать, но, если планируете сделать так, чтобы пользователь мог прикрепить вложение к письму, то нужно оставить все как есть.
Далее, для простоты работы с js воспользуемся jQuery. Подключаем его, как обычно, перед всеми скриптами, которые зависят от него. Я, обычно, делаю это ближе к закрывающему тегу 'body', чтобы основной контент грузился быстрее.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="/mail/js/mail.js"></script>
Скрипт 'mail.js' - это файл формы, который помогает в отправке и обработке ответа сервера. О нем чуть позже. Сейчас нужно познакомить вас со структурой всех файлов, отвечающих за отправку.
Структура проекта
Здесь нас интересует папка 'mail'. Именно тут и происходит вся магия.
Обратите внимание, что она лежит в корне сайта.
В первую очередь давайте разберем файл 'config.php'. Тут задаются основные настройки формы.
Основные настройки формы
<? // *** Настройка обязательности полей, в случае если они присутствуют в вашей форме // Имя const NAMEISREQUIRED = true; const MSGSNAMEERROR = "Поле обязательно для заполнения"; // Телефон const TELISREQUIRED = false; const MSGSTELERROR = "Поле обязательно для заполнения"; // Email const EMAILISREQUIRED = false; const MSGSEMAILERROR = "Поле обязательно для заполнения"; const MSGSEMAILINCORRECT = "Некорректный почтовый адрес"; // Текстовое поле const TEXTISREQUIRED = false; const MSGSTEXTERROR = "Поле обязательно для заполнения"; // Файл const FILEISREQUIRED = false; const MSGSFILEERROR = "Поле обязательно для заполнения"; // Соглашение const AGGREMENTISREQUIRED = false; const MSGSAGGREMENTERROR = "Поле обязательно для заполнения"; // Сообщение об успешной отправке const MSGSSUCCESS = "Сообщение успешно отправлено"; // *** SMTP *** // require_once($_SERVER['DOCUMENT_ROOT'] . '/mail/phpmailer/smtp.php'); const HOST = 'ssl://smtp.yandex.ru'; const LOGIN = 'sender@yandex.ru'; const PASS = 'senderPass'; const PORT = '465'; // *** /SMTP *** // // Почта с которой будет приходить письмо const SENDER = 'sender@yandex.ru'; // Почта на которую будет приходить письмо const CATCHER = 'catcher@mail.ru'; // Тема письма const SUBJECT = 'Заявка с сайта'; // Кодировка const CHARSET = 'UTF-8';
В принципе я объясняю комментариями в коде что и зачем, константы имеют интуитивно понятные имена, но давайте для новичков объясню все еще подробнее.
В начале идут константы, которые отвечают за проверку обязательно ли поле или нет и какое сообщение будет выводится в случае ошибки. Например, константы для имени
const NAMEISREQUIRED = true; const MSGSNAMEERROR = "Поле обязательно для заполнения";
- 'const NAMEISREQUIRED = true;' - означает, что поле обязательно для заполнения. Если в вашем случае его можно не заполнять, то поставьте 'false'.
- 'const MSGSNAMEERROR = "Поле обязательно для заполнения";' - это сообщение, которое будет выводится пол полем, в случае если заполнение его обязательно, но по каким-то причинам пользователь этого не сделал.
То есть если имя обязательно, но не было заполнено, появиться сообщение 'Поле обязательно для заполнения'. Вот так:
Далее идет константа с сообщением, которое увидит пользователь при успешной отправке, давайте, пока, реализуем такой функционал, а потом с перебросом на страницу благодарности.
// Сообщение об успешной отправке const MSGSSUCCESS = "Сообщение успешно отправлено";
Можете вывести любое сообщение, которое подходит в вашем случае.
Теперь самое главное. Если прошлые вещи можно было оставить по умолчанию, то теперь нужно настроить отправку на почту. Так как в скрипте используется SMTP протокол передачи почты, то нужно узнать несколько параметров у вашего почтового сервиса. Это:
- Адрес сервера - ( константа HOST )
- Логин (адрес электронной почты) - ( константа LOGIN )
- Пароль - ( константа PASS )
- Порт - ( константа PORT )
пароль и логин у каждого свои, а 'HOST' и 'PORT' для популярных почтовых сервисов я приведу в списке.
Сервис | HOST | PORT |
Яндекс | ssl://smtp.yandex.ru | 465 |
Gmail | smtp.gmail.com | 465 |
Mail.ru | ssl://smtp.mail.ru | 465 |
Будьте внимательны с этими параметрами, так как тут легко сделать ошибку и ничего приходить не будет.
С остальным все проще, объяснять по сути и нечего:
// Почта с которой будет приходить письмо const SENDER = 'sender@yandex.ru'; // Почта на которую будет приходить письмо const CATCHER = 'catcher@mail.ru'; // Тема письма const SUBJECT = 'Заявка с сайта'; // Кодировка const CHARSET = 'UTF-8';
Обратите внимание, что почта, указанная в 'const SENDER' должна совпадать с почтой, которую указали в 'LOGIN'.
Валидация формы перед отправкой
Я не стал очень сильно заморачиваться с валидацией, потому как всем, все равно, не угодишь и сделал валидацию на обязательность заполнения полей, а в случае с полем для ввода электронной почты то еще и на корректность ввода адреса.
Все вам понадобится дополнительная валидация, все это реализовано в файле 'valid.php'.
<?php $msgs = []; if (isset($_POST['name']) ) { if(empty($_POST['name']) && NAMEISREQUIRED) { $msgs['name'] = MSGSNAMEERROR; } else { if (!empty($_POST['name'])) { $name = "<b>Имя: </b>" . trim(strip_tags($_POST['name'])) . "<br>"; } } } if (isset($_POST['tel']) ) { if(empty($_POST['tel']) && TELISREQUIRED) { $msgs['tel'] = MSGSTELERROR; } else { if (!empty($_POST['tel'])) { $tel = "<b>Телефон: </b> " . trim(strip_tags($_POST['tel'])) . "<br>"; } } } if (isset($_POST['email']) ) { if(empty($_POST['email']) && EMAILISREQUIRED) { $msgs['email'] = MSGSEMAILERROR; } else { if(!empty($_POST['email'])) { if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { $email = "<b>Почта: </b> " . trim(strip_tags($_POST['email'])) . "<br>"; } else { $msgs['email'] = MSGSEMAILINCORRECT; } } } } if((empty($_POST['email']) && empty($_POST['tel'])) && (!EMAILISREQUIRED && !TELISREQUIRED)) { $msgs['attantion'] = 'Заполните хотя бы одно контактное поле для связи с вами'; } if ($msgs) { echo json_encode($msgs); die; } else { $msgs['success'] = MSGSSUCCESS; }
Еще, я подумал, что было бы полезно сделать так, чтобы скрипт не отправлял данные, если не заполнено хотя бы одно из контактных полей. То есть телефон или email. Вот так я это реализовал.
if((empty($_POST['email']) && empty($_POST['tel'])) && (!EMAILISREQUIRED && !TELISREQUIRED)) { $msgs['attantion'] = 'Заполните хотя бы одно контактное поле для связи с вами'; }
Если вам это не нужно или у вас какой-то другой способ связи, поменяйте под свои нужды или удалите. Вот как это выглядит сейчас:
Отправка формы
Отправка формы осуществляется в файле mail.php, там нечего менять и настраивать. Оставьте как есть, если плохо разбираетесь в php. Если соберетесь добавить свои поля и, по какой-то причине не захотите скачать файл, предложенный мной ниже, где мы будем добавлять обещанный ранее функционал, то в тело письма, после валидации, необходимо передать переменные с данными полученными из формы. Делается это в 34 строке.
<?php // mb_internal_encoding("UTF-8"); // ini_set('error_reporting', E_ALL); // ini_set('display_errors', 1); // ini_set('display_startup_errors', 1); use PHPMailer\PHPMailer\PHPMailer; if ($_SERVER["REQUEST_METHOD"] == "POST") { require_once($_SERVER['DOCUMENT_ROOT'] . '/mail/phpmailer/phpmailer.php'); require_once($_SERVER['DOCUMENT_ROOT'] . '/mail/php/config.php'); require_once($_SERVER['DOCUMENT_ROOT'] . '/mail/php/valid.php'); if(defined('HOST') && HOST != '') { $mail = new PHPMailer; $mail->isSMTP(); $mail->Host = HOST; $mail->SMTPAuth = true; $mail->Username = LOGIN; $mail->Password = PASS; $mail->SMTPSecure = 'ssl'; $mail->Port = PORT; $mail->AddReplyTo(SENDER); } else { $mail = new PHPMailer; } $mail->setFrom(SENDER); $mail->addAddress(CATCHER); $mail->CharSet = CHARSET; $mail->isHTML(true); $mail->Subject = SUBJECT; $mail->Body = "$name $tel $email"; if(!$mail->send()) { } else { echo json_encode($msgs); } } else{ header ("Location: /"); // главная страница вашего лендинга }
Но еще раз напомню, что чуть ниже мы будем добавлять в форму и другие поля, а там изменяться и все эти файлы. Файлы phpmailer - это вспомогательная библиотека для правильной отправки данных на почту. Там ничего трогать нельзя.
Также, в отправке формы и валидацие участвует файл 'mail.js'. Именно он помогает реализовать отправку без перезагрузки страницы. Тут тоже ничего менять не нужно, если вы не планируете использовать страницу благодарности, а вам достаточно того, что уведомление об успешной отправке выводится в форме.
(function ($) { $(".contact-form").submit(function (event) { event.preventDefault(); // Сохраняем в переменную form id текущей формы, на которой сработало событие submit let form = $('#' + $(this).attr('id'))[0]; // Сохраняем в переменные дивы, в которые будем выводить текст ошибки let inpNameError = $(this).find('.contact-form__error_name'); let inpEmailError = $(this).find('.contact-form__error_email'); let inpTelError = $(this).find('.contact-form__error_tel'); // Сохраняем в переменную див, в который будем выводить сообщение формы let formDescription = $(this).find('.contact-form__description'); let fd = new FormData(form); $.ajax({ url: "/mail/php/mail.php", type: "POST", data: fd, processData: false, contentType: false, success: function success(res) { let respond = $.parseJSON(res); if (respond.name) { inpNameError.text(respond.name); } else { inpNameError.text(''); } if (respond.tel) { inpTelError.text(respond.tel); } else { inpTelError.text(''); } if (respond.email) { inpEmailError.text(respond.email); } else { inpEmailError.text(''); } if (respond.attantion) { formDescription.text(respond.attantion).css('color', '#e84a66').fadeIn(); } else { formDescription.text(''); } if (respond.success) { formDescription.text(respond.success).fadeIn(); setTimeout(() => { formDescription.fadeOut("slow"); }, 4000); setTimeout(() => { formDescription.text(''); }, 5000); } }, }); }); }(jQuery));
На этом, в принципе, с основной формой можно заканчивать. Дальше будут только «навороты».
Если что-то упустил или что-то непонятно - пишите в комментариях, попробую объяснить подробнее или дополнить статью.
Форма обратной связи с основными полями
Размер: 1.4 Мб
Стили специально не добавлял в статью, так как статья и так очень большая. В исходнике все есть.
Переброс на страницу благодарности
Как и говорил в начале статьи данная форма может работать как без перезагрузки, так и с перебросом на страницу благодарности. Давайте реализуем это. Нам понадобится немного подправить код в файле 'mail.js' и сама страница благодарности. На скриншоте со структурой проекта вы видели файл 'thank-you-page.php' - это и есть страница благодарности, которую я буду использовать. Как вы могли заметить, он лежит в корне. У вас она может быть где угодно, главное правильно указать к ней путь.
Итак, открываем файл 'mail.js', находим участок кода:
if (respond.success) { formDescription.text(respond.success).fadeIn(); setTimeout(() => { formDescription.fadeOut("slow"); }, 4000); setTimeout(() => { formDescription.text(''); }, 5000); }
И заменяем на:
if (respond.success) { window.location.replace("/thank-you-page.php?status=success"); }
Внимательный читатель мог заметить, что мы передаем GET-параметр, когда указываем страницу для перехода и это не случайно, вы же не хотите, чтобы случайные посетители вашей страницы благодарности появлялись в статистике, если у вас будут настроены цели на посещение этой страницы, поэтому мы реализуем простейший механизм для переброса на главную, если они зашли на страницу без этого параметра в адресной строке. Конечно, шанс что пользователь все равно попадет сюда есть, но он гораздо меньше.
Делать мы это будем при помощи php, поэтому убедитесь, что страница благодарности у вас сохранена именно в этом формате.
Если у вас уже страница в 'html', просто измените расширение. Это никак не повлияет на работоспособность.
Итак, давайте как обычно начнем с разметки. В принципе, это обычная html страница, которую вы вольны оформлять как душе угодно, но, чтобы сработал наш механизм, при котором случайному человеку не будет показываться страничка нам нужно обернуть ее в небольшой php-код.
<? if ($_GET['status'] == 'success') { ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Страница благодарности формы обратной связи</title> <link rel="stylesheet" href="./css/style.css"> <!-- <meta http-equiv="Refresh" content="4; URL=/"> --> </head> <body> <div class="thank-you-page"> <h1 class="thank-you-page__title">Страница благодарности</h1> <p class="thank-you-page__descriptor">Оформляйте как вам будет угодно</p> <a class="thank-you-page__button" href="/">Вернуться на главную</a> </div> </body> </html> <? } else { header ("Location: /"); // главная страница вашего лендинга } ?>
В первой строке мы отлавливаем наш GET-параметр, и, если он совпадает с заданным, то показываем страницу, если нет, то перебрасываем пользователя на главную.
Кроме того, я закомментировал строку, при помощи которой можно автоматически возвращать посетителя на главную через заданный промежуток времени.
<meta http-equiv="Refresh" content="4; URL=/">
То есть это строка говорит, что через 4 секунды после открытия этой страницы, перекинь автоматически посетителя на главную страницу. За это время, человек успеет прочитать ваше сообщение и его благополучно вернет на главную.
Если вам важен такой функционал, то раскомментируйте ее и настройте приемлемое время.
Маска ввода номера телефона
Конечно же вам может понадобиться маска для ввода номера телефона. Я уже делал пару статей на эту тему, поэтому не буду слишком подробно описывать как это делается, просто покажу код.
Для маски ввода номера телефона нам понадобиться сторонний скрипт. Я предлагаю взять 'jQuery Mask Plugin' из статьи, ссылку на которую дал выше.
Подключаем после jQuery. Я делаю это так:
<!-- jQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!-- jQuery Mask Plugin --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.15/jquery.mask.min.js"></script> <script src="/mail/js/mail.js"></script>
Теперь необходимо инициализировать скрипт.
<!-- jQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!-- jQuery Mask Plugin --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.15/jquery.mask.min.js"></script <script src="/mail/js/mail.js"></script> <script> $(function() { $('.contact-form__input_tel').mask('+3(000)000-00-00'); }); </script>
После этого маска успешно появилась в поле телефона:
С этим, думаю, более-менее понятно. Теперь давайте потихоньку добавлять поля для ввода сообщения, чекбокс с принятием пользовательского соглашения и файла.
Совсем подробно расписывать не буду, просто покажу что и куда добавляю, а в конце дам ссылку на исходник. Если какое-то из полей вам не понадобится, то просто не используйте его в разметке, а в файле 'config' - установите значение 'false' там, где задаем обязательность заполнения.
Область для ввода сообщения
Конечно же многим из вас может понадобится поле для ввода сообщения. Для того, чтобы получить его мы воспользуемся тегом 'textarea'. Добавьте следующую разметку в форму:
<div class="contact-form__input-wrapper"> <textarea name="text" class="contact-form__input contact-form__text" placeholder="Введите ваше сообщение"></textarea> <div class="contact-form__error contact-form__error_text"></div> </div>
Стили я уже добавил в 'style.css', так что теперь наша форма выглядит так:
Теперь необходимо передать данные в файл валидации 'valid.php' и проверить все ли в порядке. Как уже говорил выше, у нас простейший случай с проверкой не пустое ли поле. Прежде чем перейти к реализации валидации давайте предположим, что поле для ввода текста обязательно для заполнения.
Для этого перейдем в файл 'config.php' и укажем 'true' в константе, отвечающей за это текстовое поле.
// Текстовое поле const TEXTISREQUIRED = true; const MSGSTEXTERROR = "Поле обязательно для заполнения";
Теперь наше текстовое поле стало обязательно для заполнения. В файле 'valid.php', по аналогии с другими полями напишем такую проверку:
if (isset($_POST['text']) ) { if(empty($_POST['text']) && TEXTISREQUIRED) { $msgs['text'] = MSGSTEXTERROR; } else { if (!empty($_POST['text'])) { $text = "<b>Сообщение: </b> " . trim(strip_tags($_POST['text'])) . "<br>"; } } }
Обратите внимание на 'text' в проверке POST запроса. Этот то самое значение, которое указывали в параметре 'name' у тега 'textarea'.
<textarea name="text" class="contact-form__input contact-form__text" placeholder="Введите ваше сообщение"></textarea>
В файле 'mail.js' сохраним 'div' в который будем выводить ошибку, если валидатор ее вернет для текстового поля:
// Сохраняем в переменные дивы, в которые будем выводить текст ошибки let inpNameError = $(this).find('.contact-form__error_name'); let inpEmailError = $(this).find('.contact-form__error_email'); let inpTelError = $(this).find('.contact-form__error_tel'); let inpTextError = $(this).find('.contact-form__error_text');
А затем, ниже, напишем проверку:
if (respond.text) { inpTextError.text(respond.text); } else { inpTelError.text(''); }
По аналогии вы можете добавлять любые другие поля. Но прежде нужно передать нашу переменную '$text' в тело письма. Делается это в файле 'mail.php' в 34 строке, той самой, о которой я уже упоминал выше.
$mail->Body = "$name $tel $email $text";
Теперь, если все сделали правильно, в письме будут приходить данные и из этого поля.
Еще раз повторюсь, если добавление этого поля показалось слишком сложным, то в конце статьи будет исходник, где можно просто в форме удалить лишнее инпуты, и все будет прекрасно работать.
Checkbox
Настало время добавить 'checkbox' с соглашением на обработку персональных данных. Вы можете делать и другие чекбоксы или радиокнопки. Принцип один и тот же для всех полей.
Создаем разметку в форме, определяем в 'config.php' обязательно ли поле, проверяем в валидаторе и формируем ошибку если она есть и выводим при помощи mail.js ее обратно в форму. Если нет, то передаем в mail.php и отправляем.
Итак, checkbox. Добавим разметку:
<div class="contact-form__input-wrapper"> <input type="checkbox" name="agreement" class="contact-form__input contact-form__checkbox" id="agreement" checked> <label for="agreement" class="contact-form__checkbox-label">Я принимаю условия <a href="#">пользовательского соглашения</a></label> <div class="contact-form__error contact-form__error_agreement"></div> </div>
Не забудьте указать ссылку на соглашение. Стили уже добавлены в исходник.
Идем в файл 'config.php' и делаем поле обязательным.
// Соглашение const AGGREMENTISREQUIRED = true; const MSGSAGGREMENTERROR = "Примите пользовательское соглашение";
Далее открываем файл 'valid.php' и добавляем следующий код:
if(empty($_POST['agreement']) && AGGREMENTISREQUIRED) { $msgs['agreement'] = MSGSAGGREMENTERROR; } else { if (!empty($_POST['agreement'])) { $agreement = "<b>Соглашение: </b> Пользовательское соглашение принято " . "<br>"; } }
Теперь переходим в файл 'mail.js' добавляем 'div' в который будет выводится ошибка, если она есть, и обработчик ошибки:
// Сохраняем в переменные дивы, в которые будем выводить текст ошибки let inpNameError = $(this).find('.contact-form__error_name'); let inpEmailError = $(this).find('.contact-form__error_email'); let inpTelError = $(this).find('.contact-form__error_tel'); let inpTextError = $(this).find('.contact-form__error_text'); let inpAgreementError = $(this).find('.contact-form__error_agreement');
Обработчик ошибки:
if (respond.agreement) { inpAgreementError.text(respond.agreement); } else { inpAgreementError.text(''); }
Осталось в тему письма добавить переменную с текстом о принятии соглашения.
$mail->Body = "$name $tel $email $text $agreement";
В принципе, если поле обязательно модно было этого и не делать, но пусть лучше будет.
Добавление файла
Многим может понадобиться возможность отправки файла, давайте реализуем и этот функционал. Я уже подготовил все, вам остается только добавить разметку и выбрать обязательное ли поле для заполнения.
Разметка:
<div class="contact-form__input-wrapper"> <input class="contact-form__input contact-form__file" type="file" name="files[]"> <div class="contact-form__error contact-form__error_file"></div> </div>
Настройки в файле 'config.php':
// Файл const FILEISREQUIRED = false; const MSGSFILEERROR = "⚠ Забыли добавить файл";
Вот так теперь выглядит форма.
А вот так выглядят пришедшие данные.
Вот такая большая статья о создании формы обратной связи получилась.
Форма обратной связи с дополнительными полями
Размер: 1.4 Мб
Постарался ответить на многие вопросы, которые вы задавали в комментариях и подать материал так, чтобы у вас было как можно меньше проблем, чтобы сделать другие поля по аналогии.
Очистка полей после отправки данных формы на почту
Для того, чтобы очистить форму обратной связи после успешной отправки, нужно добавить несколько строк кода в файл "mail.js". Давайте сделаем это. В первую очередь сохраним в переменную класс формы на которой сработало событие "submit".
Чуть ниже, там где получали "id", добавим переменную "formClass" и передадим класс формы:
. . let form = $('#' + $(this).attr('id'))[0]; // Сохраняем в переменную класс формы let formClass = $(this).attr('class'); // Сохраняем в переменные дивы, в которые будем выводить текст ошибки let inpNameError = $(this).find('.contact-form__error_name'); . .
А когда срабатывает событие success, при успешном ответе сервера, добавим саму очистку полей. Заменим это:
if (respond.success) { formDescription.text(respond.success).fadeIn(); setTimeout(() => { formDescription.fadeOut("slow"); }, 4000); setTimeout(() => { formDescription.text(''); }, 5000); }
На это:
if (respond.success) { formDescription.text(respond.success).fadeIn(); $('.'+formClass).find('input').val(''); $('.'+formClass).find('input').prop('checked', false); $('.'+formClass).find('textarea').val(''); setTimeout(() => { formDescription.fadeOut("slow"); }, 4000); setTimeout(() => { formDescription.text(''); }, 5000); }
Теперь, при успешной отправке, очистятся чекбоксы, обычные поля и textarea.
Автоматическое скачивание файла
Многие просили, чтобы я рассказал как в эту форму добавить возможность скачивания файла после отправки данных формы. Несмотря на то, что статья уже есть на блоге, просили добавить и в эту статью такую возможность. Давайте сделаем это.
Будем отталкиваться от того, что файл, который автоматически будет скачиваться после отправки формы, лежит в папке "files", которая, в свою очередь находится в корне вашего проекта.
Теперь, после успешной отправки нам необходимо добавить "Window.location" со ссылкой на расположение файла. Я предпочитаю делать это с небольшой задержкой, чтобы пользователь успел понять, что произошло, а именно увидеть сообщение об успешной отправке. Можно, конечно, и прелоадер "прикрутить", но это уже дело вкуса.
Напоминаю, что сигналом о том, что сообщение успешно отправлено у нас является строка пришедшая в файле "mail.js". Вот тут:
if (respond.success) { //. // some code //. }
Сюда и будем добавлять ссылку на файл. Поставим задержку в 1 секунду при помощи "setTimeout".
if (respond.success) { setTimeout(() => { window.location = '/files/test-file.docx'; }, 1000); }
Если вы работаете со страницей благодарности, то можно на нее поместить тот же код, например, просто в футере.
<script> window.onload = function() { setTimeout(() => { window.location = '/files/test-file.docx'; }, 1000); }; </script>
Важно
Для корректной работы потребуется:
- PHP > 7.
- Сам сервер
- Jquery 3 версии
- Если тестируете на хостинге, то должен быть не тестовый период, не бесплатный домен и у хостера не отключена функция mail. Во всех этих случая хостер может накладывать ограничение на работоспособность под предлогом борьбы со спамом. Кроме того, некоторые хостеры не позволяют отправлять сообщения с почтовых адресов не привязанных к сайту.
- Перед тем как задать вопрос, посмотрите нет ли ошибок в консоли и попробуйте вывести ошибки php.
- Если не приходят сообщения, проверьте не попали ли письма в спам.
- Если вам лень разбираться и самостоятельно делать форму, то рекомендую обратить внимание на конструкторы форм обратной связи
Как вам такой формат статей? Нужно ли делать настолько большие?
378 комментариев
возникает Unexpected token < in JSON at position 0
в чем может быть проблема?
вот потом из за таких горе верстальщиков и появляются доноры для спама...
если не валидировать и не запрещать символы ссылки и тому подобное в именах и в тексте... то с ваших горе одностраничников и сайтов будут слать спам!.. до тех пор пока вваш сервер не загонят под фильтры..
верстальшики... твою мать
Анон, ути-пути, анонимный гуру пришел и рассказал как правильно делать. А нет, налил воды просто и проквакал. Во-первых это учебный пример, чтобы предать суть того, как отправляется форма, а каждый уже дорабатывает под свои нужды. Во-вторых на блоге есть статьи, как прикрутить каптчу, сделать отправку по клику, а не submit и так далее, чтобы было меньше спама. В-третьих, почему-то ни один человек еще не жаловался, что его засыпает спамом и сервер "ложится", используя эту форму. Появится спрос или проблема, тогда и буду расширять статью и делать ее еще более подробной, а пока, не вижу в этом смысла. Поэтому, всего доброго. Поищите ресурс, который достоин вашего уровня знаний.
Александр, ошибка говорит, что не найден файл phpmailer.php по указанному пути. Проверьте его наличие.
Cтранно, сейчас распаковал просто ваш архив, ничего не меняя, и все равно эта ошибка, в папке првоерил phpmailer присутствует, подскажиет куда еще покопать?
dimadv7,
Александр, а на чем вы тестируете, на локальном или реальном сервере?
тоже проблема Fatal error: Class 'PHPMailer\PHPMailer\Exception' not found in /home/c/ck69968/123/public_html/mail/phpmailer/phpmailer.php on line 1960
файл доступен /public_html/mail/phpmailer/phpmailer.php
Дмитрий, ясам так и не разобрался что было, но дима(автор), решил проблему буквально за несколько часов и взял недорого.
Дмитрий, проверьте все по этой статье, сначала.
Здравствуйте. Не подскажете, в чем может быть ошибка...форму открываю на openserver, php 7.2, smtp данные забил...вылезает такая ошибка
что это может быть?
скриншот:
https://yadi.sk/i/hKvgx43mA-GL6Q
Николай, если вы использует SMTP, то пропишите правильно эти данные. Если - нет, то закомментируйте строки связанные с SMTP в файле, где прописываете почту. Предполагаю, что проблема в этом у вас.
Добрый день. const CATCHER = 'catcher@mail.ru'; - переменная адреса клиента. Ничего менять не нужно?
Александр, здравствуйте. Нет, только вписать адрес, на который будут приходить письма.
Почему при нажатии отправить, приходит одновременно 2 сообщения?
Денис, наверное, вы добавили несколько форм и забыли поменять id. У каждой формы должен буть уникальный id.
Здраствуйте хотел бы разобратся как работает. Сделал все как написано но не приходят заявки... выдает ошибку 404 mail.php
jquery.min.js:2 POST _http://142.93.174.49/mail/php/mail.php 404 (Not Found)
Михаил, здравствуйте. Пройдиетесь по пунктам из этой статьи. Если проблема останется, будем разбираться дальше.
Да я читал раньше проверял, но проблема не ушла. 1 это не приходят письма а 2 не перекидывает на страницу спасибо
Вы через SMTP-протокол пытаетесь отправить? Попробуйте закомментировать и отправить без него.
Все таже ошибка
По другой php форме все норм отправляет __http://142.93.174.49/lander/olio879/index.php
но мне нужно что б была страница спасибо, а я что только не пробовал но не получаутся редиректить на спасибо(((
По чужим формам я точно не помощник.
Так я почему ж ваша у меня не хочет работать? я просто привет пример что работает форма но почему-то не вашша
Михаил, вы меняли что-то в форме? Скачайте исходник, распакуйте в корень сайта папку mail, если там используется SMTP - закомментируйте строки связанные с ним. В catcher укажите свой email, в sender email отправителя. Оба ящика должны быть реальными. При этом, PHP >= 7, jQuery > 3.1.
Михайл, сделали? Вот я закинул к себе архив, закомментировал все, что связанно с SMTP: https://prnt.sc/vb6oxy
Вот отправил письма с обоих форм: раз - https://prnt.sc/vb6pe7, и два: https://prnt.sc/vb6psh
Заняло 3 минут, все работает.
Михаил??? Вы еще на связи? Вам нужна помощь или нет?
сделал все как сказали ошибка та же. + если просто скачать форму там не подключены пару файлов https://prnt.sc/vb7o3v
но это ладно надо по точке добавить впереди файлов.... после того как добавляю все норм https://prnt.sc/vb7p40 ... отправляю заявку https://prnt.sc/vb7pqa
Михаил, файлы подключены правильно... от корня сайта. Тестировать на сервере нужно... Ничего править в путях, если все в корне находится, не нужно.
Да делал все как и сказали но проблема не ушла, и если скачать исходники там не коректно пути прописаны к стилям и маил.js https://prnt.sc/vb7o3v https://prnt.sc/vb7p40 https://prnt.sc/vb7pqa https://prnt.sc/vb7ug9
Зайдите сейчас на сайт _http://dimadvds.bget.ru/ отправьте форму.
Ошибка говорит, что по данному пути нет файла mail.php, где он у вас лежит? Если уж правите пути, то правьте и в файле, на который указывает ошибка ,а именно в файле mail.js
Вот ваши данные: https://prnt.sc/vb7ziv, которые вы отправили с моего сайта, и вот: https://prnt.sc/vb89lb
Михаил, просто, раз уж вы тестируете не в корне сайта, то, ориентируясь на подсказки в консоли, найдите пути ко всем файлам и пропишите их относительно вашей структуры.
без понятие почему не работает ... уже выдает такую ошибку
jquery.min.js:2 POST _http://142.93.174.49/lander/forma-v1-zip/mail/php/mail.php
500 (Internal Server Error)
send @ jquery.min.js:2
ajax @ jquery.min.js:2
(anonymous) @ mail.js:22
dispatch @ jquery.min.js:2
y.handle @ jquery.min.js:2
Потому, что пути неправильно прописаны, относительно вашей структуры сайта. По умолчанию настройки сделаны для структуры, когда все лежит в корне, у вас совсем иначе. Вам же консоль подсказывает, что 404, значит по такому пути файла нет, правьте под вашу структуру пути. Там же показывает, где и в каком файле нужно поправить. Папка mail у вас должна лежать по пути _http://142.93.174.49/mail/, чтобы работало по умолчанию, у вас она там не лежит. В таком случае ничего удивительного, что вам скрипт пишет, что по такому пути ничего нет. Поправьте пути, будет работать. Или используйте структуру, которую предложил я.
Столкнулся с такой проблемой
Fatal error: Uncaught Error: Class 'PHPMailer\PHPMailer\Exception' not found in /home/users/i/ilyas-z/domains/demo/mail/phpmailer/phpmailer.php:1775
Влад, зачем вам "PHPMailer\PHPMailer\Exception" ?
Боже, сколько геморроя для задротов
Дима, добрый день. Надеюсь у вас все Хорошо. Хотел спросить, можно ли реализовать в этой форме следующее:
После отправки формы - отправлять ответное письмо с прикрепленным файлом и своим текстом клиенту на почту? Спасибо
Игорь, думаю да. У вас же есть статус об успешной отправке письма вам. Значит в том месте можно сформировать заголовки и тело нового письма, указать отправителя и получателя и отправить его.
Дима, добрый день. Меня зовут Максим. У меня есть сайт с уже готовой формой, которую нужно подключить , сайт лежит на гитхабе, подскажите, будет ли работать на гитхабе предложенный вами вариант и если нет, то можете ли помочь с подключением существующей формы к варианту, который будет работать на гитхаб?
Недавно писал статью об отправке данных из формы в гугл-таблицу, там же есть возможность отправить и на почту. Тот вариант сработает и на гитхабе. Вот статья.
Здравствуйте. Создаю сайт для брата и он попросил сделать обратную связь с клиентом. Сам я пока еще обучаюсь этому. В настоящее время сайт еще не запущен. Хотел спросить, есть ли возможность отправить текстовое сообщение с незапущенного сайта. У меня выдает ошибку "Cannot POST /" или это все таки работает с запущенным сайтом? Спавсибо
Тестировать нужно на сервере. Не важно на каком, локальном или нет.
Здравствуйте, как можно дополнить скрипт, что бы отправителю приходило уведомлении с произвольным текстом?
Доброго времени суток, Дмитрий! Огромное спасибо за статью! Вот прям выручили))
Но есть две проблемы : 1 - письма приходят на почту, а файлы не приходят
2 - очистка полей не работает..
подскажите пожалуйста детально как можно решить данную проблему? (в этом я ещё новичок)
Заранее спасибо!
Здравствуйте: Дмитрий!
Могу ли я использовать форму обратной связи в виртуальном туре (панораме) ? Виртуальный тур находится на сервере и доступен для просмотра. Саму форму обратной связи я могу вставить в панораму и открывать в панораме. Как заполненную форму отправить на почту. Спасибо!
Здравствуйте!
А как сделать, чтобы при клике на кнопку "Отправить" появлялось модальное окно? В вашей статье увидел два других варианта - сообщение об успешной отправке и переход на страницу благодарности.
Александр, здравствуйте. Создать модальное окно. Скрыть его, например, при помощи dispaly: none. При успешной отправке дать модальному окну dispaly:block или класс новый добавить, у которого будет display:block.
А как сделать горизонтальную форму обратной связи?
Поясню: надо вставить на фото форму обратной связи в одну строку. Не колонкой. Имя, е-мейл и кнопка отправки на почту или на гугл форму
В браузере - норм. Но хостинг Timeweb (через клиенты FileZilla и Cyberduck) не может считать стили, именно для данной формы! Почему?
*ставишь перед адресной строкой https:// - и все работает. Это решается хостинговыми настройками или можно прописать в коде?
Советуют вставить
if(isset($_SERVER['HTTPS'])) {
$schema = 'https://';
}
else {
$schema = 'http://';
}
define('WP_HOME', $schema.$_SERVER['SERVER_NAME']);
define('WP_SITEURL', $schema.$_SERVER['SERVER_NAME']);
..Если это выход, то куда конкретно это надо впихнуть?
.. проверила полную работу с добавленным в адресную строку https. Стили на окно работают, но не работают error-подсказки и уведомление об отправке невидимое.. А без https без стилей все отображается..
Выдает такую ошибку. Хостинг reg.ru, подскажите пожалуйста, что делаю не так. Распаковал прямо в корень.
Вячеслав, вроде как не может файл найти по этому пути скрипт.
Ни в архиве formav1 ни в архиве formav2 файла Exception в подпапках /mail/phpmailer/ нет. В итоге я вообще в принципе просто взял архив без изменений и залил на хостинг (reg.ru). Единственное изменения конфига на свою почту (пробовал 2-ве яндекс и майл). Ошибка никуда не исчезает.
Вячеслав, как же нет? Вот: https://prnt.sc/1vz1xyb
Смотрите я залил на свой хостинг прямо из архива, ничего не меняя https://prnt.sc/1w005zv в том числе и папку на которую вы указали https://prnt.sc/1w009lo. Да данные файлы есть. Далее я открываю страницу и заполняю форму https://prnt.sc/1w00dmt после нажатия на кнопку "Получить прайс" в консоли отображаются данные ошибки https://prnt.sc/1w00ifb. При этом файл конфиг я изменил строго по инструкции выше https://prnt.sc/1w00klw. Соответственно файл mail.php я не менял https://prnt.sc/1w00mjz и тем более не трогал phpmailer.php https://prnt.sc/1w00p7e. И вот вопрос почему не работает...
Отлично, а теперь попробуйте не с яндексом сделать. Если нужен яндекс, то сделайте почту для домена в яндекс коннект, так как с недавнего времени нельзя использовать обычную почту для отправки с сайта через SMTP.
Дмитрий, проблема в том, что я использовал 3 вида почты: яндекс, mail.ru и создавал на хостинге от своего домена. Ошибка одинаковая везде. Помучавшись с phpmailer, я даже в какой то момент прописывал use Exception и закидывал из оригинального PHPMailer, но выдавал ошибку из mail.js на тему parseJSON
И вот я в тупике нахожусь
Вячеслав, подскажите какая версия PHP?
Попробуйте включить вывод предупреждений и ошибок php в файле mail.php
https://prnt.sc/1w0c2vr
Посмотрим, в чем ошибка.
https://prnt.sc/1w4g6ch вот такие ошибки после включения предупреждений. PHP версии с 5.1.6 (alt) по 8.0.10 (alt)
Вячеслав, отлично, версию PHP поставьте от 7.1 до 7.3 для тестов. И пришлите ошибку в консоли которая.
Подскажите еще, вы используете поле с файлом для отправки? Если нет - то, лучше закомментируйте это в файле mail.php: https://prnt.sc/1w4i3yu
PHP версии https://prnt.sc/1w4m53j код закомментировал. Config.php с почтой mail.ru https://prnt.sc/1w4mbw0 Ошибка осталась https://prnt.sc/1w4mdqi
Версии php в панели управления хостингом не могу отключить идут по дефолту
Так какая текущая версия php? Скрипт не будет работать с 5.1. Она лет 6 назад уже считалась устаревшей.
Сообщения не приходят.
При нажатии на кнопку "Получить прайс" просто обновляется страница, не перекидывает на страницу благодарности. Ошибок в консоле нет. Почта активна. Пускал с джумлы тестовые письма, все приходили. Php 7.3
Что может быть?
Антон, вот тут топ 10 причин по которым может не отрпавляется форма. Кроме того, если используете SMTP и яндекс почту, то почта сейчас обязательно должна быть привязана к домену в Яндекс.Коннект.
Понял что у меня нет связи с файлом config.php. Потому что обязательные поля не работают. При попытке получить доступ к любому файлу с расширением .php через адресную строку - получаю редирект на главную страницу. Буду сейчас решать, спасибо за помощь
Здравствуйте, Дмитрий
Пытаюсь самостоятельно настроить Переброс на страницу благодарности. Не выходит:
У меня на странице есть еще квиз, поэтому код, который подлежит замене отличается от примера:
И квиз не должен перебрасывать. И кроме того, не срабатывает автоматическое возвращение посетителя на главную через заданный промежуток времени. Строку я раскомментировал.
Эта страница Вам должна быть знакома :) hpltop.ru
Здравствуйте. В вашем случае нужно проверять Id формы и делать переброс на страницу благодарности только в том случае, если ответ пришел от нужной формы. По аналогии с условиями и действиями только для формы с квизом.
if (idFOrm === "quiz__form") {}
Да, Дмитрий, для меня это темный лес.
Ну, пробуйте, столкнетесь с ошибкой или сложностями - пишите. Будем разбираться.
У меня там 4 формы с разными ID
И все 4 должны перебрасывать на страницу благодарности. И каждую надо проверять?
И т.д. ?
Если после отправки остальных форм ожидается общее поведение, то можно в одной строке сделать проверку посредством оператора "или" то есть "||".
if (idFOrm === "diler__form" || idFOrm === "cooperation__form") {}
Дмитрий, вроде работает. Можете посмотреть?
Да, вроде все нормально))
Спасибо, Дмитрий. Теперь начну Вас доставать по интеграции форм и квиза в Битрикс.
Здравствуйте!
Никак не могу сообразить, как настроить отправку данных из нескольких форм с LP так, что бы в теле письма указывался id формы. Подскажите где и что необходимо прописать в sendmail, что бы в письмо подставлялся id формы и можно ли этот id переименовывать в читабельный вид из в " первая форма на сайте"?
Алексей, конечно можно, но лучше прсото сделать скрытое поле, которое, например, назвать "theme", задать значение поумочанию, например, "обратный звонок", "скачали прайс" и так далее. И передавать его. Если нужна конкретная помощь именно по id, напишите.
На php-fpm не работает. Только на fastcgi. Печально. Или есть варианты решения?
Barinov, nginx + php-fpm, работает всё же. Но пока не воспроизводится сообщение "Сообщение успешно отправлено".
Форма - собери меня, если сможешь. Впрочем как и все бесплатные в интернете. Работает она на PHP 5.5
Дима, подскажи, пожалуйста, как сделать на каждой странице отдельную форму так, чтобы были разные получатели?
Уух! Ну можно получать адресную строку и передавать в форму, а уже в обработчике проверять эту строку и, в зависимости от того какой адрес, подставлять разную почту. Как-то так..
Добрый день!
Запускаю выполнение в VSC при помощи PHP Server. На 3000 порту.
После заполнения формы на сайте нажимаю "Отправить заявку" и после этого в терминале выдает такую ошибку:
[Sun Nov 19 13:01:08 2023] [200] /mail/php/mail.php
[Sun Nov 19 18:01:08 2023] [::1]:59995 [200]: POST /mail/php/mail.php - Uncaught Error: Class "PHPMailer\PHPMailer\Exception" not found in C:\Users\Fanil\Desktop\forma-mail\mail\phpmailer\phpmailer.php:1920
Stack trace:
#0 C:\Users\Fanil\Desktop\forma-mail\mail\phpmailer\phpmailer.php(1774): PHPMailer\PHPMailer\PHPMailer->smtpConnect(Array)
#1 C:\Users\Fanil\Desktop\forma-mail\mail\phpmailer\phpmailer.php(1516): PHPMailer\PHPMailer\PHPMailer->smtpSend('Date: Sun, 19 N...', '\xD0\x98\xD0\xBC\xD1\x8F: ...')
#2 C:\Users\Fanil\Desktop\forma-mail\mail\phpmailer\phpmailer.php(1352): PHPMailer\PHPMailer\PHPMailer->postSend()
#3 C:\Users\Fanil\Desktop\forma-mail\mail\php\mail.php(35): PHPMailer\PHPMailer\PHPMailer->send()
#4 {main}
thrown in C:\Users\Fanil\Desktop\forma-mail\mail\phpmailer\phpmailer.php on line 1920
[Sun Nov 19 18:01:08 2023] [::1]:59995 Closing
То есть ругается на 1920 строку на оператор Exception.
Подскажите - что делать?
Фаниль,
В общем-то, решил этот вопрос после исправлений в исходных кодах php.
Теперь нужно как-то поправить коды для того, чтобы при успешной отправке все-таки появлялось сообщение - "Сообщение успешно отправлено", а то оно не появляется и клиенты не понимают - отправилось ли их письмо и молотят по кнопке "Получить прайс" (у меня просто "Отправить").
Кто-то уже решил этот вопрос?
Здравствуйте!
Подскажи код (или готовый плагин) простейшей формы обратной связи только с сохранением на отдельную страницу на самом сайте (без отправки на почту ) только на html+PHP (или вообще на чистом html и JS если можно)
Надо:
- текстовое поле для написания (можно с инструментами редактирования) и может поле для имени
- посетитель пишет имя, и текст какой то сообщения, это все отправляется на отдельную страницу на этом же домене/сайте (не куда то и не по почте), и там просто все подряд идут сообщения из формы кто пишет, только добавляется время, IP и может какие то данные браузера и компа какие можно. И так штук по 20-30 на страницу
- эту страницу со списком подряд всех сообщений с сайта - вход под паролем можно - имя страницы типа имя_сайта.ru/заявки/заявки_дата.html
ну типа страница как форума, только просто то что написали в форму (вот как эта форма куд я сейчас пишу вопрос), но только вывод на другую секретную страницу и видно только тем кто знает адрес и/или еще и пароль.
Спасибо!