Всплывающая форма обратной связи

В предыдущей статье мы разобрали создание контактной формы, реализовали отправку писем с реальных E-mail адресов и SMTP-серверов популярных почтовиков (ЯндексПочта, mail.ru, gmail.ru).

В этом посте продолжим тему и рассмотрим как сделать форму обратной связи во всплывающем окне. Для этого воспользуемся возможностями, которые предоставляет фреймворк Bootstrap 4. В данной статье не будем разбирать технический процесс отправки почты, так как сделали это в прошлой.

Возьмем все исходники из прошлой статьи, нам не понадобится main.css, так как будем использовать стили бутстрапа. Изменим только index.html.

Для быстроты я подключу фреймворк с CDN, скопировав стартовый шаблон из документации, но здесь есть один нюанс. В бутстраповском шаблоне подключается урезанная версия jQuery, а в ней нет поддержки Ajax, который мы использовали для обращения к серверу, поэтому подключим полную версию jQuery, а урезанную я закомментирую и оставлю для примера.

<!DOCTYPE html>
<html lang="ru">
<head>
	<!-- Required meta tags -->
	<meta charset="utf-8">
  	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  	<!-- Bootstrap CSS -->
  	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">

	<title>Bootstrap 4: всплывающая форма обратной связи</title>
</head>
<body>
	
	<!-- Optional JavaScript -->
	<!-- jQuery first, then Popper.js, then Bootstrap JS -->

	<!-- Подключение урезанной версии jQuery -->
	<!-- <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> -->

	<!-- Подключение полной версии jQuery -->
	<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
</body>
</html>

Подключим необходимые нам скрипты в самый конец перед закрывающим тегом body:

<!-- Маска для номера телефона -->
<script src="js/jquery.maskedinput.min.js"></script>
<!-- Инициализация и Ajax-запрос -->
<script src="js/main.js"></script>

Сделаем на нашей страничке кнопку, открывающую всплывающее окно:

<div class="container">
    <div class="my-5 mx-auto text-center">
        <button class="btn btn-dark btn-lg" data-toggle="modal" data-target="#exampleModal">Открыть модальное окно</button>
    </div>
</div>

Ну и HTML-код самого модального окна:

<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">Обратная связь</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>
        </div>
    </div>
</div>

Из всплывающего окна я убрал .modal-footer, если он вам нужен или вы хотите изменить внешний вид или какие-то настройки окна, то прочитайте статью «Bootstrap 4 – модальное окно».

Осталось в блок с классом .modal-body вставить HTML-код формы бутстрапа:

<form id="contactForm" action="handler.php" method="post">
    <div class="form-group">
        <label for="name">Ваше имя:</label>
        <input id="name" class="form-control" name="name" required type="text" placeholder="Иванов Иван Иванович">
    </div>
    <div class="form-group">
        <label for="email">Ваш E-mail:</label>
        <input id="email" class="form-control" name="email" required type="text" placeholder="ivanov@email.com">
    </div>
    <div class="form-group">
        <label for="phone">Ваш телефон:</label>
        <input id="phone" class="form-control" name="phone" required type="text" placeholder="+7 (800) 000-00-00">
    </div>
    <div class="form-group">
        <label for="message">Текст сообщения:</label>
        <textarea id="message" class="form-control" required name="message" rows="4"></textarea>
    </div>
    <div class="form-group form-check">
        <input id="check" class="form-check-input" checked type="checkbox">
        <label class="form-check-label" for="check">Я добровольно отправляю свои данные</label>
    </div>
    <button id="button" class="btn btn-success" type="submit">Отправить</button>
    <div class="result">
        <span id="answer"></span>
        <span id="loader" style="display:none"><img src="images/loader.gif" alt=""></span>
    </div>
</form>

Форма практически не изменилась, поменялись классы на бутстраповские и для лоадера я установил display: none; прямо в HTML-коде, так как main.css мы не подключали.

В результате внешний вид нашей формы получился следующим:

Пример контактной формы Bootstrap 4 в модальном окне

Окончательный код в index.html:

<!DOCTYPE html>
<html lang="ru">
<head>
	<!-- Required meta tags -->
	<meta charset="utf-8">
  	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  	<!-- Bootstrap CSS -->
  	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">

	<title>Bootstrap 4: всплывающая форма обратной связи</title>
