WordPress. Простая форма обратной связи на Ajax • 1 • WPRUSe

WordPress. Простая форма обратной связи на Ajax

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

Для тех кто хочет разобраться или по какой-то причине не любит плагины.

Хотя плагином сделать подобную форму можно без проблем — это будет быстрее, проще и удобнее. Например, плагином Simple Basic Contact Form.

Итак, создаем форму обратной связи без плагина. Алгоритм простой

  1. Создание и вывод формы
  2. Подключение ajax
  3. Подключение обработчика

Приступим.

Внимание! Код добавлять в файл functions.php дочерней темы или пустой плагин.

1. Создаем и выводим форму

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

add_shortcode( 'art_feedback', 'art_feedback' );
/**
 * Шорткод вывода формы
 *
 * @return string
 * @see https://wpruse.ru/?p=3224
 */
function art_feedback() {

	ob_start();
	?>
	<form id="add_feedback">
		<input type="text" name="art_name" id="art_name" class="required art_name" placeholder="Ваше имя" value=""/>
		<input type="email" name="art_email" id="art_email" class="required art_email" placeholder="Ваш E-Mail" value=""/>
		<input type="text" name="art_subject" id="art_subject" class="art_subject" placeholder="Тема сообщения" value=""/>
		<textarea name="art_comments" id="art_comments" placeholder="Сообщение" rows="10" cols="30" class="required art_comments"></textarea>
		<input type="checkbox" name="art_anticheck" id="art_anticheck" class="art_anticheck" style="display: none !important;" value="true" checked="checked"/>
		<input type="text" name="art_submitted" id="art_submitted" value="" style="display: none !important;"/>
		<input type="submit" id="submit-feedback" class="button" value="Отправить сообщение"/>
	</form>
	<?php

	return ob_get_clean();
}

Теперь создаем страницу и выводим на ней шорткод.

WordPress. Простая форма обратной связи на Ajax • 3 • WPRUSe

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

WordPress. Простая форма обратной связи на Ajax • 5 • WPRUSe
к содержанию

2. Внешний вид формы

Добавим красоты нашей форме.

/*
* Внешний вид формы
*/
#add_feedback {
    margin: 20px 0 0;
    position: relative;
}

#art_name, #art_email, #art_subject, #art_comments {
    padding: 10px 5px;
    display: inline-block;
    width: 49.548%;
    border-radius: 3px;
    border: 1px solid #ddd;
    font-size: 0.9em;
}

#art_subject {
    width: 100%;
    margin: 5px 0;
}

#art_comments {
    width: 100%;
}

#add_feedback .button {
    border: none;
    padding: 10px 20px;
    color: #fff;
    font-size: 1em;
    display: inherit;
    margin: 10px 0 0 0;
    border-radius: 3px;
    background-color: #2f94ce;
}

#add_feedback input[type="text"]:focus, #add_feedback input[type="password"]:focus, #add_feedback input[type="email"]:focus, #add_feedback textarea:focus {
    color: #444;
    box-shadow: 0 0 3px rgba(68, 68, 68, 0.2);
}

.error-text {
    background: #F59E9E;
    padding: 15px 0px;
    text-align: center;
    color: #fff;
}

.error-name, .error-email, .error-comments {
    display: inline-block;
    font-size: 11px;
    position: absolute;
    top: -30px;
    color: white;
    border: 1px solid red;
    padding: 5px 10px;
    line-height: 1.1;
    background: red;
    box-shadow: 0 0 3px 0px rgba(0, 0, 0, 0.3);
}

.error-name:after, .error-email:after, .error-comments:after {
    content: '';
    position: absolute;
    left: 20px;
    bottom: -10px;
    border: 5px solid transparent;
    border-top: 5px solid red;
}

.error-comments {
    top: 16%;
    left: 0;
}

.error-name {

    left: 0;
}

.error-email {
    right: 4%;
}

.message-success {
    background: rgba(0, 128, 0, 0.5);
    color: #fff;
    padding: 20px;
    text-align: center;
    margin: 20px auto;
    border-radius: 3px;
}

#add_feedback .error {
    border: 1px solid red;

}