</head>
<body>

	<div class="container">
		<div class="my-5 mx-auto text-center">
			<button class="btn btn-dark btn-lg" data-toggle="modal" data-target="#exampleModal">Открыть модальное окно</button>
		</div>
	</div>

	<!-- Modal -->
	<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
		<div class="modal-dialog" role="document">
			<div class="modal-content">
				<div class="modal-header">
					<h5 class="modal-title" id="exampleModalLabel">Обратная связь</h5>
					<button type="button" class="close" data-dismiss="modal" aria-label="Close">
						<span aria-hidden="true">&times;</span>
					</button>
				</div>
				<div class="modal-body">
					<form id="contactForm" action="handler.php" method="post">
						<div class="form-group">
							<label for="name">Ваше имя:</label>
							<input id="name" class="form-control" name="name" required type="text" placeholder="Иванов Иван Иванович">
						</div>
						<div class="form-group">
							<label for="email">Ваш E-mail:</label>
							<input id="email" class="form-control" name="email" required type="email" placeholder="ivanov@email.com">
						</div>
						<div class="form-group">
							<label for="phone">Ваш телефон:</label>
							<input id="phone" class="form-control" name="phone" required type="text" placeholder="+7 (800) 000-00-00">
						</div>
						<div class="form-group">
							<label for="message">Текст сообщения:</label>
							<textarea id="message" class="form-control" required name="message" rows="4"></textarea>
						</div>
						<div class="form-group form-check">
							<input id="check" class="form-check-input" checked type="checkbox">
							<label class="form-check-label" for="check">Я добровольно отправляю свои данные</label>
						</div>
						<button id="button" class="btn btn-success" type="submit">Отправить</button>
						<div class="result">
							<span id="answer"></span>
							<span id="loader" style="display:none"><img src="images/loader.gif" alt=""></span>
						</div>
					</form>
				</div>
			</div>
		</div>
	</div>
	
	<!-- Optional JavaScript -->
	<!-- jQuery first, then Popper.js, then Bootstrap JS -->

	<!-- Подключение урезанной версии jQuery -->
	<!-- <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> -->

	<!-- Подключение полной версии jQuery -->
	<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
	
	<!-- Маска для номера телефона -->
	<script src="js/jquery.maskedinput.min.js"></script>
	<!-- Инициализация и Ajax-запрос -->
	<script src="js/main.js"></script>
</body>
</html>

Нужно еще немного изменить наш код в main.js, поменять класс для очищения полей после отправки формы с .field на .form-control, остальное оставляем без изменения.

В итоге в main.js код стал таким:

jQuery(document).ready(function($) {

    // Добавляем маску для поля с номера телефона
    $('#phone').mask('+7 (999) 999-99-99');

    // Проверяет отмечен ли чекбокс согласия
    // с обработкой персональных данных
    $('#check').on('click', function() {
        if ($("#check").prop("checked")) {
            $('#button').attr('disabled', false);
        } else {
            $('#button').attr('disabled', true);
        }
    });

    // Отправляет данные из формы на сервер и получает ответ
    $('#contactForm').on('submit', function(event) {
        
        event.preventDefault();

        var form = $('#contactForm'),
            button = $('#button'),
            answer = $('#answer'),
            loader = $('#loader');

        $.ajax({
            url: 'handler.php',
            type: 'POST',
            data: form.serialize(),
            beforeSend: function() {
                answer.empty();
                button.attr('disabled', true).css('margin-bottom', '20px');
                loader.fadeIn();
            },
            success: function(result) {
                loader.fadeOut(300, function() {
                    answer.text(result);
                });
                form.find('.form-control').val('');
                button.attr('disabled', false);
            },
            error: function() {
                loader.fadeOut(300, function() {
                    answer.text('Произошла ошибка! Попробуйте позже.');
                });
                button.attr('disabled', false);
            }
        });
    
    });

});

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

Вместо Bootstrap можно использовать любой другой фреймворк. На этом статью и тему с формой обратной связи буду заканчивать. Если остались вопросы, спрашивайте.