#add_feedback .required:after {
    content: '*';
    position: absolute;
    left: 20px;
    bottom: -10px;
}

#art_name:focus::-moz-placeholder,
#art_name:focus:-moz-placeholder,
#art_name:focus:-ms-input-placeholder,
#art_email:focus::-webkit-input-placeholder,
#art_email:focus::-moz-placeholder,
#art_email:focus:-moz-placeholder,
#art_email:focus:-ms-input-placeholder,
#art_comments:focus::-webkit-input-placeholder,
#art_comments:focus::-moz-placeholder,
#art_comments:focus:-moz-placeholder,
#art_comments:focus:-ms-input-placeholder,
#art_subject:focus::-webkit-input-placeholder,
#art_subject:focus::-moz-placeholder,
#art_subject:focus:-moz-placeholder,
#art_subject:focus:-ms-input-placeholder {
    color: transparent
}

Вот так теперь выглядит форма

WordPress. Простая форма обратной связи на Ajax • 7 • WPRUSe
к содержанию

3. Работа формы

Теперь заставим форму работать так как надо.

Создание и подключение нужных файлов

Для работы формы потребуется создать файл js. Например, feedback.js. Файл необходимо создать в папке дочерней темы. Или в соответсвующей папке плагина.

Теперь через файл functions.php подключаем нужное

add_action( 'wp_enqueue_scripts', 'art_feedback_scripts' );
/**
 * Подключение файлов скрипта формы обратной связи
 *
 * @see https://wpruse.ru/?p=3224
 */
function art_feedback_scripts() {

	// Обрабтка полей формы
	wp_enqueue_script( 'jquery-form' );

	// Подключаем файл скрипта
	wp_enqueue_script(
		'feedback',
		get_stylesheet_directory_uri() . '/js/feedback.js',
		array( 'jquery' ),
		1.0,
		true
	);

	// Задаем данные обьекта ajax
	wp_localize_script(
		'feedback',
		'feedback_object',
		array(
			'url'   => admin_url( 'admin-ajax.php' ),
			'nonce' => wp_create_nonce( 'feedback-nonce' ),
		)
	);

}

После подключения в исходном коде должно быть видно подлючение и вывод скрипта

WordPress. Простая форма обратной связи на Ajax • 9 • WPRUSe
к содержанию

Отправка данных формы через ajax

В подключенный файл feedback.jsдобавляем отправку данных формы

jQuery(document).ready(function ($) {
    var add_form = $('#add_feedback');

    // Сброс значений полей
    $('#add_feedback input, #add_feedback textarea').on('blur', function () {
        $('#add_feedback input, #add_feedback textarea').removeClass('error');
        $('.error-name,.error-email,.error-comments,.message-success').remove();
        $('#submit-feedback').val('Отправить сообщение');
    });

    // Отправка значений полей
    var options = {
        url: feedback_object.url,
        data: {
            action: 'feedback_action',
            nonce: feedback_object.nonce
        },
        type: 'POST',
        dataType: 'json',
        beforeSubmit: function (xhr) {
            // При отправке формы меняем надпись на кнопке
            $('#submit-feedback').val('Отправляем...');
        },
        success: function (request, xhr, status, error) {
            
            if (request.success === true) {
                // Если все поля заполнены, отправляем данные и меняем надпись на кнопке
                add_form.after('<div class="message-success">' + request.data + '</div>').slideDown();
                $('#submit-feedback').val('Отправить сообщение');
            } else {
                // Если поля не заполнены, выводим сообщения и меняем надпись на кнопке
                $.each(request.data, function (key, val) {
                    $('.art_' + key).addClass('error');
                    $('.art_' + key).before('<span class="error-' + key + '">' + val + '</span>');
                });
                $('#submit-feedback').val('Что-то пошло не так...');

            }
            // При успешной отправке сбрасываем значения полей
            $('#add_feedback')[0].reset();
        },
        error: function (request, status, error) {
            $('#submit-feedback').val('Что-то пошло не так...');
        }
    };
    // Отправка формы
    add_form.ajaxForm(options);
});

Если все верно подключено, при отправке данных скрипт будет срабатывать и выдавать ошибку

WordPress. Простая форма обратной связи на Ajax • 11 • WPRUSe
к содержанию

Обработка Ajax

Теперь требуется написать обработчик скрипта.

Напоминаю, обработка ajax «подвешивается» на динамические хуки wp_ajax_ и wp_ajax_nopriv_и требуется проверка nonce

add_action( 'wp_ajax_feedback_action', 'ajax_action_callback' );
add_action( 'wp_ajax_nopriv_feedback_action', 'ajax_action_callback' );
/**
 * Обработка скрипта
 *
 * @see https://wpruse.ru/?p=3224
 */
function ajax_action_callback() {

	// Массив ошибок
	$err_message = array();

	// Проверяем nonce. Если проверкане прошла, то блокируем отправку
	if ( ! wp_verify_nonce( $_POST['nonce'], 'feedback-nonce' ) ) {
		wp_die( 'Данные отправлены с левого адреса' );
	}

	// Проверяем на спам. Если скрытое поле заполнено или снят чек, то блокируем отправку
	if ( false === $_POST['art_anticheck'] || ! empty( $_POST['art_submitted'] ) ) {
		wp_die( 'Пошел нахрен, мальчик!(c)' );
	}

	// Проверяем полей имени, если пустое, то пишем сообщение в массив ошибок
	if ( empty( $_POST['art_name'] ) || ! isset( $_POST['art_name'] ) ) {
		$err_message['name'] = 'Пожалуйста, введите ваше имя.';
	} else {
		$art_name = sanitize_text_field( $_POST['art_name'] );
	}

	// Проверяем полей емайла, если пустое, то пишем сообщение в массив ошибок
	if ( empty( $_POST['art_email'] ) || ! isset( $_POST['art_email'] ) ) {
		$err_message['email'] = 'Пожалуйста, введите адрес вашей электронной почты.';
	} elseif ( ! preg_match( '/^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$/i', $_POST['art_email'] ) ) {
		$err_message['email'] = 'Адрес электронной почты некорректный.';
	} else {
		$art_email = sanitize_email( $_POST['art_email'] );

	}
	// Проверяем полей темы письма, если пустое, то пишем сообщение по умолчанию
	if ( empty( $_POST['art_subject'] ) || ! isset( $_POST['art_subject'] ) ) {
		$art_subject = 'Сообщение с сайта';
	} else {
		$art_subject = sanitize_text_field( $_POST['art_subject'] );
	}

	// Проверяем полей сообщения, если пустое, то пишем сообщение в массив ошибок
	if ( empty( $_POST['art_comments'] ) || ! isset( $_POST['art_comments'] ) ) {
		$err_message['comments'] = 'Пожалуйста, введите ваше сообщение.';
	} else {
		$art_comments = sanitize_textarea_field( $_POST['art_comments'] );
	}

	// Проверяем массив ошибок, если не пустой, то передаем сообщение. Иначе отправляем письмо
	if ( $err_message ) {

		wp_send_json_error( $err_message );

	} else {

		// Указываем адресата
		$email_to = '';

		// Если адресат не указан, то берем данные из настроек сайта
		if ( ! $email_to ) {
			$email_to = get_option( 'admin_email' );
		}

		$body    = "Имя: $art_name \nEmail: $art_email \n\nСообщение: $art_comments";
		$headers = 'From: ' . $art_name . ' <' . $email_to . '>' . "\r\n" . 'Reply-To: ' . $email_to;

		// Отправляем письмо
		wp_mail( $email_to, $art_subject, $body, $headers );

		// Отправляем сообщение об успешной отправке
		$message_success = 'Собщение отправлено. В ближайшее время я свяжусь с вами.';
		wp_send_json_success( $message_success );
	}

	// На всякий случай убиваем еще раз процесс ajax
	wp_die();

}
к содержанию

Заключение

Вот и все. Если все сделано правильно, то при отправке пустой формы будут такие сообщения

WordPress. Простая форма обратной связи на Ajax • 13 • WPRUSe

Если отправка прошла успешно, то появится соответствующее сообщение

WordPress. Простая форма обратной связи на Ajax • 15 • WPRUSe

На этом все. Если есть вопросы пишите в комментариях. Удачи!