Похожие записи: Axios: библиотека для работы с Ajax без использования jQuery Контактная форма обратной связи для сайта своими руками Open Server: установка и работа с сервером
Добавлено коментариев -  12
  • Андрей 13.05.2018 12:02

    За форму обратной связи большое спасибо. Но было бы не лишним так же написать про handler.php и настройку PHPMailer, потому что мало понимающий в этом человек просто не поймет, почему его письма не отправляются)

    Ответить
    • Евгений 13.05.2018 14:57

      Об этом я писал в прошлой статье и дал ссылку на нее в начале этого поста)

      Ответить
  • Владимир 12.10.2018 22:32

    Добрый день, как встроить кнопку вызова модального окна на уже имеющуюся страницу сайта - чтобы не тащить на нее весь код из файла index.html

    Ответить
    • Евгений 13.10.2018 17:07

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

      Ответить
  • Владимир 13.10.2018 22:53

    Добрый вечер, не получается настроить отправку

    <?php
    
    use PHPMailer\PHPMailer\Exception;
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    
    require_once __DIR__ . '/PHPMailer/src/Exception.php';
    require_once __DIR__ . '/PHPMailer/src/PHPMailer.php';
    require_once __DIR__ . '/PHPMailer/src/SMTP.php';
    /**
     * Mailer: класс-хелпер, отправляет почту администратору
     */
    class ContactMailer
    {
    	/**
         * E-mail отправителя
         * @var string
         */
        private static $emailFrom = 'from@mail.ru';
        /**
         * E-mail получателя
         * @var string
         */
        private static $emailTo = 'to@gmail.com';
    
        /**
         * Отправляет писмо, если письмо отправлено,
         * возвращает TRUE, в противном случае FALSE.
         * @param string $name
         * @param string $email
         * @param string $phone
         * @param string $message
         * @return boolean
         */
        public static function send($name, $email, $phone, $message)
        {
    		// Формируем тело письма
    		$body = "Имя: " . $name . "\nE-mail: " . $email . "\nТелефон: " . $phone . "\n\nСообщение:\n" . $message;
    
    		// Создаем объект PHPMailer
            $mailer = new PHPMailer();
            // Настройки подключения
            $mailer->isSMTP();
            // Устанавливает хост почтового сервера (Mail.ru: smtp.mail.ru, Google: smtp.gmail.com)
            $mailer->Host = 'smtp.mail.ru';
            // Включает SMTP-авторизацию
            $mailer->SMTPAuth = true;
            // Логин или E-mail целиком
            $mailer->Username = self::$emailFrom;
            // Пароль от почтового ящика
            $mailer->Password = 'passwd';
            // Протокол соединения
            $mailer->SMTPSecure = 'ssl';
            // Порт для исходящаей почты
            $mailer->Port = '465';
    
            // Устанавливает кодировку
            $mailer->CharSet = 'UTF-8';
            // Устанавливает E-mail и имя отправителя
            $mailer->setFrom(self::$emailFrom, 'Имя отправителя');
            // Добавляет E-mail получателя
            $mailer->addAddress(self::$emailTo);
            // Настройка HTML-формата
            $mailer->isHTML(false);
            // Тема письма
            $mailer->Subject = 'Заполнена форма обратной связи';
            // Основное тело письма
            $mailer->Body = $body;
            
            // Отправляет письмо
            if ($mailer->send()) {
            	return true;
            }
        	return false;
        }
    }

    "произошла ошибка не удалось отправить сообщение"

    куда еще можно посмотреть?

    Ответить
    • Евгений 14.10.2018 02:39

      1. Версия PHP должна быть 5.5 или выше.

      2. Для вывода ошибки (исключения) на экран передайте true при создании объекта:

      $mailer = new PHPMailer(true);
      Ответить
  • Владимир 14.10.2018 20:55

    <br /> <b>Fatal error</b>: Uncaught exception 'PHPMailer\PHPMailer\Exception' with message 'SMTP Error: data not accepted.' in /var/www/u0568730/data/www/site.ru/mailer/PHPMailer/src/PHPMailer.php:1757 Stack trace: #0 /var/www/u0568730/data/www/site.ru/mailer/PHPMailer/src/PHPMailer.php(1481): PHPMailer\PHPMailer\PHPMailer-&gt;smtpSend('Date: Sun, 14 O...', '\xD0\x98\xD0\xBC\xD1\x8F: ee\r\nE-m...') #1 /var/www/u0568730/data/www/site.ru/mailer/PHPMailer/src/PHPMailer.php(1320): PHPMailer\PHPMailer\PHPMailer-&gt;postSend() #2 /var/www/u0568730/data/www/site.ru/mailer/ContactMailer.php(71): PHPMailer\PHPMailer\PHPMailer-&gt;send() #3 /var/www/u0568730/data/www/site.ru/handler.php(31): ContactMailer::send('ee', 'mymail@gm...', '+7 (333) 333-33...', '33333') #4 {main} thrown in <b>/var/www/u0568730/data/www/site.ru/mailer/PHPMailer/src/PHPMailer.php</b> on line <b>1757</b><br />
    Ответить
    • Евгений 15.10.2018 20:46

      Здесь скорее всего проблема либо в e-mail адресе отправителя, либо в вашем сервере.

      Ответить
      • Владимир 16.10.2018 21:27

        Проблема решена: я делал на mail.ru и вот очень интересно себя ведет этот сервис- я использовал действующую почту, но достаточно давно созданную. При заходе в свою почту на mail.ru все проходит гладко - я могу отправлять и принимать письма, но через вашу форму не отправляет - пишет ошибка. Через сутки при попытке зайти в свою почту на сервере mail.ru всплывает оповещение о том, что ящик забллокирован и требуется подтвердить через sms (обычное дело сейчас). После того как подтверждаешь - отправка через вашу форму начинает работать.

        Ответить
        • Евгений 16.10.2018 21:46

          Черт его знает, я реализовывал отправку через все три самых популярных почтовых сервиса (Яндекс, Mail и Gmail), у меня всегда все срабатывало корректно. Почему ваш конкретный ящик вызвал подозрение, может когда-то пытались делать рассылки через него. В общем главное, что отправляется теперь форма))

          Ответить
  • Шахзод 13.11.2018 07:16

    Добрый день Евгений! вот я всё сделал как по инструции но при отправке формы выдаёт ошибку: Р”оступ запрещен!

    что я делаю не так?

    Ответить
    • Евгений 14.11.2018 09:04

      Здравствуйте! Во-первых сделайте кодировку нормальную, чтоб сообщения об ошибкак читались, во-вторых нужно включить debug-режим, как это сделать я писал здесь.

      Ответить

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

Нажимая на кнопку «Добавить», я даю согласие на обработку своих персональных данных в соответствии с политикой конфиденциальности