Array ( [0] => 13701 [1] => 12681 [2] => 12146 [3] => 11896 [4] => 11727 [5] => 11198 [6] => 9687 [7] => 6123 [8] => 8835 [9] => 8798 [10] => 8588 [11] => 8448 [12] => 7309 [13] => 6985 [14] => 6700 [15] => 3701 [16] => 3573 [17] => 2023 [18] => 1791 ) в запросе 19 результатов
Категория: 35
Ajax форма без плагина

Ajax форма без плагина

Создаем формы без использования плагинов (например Contact Form 7). Делаем форму Ajax. Создание простой формы Добавляем скрипт обработчик (с валидацией полей) Прописываем функцию формы Данное решение взято с сайта inprocess.by Читать далее »

Ajax форма с вложением файла

Ajax форма с вложением файла

Долго искал и нашел (здесь www.thenerdyblog.com) отличное решение — форма с вложением файла на ajax. Форма Скрипт Файл-обработчик Если нужно чтобы вложение было обязательным, то в условии else прописываем ошибку: Читать далее »

/
API Яндекс.Карт

API Яндекс.Карт

Если нам нужно кастомизировать карту Яндекс, то будет не достаточно подключить ее через iframe, т.к. в нем не будет никаких настроек. Необходимо подключить API Яндекс.Карт Подключаем API Яндекс.Карт На данный Читать далее »

Contact Form 7

Contact Form 7

Contact Form 7 — очень нужный плагин для модулирования различных форм обратной связи. Имеет множество дополнений. Плагин Contact Form 7 Код вставки формы Отключить обертку в <p> и добавление <br> Читать далее »

/
WP_Query Object
(
    [query] => Array
        (
            [post__in] => Array
                (
                    [0] => 13701
                    [1] => 12681
                    [2] => 12146
                    [3] => 11896
                    [4] => 11727
                    [5] => 11198
                    [6] => 9687
                    [7] => 6123
                    [8] => 8835
                    [9] => 8798
                    [10] => 8588
                    [11] => 8448
                    [12] => 7309
                    [13] => 6985
                    [14] => 6700
                    [15] => 3701
                    [16] => 3573
                    [17] => 2023
                    [18] => 1791
                )

            [orderby] => title
            [order] => ASC
            [posts_per_page] => 4
        )

    [query_vars] => Array
        (
            [post__in] => Array
                (
                    [0] => 13701
                    [1] => 12681
                    [2] => 12146
                    [3] => 11896
                    [4] => 11727
                    [5] => 11198
                    [6] => 9687
                    [7] => 6123
                    [8] => 8835
                    [9] => 8798
                    [10] => 8588
                    [11] => 8448
                    [12] => 7309
                    [13] => 6985
                    [14] => 6700
                    [15] => 3701
                    [16] => 3573
                    [17] => 2023
                    [18] => 1791
                )

            [orderby] => title
            [order] => ASC
            [posts_per_page] => 4
            [error] => 
            [m] => 
            [p] => 0
            [post_parent] => 
            [subpost] => 
            [subpost_id] => 
            [attachment] => 
            [attachment_id] => 0
            [name] => 
            [pagename] => 
            [page_id] => 0
            [second] => 
            [minute] => 
            [hour] => 
            [day] => 0
            [monthnum] => 0
            [year] => 0
            [w] => 0
            [category_name] => 
            [tag] => 
            [cat] => 
            [tag_id] => 
            [author] => 
            [author_name] => 
            [feed] => 
            [tb] => 
            [paged] => 0
            [meta_key] => 
            [meta_value] => 
            [preview] => 
            [s] => 
            [sentence] => 
            [title] => 
            [fields] => 
            [menu_order] => 
            [embed] => 
            [category__in] => Array
                (
                )

            [category__not_in] => Array
                (
                )

            [category__and] => Array
                (
                )

            [post__not_in] => Array
                (
                )

            [post_name__in] => Array
                (
                )

            [tag__in] => Array
                (
                )

            [tag__not_in] => Array
                (
                )

            [tag__and] => Array
                (
                )

            [tag_slug__in] => Array
                (
                )

            [tag_slug__and] => Array
                (
                )

            [post_parent__in] => Array
                (
                )

            [post_parent__not_in] => Array
                (
                )

            [author__in] => Array
                (
                )

            [author__not_in] => Array
                (
                )

            [search_columns] => Array
                (
                )

            [ignore_sticky_posts] => 
            [suppress_filters] => 
            [cache_results] => 1
            [update_post_term_cache] => 1
            [update_menu_item_cache] => 
            [lazy_load_term_meta] => 1
            [update_post_meta_cache] => 1
            [post_type] => 
            [nopaging] => 
            [comments_per_page] => 50
            [no_found_rows] => 
        )

    [tax_query] => WP_Tax_Query Object
        (
            [queries] => Array
                (
                )

            [relation] => AND
            [table_aliases:protected] => Array
                (
                )

            [queried_terms] => Array
                (
                )

            [primary_table] => wp_posts
            [primary_id_column] => ID
        )

    [meta_query] => WP_Meta_Query Object
        (
            [queries] => Array
                (
                )

            [relation] => 
            [meta_table] => 
            [meta_id_column] => 
            [primary_table] => 
            [primary_id_column] => 
            [table_aliases:protected] => Array
                (
                )

            [clauses:protected] => Array
                (
                )

            [has_or_relation:protected] => 
        )

    [date_query] => 
    [request] => 
					SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID
					FROM wp_posts 
					WHERE 1=1  AND wp_posts.ID IN (13701,12681,12146,11896,11727,11198,9687,6123,8835,8798,8588,8448,7309,6985,6700,3701,3573,2023,1791) AND ((wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish')))
					
					ORDER BY wp_posts.post_title ASC
					LIMIT 0, 4
				
    [posts] => Array
        (
            [0] => WP_Post Object
                (
                    [ID] => 11198
                    [post_author] => 1
                    [post_date] => 2019-09-20 22:47:42
                    [post_date_gmt] => 2019-09-20 19:47:42
                    [post_content] => 

Создаем формы без использования плагинов (например Contact Form 7). Делаем форму Ajax.

Создание простой формы

<form class="form-container recall-form-validate">
	<h2>Заказать звонок</h2>
	<input class="form-field form-name" type="text"  name="name" placeholder="Ваше имя"><br />
	<input class="form-field form-tel" type="text"  name="tel" placeholder="Ваш телефон"><br />
	<div id="submit-ajax" class="submit-container">
		<input class="submit-button" type="submit" value="Отправить"/>
	</div>
</form>

Добавляем скрипт обработчик (с валидацией полей)

$(".submit-button").on("click", function (event) {
	event.preventDefault();
	var name = $(".form-name").val();
	var tel = $(".form-tel").val();

	if (name  === '') {
        	alert('Заполните поле с именем');
        	return false;
	}
	
	if (tel  === '') {
        	alert('Заполните поле с номером телефона');
        	return false;
	}
	
	if (tel.match(/[^0-9'".]/)) {
        	alert('Телефон заполнен не верно');
        	return false;
	}

	$.ajax({
		url: "/wp-admin/admin-ajax.php",
		method: 'post',
		data: {
			action: 'ajax_order',
			name: name,
			tel: tel
		},
		success: function (response) {
			$('#submit-ajax').html(response);
		}
	});
});

Прописываем функцию формы

function ajax_form(){
    $name = $_REQUEST['name'];
    $tel = $_REQUEST['tel'];
    $response = '';
    $thm  = 'Заказ звонка';
    $thm  = "=?utf-8?b?". base64_encode($thm) ."?=";
    $msg = "Имя: ".$name."<br/>
        Телефон: ".$tel ."<br/>";
    $mail_to = 'mail@mail.ru';
    $headers = "Content-Type: text/html; charset=utf-8\n";
    $headers .= 'From: SITE <no-replay@site.ru>' . "\r\n";

    // Отправляем почтовое сообщение
    if(mail($mail_to, $thm, $msg, $headers)) {
        $response = 'Сообщение отправлено';
	} else {
		$response = 'Ошибка при отправке';
	}
	
    // Сообщение о результате отправки почты
    if ( defined( 'DOING_AJAX' ) && DOING_AJAX ){
        echo $response;
        wp_die();
    }
}

add_action('wp_ajax_nopriv_ajax_order', 'ajax_form' );
add_action('wp_ajax_ajax_order', 'ajax_form' );

Данное решение взято с сайта inprocess.by

Отправка формы с двумя разными шаблонами

Чтобы отправить форму с двумя разными шаблонами, например администратору и покупателю, нужно сделать следующее:

1. Добавить в скрипт отправки еще одну функцию ajax с другим action

$.ajax({
	url: "/wp-admin/admin-ajax.php",
	method: 'post',
	data: {
		action: 'ajax_order_client',
		name: name,
		tel: tel
	}
});

2. Создать еще одну функцию отправки письма и привязать её к новому action (ajax_order_client)

add_action('wp_ajax_nopriv_ajax_order_client', 'ajax_form_client' );
add_action('wp_ajax_ajax_order_client', 'ajax_form_client' );

Валидация и подсветка полей

Проверки на заполненность различных полей:

// Отправка заявки
$(".submit-button").on("click", function (event) {
	event.preventDefault();
	var name = $(".form-name").val();
	var tel = $(".form-tel").val();
	var email = $(".form-email").val();
	
	if (name  === '') {
        alert('Заполните поле с именем');
        return false;
	}
	
	if (tel  === '') {
		alert('Заполните поле с номером телефона');
		return false;
	} else if (tel.match(/[^0-9'".]/)) {
        alert('Телефон заполнен не корректно');
        return false;		
	} else if (tel.length < 8) {
		alert('Слишком короткий номер');
		return false;
	} else if (!((tel.lastIndexOf("+7", 0) === 0) || (tel.lastIndexOf("8", 0) === 0))) {
		alert('Введите корректный номер в формате +79998887766 или 89998887766');
		return false;
	}
	
	if(email  === '') { 
		alert('Укажите свой E-Mail');
		return false;
	} else if ( !validateEmail(email) ) {
		alert('Введите корректный E-Mail');
		return false;		
	}

	if (!$("input[name='messenger']:checked").val()) {
		alert("Выберите удобрый для вас мессенджер"); 
		return false;
	}
	
	if (!$('input:checkbox[name="acceptance"]').is(':checked')) {
		alert('Вы должны ознакомиться с политикой конфиденциальности');
		return false;
	}
	
	

	$.ajax({
		url: "/wp-admin/admin-ajax.php",
		method: 'post',
		data: {
			action: 'ajax_order',
			name: name,
			tel: tel,
			email: email,
		},
		success: function (response) {
			$('#submit-ajax').html(response);
		}
	});
});


// Проверка E-mail
function validateEmail($email) {
	var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
	return emailReg.test( $email );
}

Подсветка полей

// Подсвечивание полей обязательных для заполнения
$(".submit-button").on("click", function (event) {
	var name = $(".form-name").val();
	var tel = $(".form-tel").val();
	var email = $(".form-email").val();
	
	$(".form-field").removeClass('validate novalidate');
	
	if (name  === '') {
        $(".form-name").addClass('novalidate');
	} else {
		$(".form-name").addClass('validate');
	}
	
	if (tel  === '') {
		$(".form-tel").addClass('novalidate');
	} else if (tel.match(/[^0-9'".]/)) {
        $(".form-tel").addClass('novalidate');		
	} else if (tel.length < 8) {
		$(".form-tel").addClass('novalidate');
	} else if (!((tel.lastIndexOf("+7", 0) === 0) || (tel.lastIndexOf("8", 0) === 0))) {
		$(".form-tel").addClass('novalidate');
	} else {
		$(".form-tel").addClass('validate');
	}
	
	if(email  === '') { 
		$(".form-email").addClass('novalidate');
	} else if ( !validateEmail(email) ) {
		$(".form-email").addClass('novalidate');		
	} else {
		$(".form-email").addClass('validate');
	}
});
[quest]Придумать единую функцию подсветки[/quest]

Ошибка при отправке

В одном из проектов, на выделенном сервере, столкнулся с тем что функция mail (и wp_mail) не отправляли письма. Решил это установкой плагина Easy WP SMTP (300 000), в котором прописал настройки SMTP созданного ящика почты домена.

Был случай, также на выделенном сервере, что не работала отправка функцией mail, но при этом wp_mail отправляется нормально.

Защита полей перед отправкой

Поля перед отправкой необходимо защищать:

$name = sanitize_text_field( $_REQUEST['name'] );
$tel = sanitize_text_field( $_REQUEST['tel'] );
$object = sanitize_text_field( $_REQUEST['object'] );

$quest = sanitize_textarea_field( $_REQUEST['quest'] );

$email = sanitize_email( $_REQUEST['email'] );

Дополнительное письмо отправителю

В некоторых специфических формах может потребоваться отправка дополнительного письма адресату с подтверждением получения заявки.

Оптимально это сделать посредством создание отдельной страны с шаблоном ответа и добавлять заголовок и содержимое страницы в виде заголовка и содержимого письма:

// Отправляем почтовое сообщение
if(wp_mail($mail_to, $thm, $msg, $headers)) {
	$response = 'Сообщение отправлено.<br>Мы свяжемся с вами в ближайшее время.';
	
	//Письмо отправителю
	$page = get_post(1511);
	wp_mail($email, $page->post_title, $page->post_content, $headers);

	wp_reset_postdata();
} else {
	$response = 'Ошибка при отправке';
}
[post_title] => Ajax форма без плагина [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => ajax-forma-bez-plagina [to_ping] => [pinged] => [post_modified] => 2022-09-25 12:08:40 [post_modified_gmt] => 2022-09-25 09:08:40 [post_content_filtered] => [post_parent] => 0 [guid] => https://opttour.ru/?p=11198 [menu_order] => 0 [post_type] => post [post_mime_type] => [comment_count] => 0 [filter] => raw ) [1] => WP_Post Object ( [ID] => 11896 [post_author] => 1 [post_date] => 2020-09-01 00:53:18 [post_date_gmt] => 2020-08-31 21:53:18 [post_content] =>

Долго искал и нашел (здесь www.thenerdyblog.com) отличное решение — форма с вложением файла на ajax.

Форма

<form id="contact-form" method="post" enctype="multipart/form-data">
	<div class="form-group">
		<label for="fname">First Name:</label>
		<input type="text" class="form-control" id="fname">
	</div>
	<div class="form-group">
		<label for="email">Email Address:</label>
		<input type="email" class="form-control" id="email_address">
	</div>
	<div class="form-group">
		<label for="attachment">File attachment:</label>
		<input type="file" name="file_attach" class="input-field"/>
	</div>

	<button type="button" id="submit" class="btn btn-default btn-dark">Submit</button>
</form>	

<div id="response"></div>
[warn]Важно чтобы кнопка отправки формы была именно button, а не полем input (type="submit"). Иначе работать не будет.[/warn]

Скрипт

$(document).ready(function() {

	$("#submit").click(function(e) {

		var proceed = true;

		if(proceed) { //everything looks good! proceed...

			//data to be sent to server        
			var m_data = new FormData();   
			m_data.append( 'first_name', $('#fname').val());
			m_data.append( 'email_address', $('#email_address').val());
			m_data.append( 'file_attach', $('input[name=file_attach]')[0].files[0]);

			//instead of $.post() we are using $.ajax()
			//that's because $.ajax() has more options and flexibly.

			$.ajax({
				url: '/wp-content/themes/meisterwerk-2/process.php',
				data: m_data,
				processData: false,
				contentType: false,
				type: 'POST',
				dataType:'json',
				success: function(response){
					//load json data from server and output message    
					if(response.type == 'error') { //load json data from server and output message    
						output = '<div class="error">'+response.text+'</div>';
					} else {
						output = '<div class="success">'+response.text+'</div>';
					}
					$("#response").hide().html(output).slideDown();
				}
			});

		}

	});
});

Файл-обработчик

<?php    

//Recepient Email Address
$to_email       = "mail@mail.ru";

//check if its an ajax request, exit if not
if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
	$output = json_encode(array( //create JSON data
		'type'=>'error',
		'text' => 'Sorry Request must be Ajax POST'
	));
	die($output); //exit script outputting json data
}

//Sanitize input data using PHP filter_var().
$first_name      = filter_var($_POST["first_name"], FILTER_SANITIZE_STRING);
$email_address   = filter_var($_POST["email_address"], FILTER_SANITIZE_EMAIL);
$subject         = "Your Email Subject Goes Here...";

 
//Textbox Validation 
if(strlen($first_name)<4){ // If length is less than 4 it will output JSON error.
	$output = json_encode(array('type'=>'error', 'text' => 'Name is too short or empty!'));
	die($output);
}



$message = '<html><body>';
$message .= "<p><strong>First Name:</strong> " . strip_tags($_POST['first_name']) . "</p>";
$message .= "<p><strong>Email Address :</strong> " . strip_tags($_POST['email_address']) . "</p>";
$message .= "</body></html>";


$file_attached = false;
if(isset($_FILES['file_attach'])) { //check uploaded file

	//get file details we need
	$file_tmp_name    = $_FILES['file_attach']['tmp_name'];
	$file_name        = $_FILES['file_attach']['name'];
	$file_size        = $_FILES['file_attach']['size'];
	$file_type        = $_FILES['file_attach']['type'];
	$file_error       = $_FILES['file_attach']['error'];



	//exit script and output error if we encounter any
	if($file_error>0) {
		$mymsg = array(
		1=>"The uploaded file exceeds the upload_max_filesize directive in php.ini",
		2=>"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
		3=>"The uploaded file was only partially uploaded",
		4=>"No file was uploaded",
		6=>"Missing a temporary folder" );
		 
		$output = json_encode(array('type'=>'error', 'text' => $mymsg[$file_error]));
		die($output);
	}
	 
	//read from the uploaded file & base64_encode content for the mail
	$handle = fopen($file_tmp_name, "r");
	$content = fread($handle, $file_size);
	fclose($handle);
	$encoded_content = chunk_split(base64_encode($content));
	
	//now we know we have the file for attachment, set $file_attached to true
	$file_attached = true;

}

if($file_attached) { //continue if we have the file
   
	// a random hash will be necessary to send mixed content
	$separator = md5(time());
 
	// carriage return type (RFC)
	$eol = "\r\n";
 
	// main header (multipart mandatory)
	$headers = "From:Fromname <info@fromemail.com>" . $eol;
	$headers .= "MIME-Version: 1.0" . $eol;
	$headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol;
	$headers .= "Content-Transfer-Encoding: 7bit" . $eol;
	$headers .= "This is a MIME encoded message." . $eol;
	
	// message
	$body .= "--" . $separator . $eol;
	$body .= "Content-type:text/html; charset=utf-8\n";
	$body .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
	$body .= $message . $eol;
 
	// attachment
	$body .= "--" . $separator . $eol;
	$body  .= "Content-Type:".$file_type." ";
	$body .= "Content-Type: application/octet-stream; name=\"" . $file_name . "\"" . $eol;
	$body .= "Content-Transfer-Encoding: base64" . $eol;
	$body .= "Content-Disposition: attachment; filename=\"".$file_name."\"".$eol.$eol; // !Обязательно два $eol иначе приходит изображение с 0 Kb
	$body .= $encoded_content . $eol;
	$body .= "--" . $separator . "--";
	
} else {
	
	$eol = "\r\n";
	
	$headers = "From: Fromname <info@fromemail.com>" . $eol;
	$headers .= "Reply-To: ". strip_tags($email_address) . "\r\n";
	$headers .= "MIME-Version: 1.0\r\n";
	$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
	$body .= $message . $eol;

}

$send_mail = false; // в одном проекте без этого была ошибка
$send_mail = mail($to_email, $subject, $body, $headers);

if(!$send_mail) {
	//If mail couldn't be sent output error. Check your PHP email configuration (if it ever happens)
	$output = json_encode(array('type'=>'error', 'text' => 'Could not send mail! Please check your PHP mail configuration.'));
	die($output);
}else{
	$output = json_encode(array('type'=>'message', 'text' => 'Hi '.$first_name .' Thank you for your order, will get back to you shortly'));
	die($output);
}

Если нужно чтобы вложение было обязательным, то в условии else прописываем ошибку:

} else {
	
	$output = json_encode(array('type'=>'error', 'text' => 'Вложите файл с рецептом'));
	die($output);

}

Проверки

Проверки полей email и телефон

if(strlen($email_address)<1){
	$output = json_encode(array('type'=>'error', 'text' => 'Ведите свой E-mail'));
	die($output);
} elseif (!filter_var($email_address, FILTER_VALIDATE_EMAIL)) {
	$output = json_encode(array('type'=>'error', 'text' => 'E-mail указан не корректно'));
	die($output);
}

if(strlen($phone_number)<1){
	$output = json_encode(array('type'=>'error', 'text' => 'Ведите свой телефон'));
	die($output);
} elseif(!preg_match('/^[0-9]{11}+$/', $phone_number)) {
	$output = json_encode(array('type'=>'error', 'text' => 'Телефон указан не корректно (нужно указать только 11 цифр, без + и -)'));
	die($output);
}

Проверка поля «принятие» (например согласие с обработкой персональных данных).

Необходимо в скрипте добавить перехват и передачу значения (у поля должен быть id acceptance):

if ( $('#acceptance').is(':checked') ) {
	m_data.append( 'acceptance', '1');
}

Проверка в файле-обработчике:

if( !isset($acceptance) ){
	$output = json_encode(array('type'=>'error', 'text' => 'Вы должны согласится на обработку персональных данных'));
	die($output);
}

Стилизовать кнопку вложения

Верстка

<div>
	<input class="form-field form-file inputfile" type="file" name="file_attach" id="file" data-multiple-caption="{count} files selected" multiple>
	<label id="form-file-btn" for="file"><img src="/wp-content/themes/bastion/img/clip.svg"><span>Прикрепите резюме</span></label>
</div>

Стили

#form-file-btn {
    background: #eee;
    width: 100%;
    display: flex;
    text-align: center;
    border-radius: 10px;
    padding: 15px 23px;
    font-weight: 300;
    cursor: pointer;
    justify-content: center;
}

#form-file-btn img {margin-right: 7px;}

Код svg-изображения скрепки

<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.7335 1.70988L17.2717 1.25426C16.4521 0.445401 15.3606 0 14.1984 0C13.0292 0 11.9294 0.449888 11.1028 1.2655L0.915275 11.2092C-0.301829 12.4101 -0.305571 14.3606 0.906971 15.5572L1.22625 15.8723C1.83223 16.4702 2.68094 16.8132 3.55461 16.8132C4.39128 16.8132 5.1642 16.5051 5.73106 15.9459L14.8773 6.92073C15.5896 6.21779 15.5915 5.0762 14.8817 4.37587L14.7112 4.20755C14.3665 3.86738 13.9072 3.68008 13.4182 3.68014C12.9267 3.68014 12.4645 3.86914 12.1169 4.2122L3.66297 12.5542C3.52707 12.6883 3.52883 12.904 3.66689 13.036C3.80501 13.168 4.02704 13.1662 4.16305 13.0322L12.617 4.69026C12.8317 4.47838 13.1163 4.36162 13.4182 4.36162C13.7178 4.36156 13.9993 4.47662 14.2111 4.68549L14.3815 4.85381C14.8242 5.29058 14.8223 6.00341 14.3772 6.44268L5.23098 15.4678C4.7971 15.8959 4.20176 16.1317 3.55467 16.1317C2.86776 16.1317 2.20138 15.8629 1.72639 15.3942L1.40711 15.0792C0.461682 14.1462 0.465425 12.6246 1.41401 11.6886L11.6016 1.74486C12.2965 1.05907 13.2187 0.681419 14.1983 0.681419C15.171 0.681419 16.0849 1.05458 16.7716 1.73226L17.2334 2.18794C18.6598 3.59541 18.6542 5.89113 17.221 7.30531L6.97033 17.4202C6.83443 17.5544 6.83619 17.7701 6.97425 17.9021C7.0426 17.9674 7.13149 18 7.22037 18C7.31106 18 7.40176 17.966 7.47041 17.8983L17.7211 7.78337C19.4215 6.10552 19.427 3.38103 17.7335 1.70988Z" fill="black"/>
</svg>

Скрипт благодаря которому надпись Прикрепите резюме подменяется на название файла при его загрузке.

( function ( document, window, index ) {
	var inputs = document.querySelectorAll( '.inputfile' );
	Array.prototype.forEach.call( inputs, function( input )
	{
		var label	 = input.nextElementSibling,
			labelVal = label.innerHTML;

		input.addEventListener( 'change', function( e )
		{
			var fileName = '';
			if( this.files && this.files.length > 1 )
				fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
			else
				fileName = e.target.value.split( '\\' ).pop();

			if( fileName )
				label.querySelector( 'span' ).innerHTML = fileName;
			else
				label.innerHTML = labelVal;
		});

		// Firefox bug fix
		input.addEventListener( 'focus', function(){ input.classList.add( 'has-focus' ); });
		input.addEventListener( 'blur', function(){ input.classList.remove( 'has-focus' ); });
	});
}( document, window, 0 ));
[warn]Важно чтобы идентификатор (например inputfile) был одним словом без дефисов. Видимо какая то особенность js. [/warn]

PHP-проверка мобильного телефона

//Tel Validation
if(strlen($tel)<11){
	$output = json_encode(array('type'=>'error', 'text' => 'Введите свой телефон, в формате +79098087766, либо 89098087766'));
	die($output);
}

if( preg_match("/[^0-9+\(\)-]/", $tel) ) {
    $output = json_encode(array('type'=>'error', 'text' => 'Введите корректный телефон'));
	die($output);
}
[post_title] => Ajax форма с вложением файла [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => ajax-forma-s-vlozheniem-fajla [to_ping] => [pinged] => [post_modified] => 2022-09-23 00:50:18 [post_modified_gmt] => 2022-09-22 21:50:18 [post_content_filtered] => [post_parent] => 0 [guid] => https://opttour.ru/?p=11896 [menu_order] => 0 [post_type] => post [post_mime_type] => [comment_count] => 0 [filter] => raw ) [2] => WP_Post Object ( [ID] => 8798 [post_author] => 1 [post_date] => 2017-12-10 21:30:55 [post_date_gmt] => 2017-12-10 18:30:55 [post_content] =>

Если нам нужно кастомизировать карту Яндекс, то будет не достаточно подключить ее через iframe, т.к. в нем не будет никаких настроек. Необходимо подключить API Яндекс.Карт

Подключаем API Яндекс.Карт

На данный момент существуют разные версии Api. Будем подключать версию 2.1

wp_enqueue_script( 'yandex-maps', 'https://api-maps.yandex.ru/2.1/?lang=ru_RU' , array( ), '2.0', true );

Создаем контейнер в котором будет создаваться карта

<div id="YMapsID" style="width: 100%; height: 400px;"></div>

Конструируем карту

Привожу типовой вариант карты Яндекс

ymaps.ready(function () {
    var myMap = new ymaps.Map('YMapsID', {
        center: [43.567075, 39.736186],
        zoom: 14,
		controls: ['smallMapDefaultSet']
    });
	
    myMap.geoObjects
        .add(new ymaps.Placemark([43.567075, 39.736186], {
            balloonContent: '', //Всплывающий при наведении текст
            iconCaption: 'Черноморская, 13 Г'
        }, {
            preset: 'islands#redCircleDotIconWithCaption',
            iconCaptionMaxWidth: '200'
   }));
	
	myMap.behaviors.disable('scrollZoom'); //Отключам zoom колесом при наведении
});

Координаты объекта проще всего выяснять, открыв Яндекс карты и введя необходимый адрес. Чуть ниже введенного адреса ебудут сами координаты и кнопка Скопировать.

Больше настроек и параметров можно узнать на специальном сайте API Яндекс.Карт

Собственная иконка на карте

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

// Создаём макет содержимого.
MyIconContentLayout = ymaps.templateLayoutFactory.createClass(
     '<div style="color: #FFFFFF; font-weight: 600;">$[properties.iconContent]</div>'
),

myPlacemark = new ymaps.Placemark(myMap.getCenter(), {
     hintContent: 'Таганрогская, 140 Б, офис 16',
     balloonContent: 'НАЗВАНИЕ<br>Таганрогская, 140 Б, офис 1<br>+7 (863) 288-88-88 доб. 118<br>+7 (888) 888-88-89'
}, {

     // Необходимо указать данный тип макета.
     iconLayout: 'default#image',
     iconImageHref: '/wp-content/uploads/2018/07/bazabirs-map.png',
     // Размеры метки.
     iconImageSize: [52, 83],
     // Смещение левого верхнего угла иконки относительно её точки привязки.
     iconImageOffset: [-26, -83]
})
		
myMap.geoObjects
.add(myPlacemark)

Сделать карту черно белой

[class*="ymaps-"][class*="-ground-pane"] {filter: grayscale(100);}

При этом нанесенные иконки не будут серыми.

[post_title] => API Яндекс.Карт [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => api-yandeks-kart [to_ping] => [pinged] => [post_modified] => 2023-12-27 13:21:02 [post_modified_gmt] => 2023-12-27 10:21:02 [post_content_filtered] => [post_parent] => 0 [guid] => https://opttour.ru/?p=8798 [menu_order] => 0 [post_type] => post [post_mime_type] => [comment_count] => 0 [filter] => raw ) [3] => WP_Post Object ( [ID] => 2023 [post_author] => 1 [post_date] => 2015-06-24 08:40:00 [post_date_gmt] => 2015-06-24 05:40:00 [post_content] =>

Contact Form 7 — очень нужный плагин для модулирования различных форм обратной связи. Имеет множество дополнений.

Плагин Contact Form 7

Код вставки формы

<?php echo do_shortcode( '[contact-form-7 id="143" title="Контактная форма 1"]' ); ?>

Отключить обертку в <p> и добавление <br>

Чтобы это сделать нужно в файле wp-config.php прописать:

define('WPCF7_AUTOP', false );

CAPTCHA

Really Simple CAPTCHA — доп. плагин для добавления captcha
Для вставки необходимо в первое поле генерации формы добавить это:

[captchac captcha-167 class:inp_1][captchar captcha-167 class:inp_1 placeholder "Введите символы"]

Сохранение отправленных форм в админке

Flamingo — доп. плагин для сохранения всех отправленных форм в интерфейсе админки.

Если формы подвержены СПАМу, то данный плагин создаст в таблице wp_posts множество записей. Чистить их !все можно запросом в phpMyAdmin:

DELETE FROM `wp_posts` WHERE `post_type` = 'flamingo_inbound';

Цели Yandex

[warn]В новейших версиях плагина рекомендуется js-обработчики прописывать в функциях. Ниже описано подробнее.[/warn]

Добавление целей для Yandex Metrika для Form7 — в Дополнительных настройках формы прописываем строку

on_sent_ok: "yaCounterXXXXXX.reachGoal('ORDER');"
[info]yaCounterXXXXXX - номер счетчика Yandex (!не ID цели), для нескольких целей будет единым. ORDER - название цели (без пробелов и без цифр, только латинские буквы) в зависимости от назначения формы[/info]

Как протестировать отправку целей Яндекс Метрики описано здесь.

«Оформленная» форма

<p class="close"><i class="fa fa-times"></i></p>
[text* your-name class:textbox placeholder "Ваше имя"]
[date* date-615 class:textbox placeholder "Дата рождения"]
[tel* tel-968 class:textbox placeholder "Телефон"]
[email* your-email class:textbox placeholder "E-mail"]
[textarea* your-message 40x8 placeholder "Сообщение"]
[captchac captcha-167 class:inp_1]
[captchar captcha-167 class:inp_1 placeholder "Введите символы"] 
<!--[submit class:button send_one "Отправить"]--> 
<button class="send-bt"><i class="fa fa-envelope"></i> Отправить</button> 

Стили формы CSS

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

#feedback .wpcf7-form {
  position: relative;
  float:left;   
  background-color: whitesmoke;
  box-sizing:border-box;
  width: 50%;
  margin: 0 25%;
  padding: 15px 5%;  
  text-align: center;
  font-size:16px;
  transition: width 0.5s ease;
  -webkit-transition: width 0.5s ease 0s; 
  border-radius: 10px;
  box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2); 
}

.wpcf7-form p {margin: 8px 0; float: left; width: 100%;}

.wpcf7-form p.close {width: 20px; height: 20px; top: -15px;}
  
.textbox {
  width:100%;
  border:rgba(0,0,0,.3) 1px solid;
  box-sizing:border-box;
  font-family: "PlayRegular"; 
  padding: 5px 10px;
}

.wpcf7-form-control-wrap {position: inherit !important; width: 100%;}

.wpcf7-captchar {
    width: 60%;
    border: rgba(0,0,0,.3) 1px solid;
    box-sizing: border-box;
    font-family: "PlayRegular";
    padding: 5px 10px;
    float: right;
}

.wpcf7-captchac {float: left; width: 30% !important;}

.wpcf7-form textarea {
    width: 100%;
    border: 1px solid rgba(0,0,0,.3);
    box-sizing: border-box;
    padding: 5px 10px;
}

.message:focus, .textbox:focus, .wpcf7-textarea:focus, .wpcf7-captchar:focus {
  outline:none;
   border:rgba(24,149,215,1) 1px solid;
   color:rgba(24,149,215,1);
}

.message{
    background: rgba(255, 255, 255, 0.4); 
    width:100%;
    height: 120px;
    border:rgba(0,0,0,.3) 1px solid;
    box-sizing:border-box;
    -moz-border-radius: 3px;
    font-family: "PlayRegular";
    display:block;
    padding:10px;
    margin-bottom:30px;
    overflow:hidden;
}

.wpcf7-form .button {
    height: 40px;
    width: 70%;
    border: rgba(0,0,0,.3) 0px solid;
    box-sizing: border-box;
    padding: 10px;
    background: rgb(28, 107, 195);
    color: #FFF;
    font-family: "PlayRegular";
    transition: background .4s ease;
    -webkit-transition: background 0.5s ease 0s; 
    cursor: pointer;
    margin-top: 20px;
}

.wpcf7-form .button:hover {background: rgb(16, 68, 125);}
   
.wpcf7-response-output.wpcf7-display-none.wpcf7-validation-errors {float: left;}

.wpcf7-not-valid-tip {
    background-color: #f00;
    color: #fff !important;
    position: relative;
    font-size: 12px !important;
    clear: both;
    display: block;
}

.wpcf7-not-valid-tip:before {
    content: '';
    position: absolute;
    top: -5px;
    left: 45%;
    border: 5px solid transparent;
    border-bottom-color: red;
    border-top: 0;
}

.wpcf7-response-output {
    margin: 0px 5px 10px 5px !important;
    padding: 5px 10px !important;
    font-size: 14px;
}

img.ajax-loader {display: none;}


/* своя кнопка отправки */

.send-bt {
    border: none;
    background: none;
    width: 70%;
    margin-bottom: 20px;
    padding: 10px;
    border-radius: 5px;
    background-color: #81D426;
    cursor: pointer;
    transition: color 0.3s, background-color 0.3s, border 0.3s;
    -webkit-transition: color 0.3s ease, background-color 0.3s ease, border 0.3s ease; 
}

.send-bt:hover {background-color: #3E8806; color: #fff;}
.send-bt:focus {outline: none;}
[info]Если текст на кнопке отправки слишком велик [submit class:button send_one "Получить консультацию по карте"] и в мобильной версии уходит за экран, можно заменить на <button class="button">Получить консультацию по карте</button>[/info]

Contact Form 7 Dynamic Text Extension

Дополнение добавляющее в плагин Contact Form 7 два дополнительных поля с динамическим содержанием (открытой и скрытое).
Есть возможность подгружать в это поле шорткоды. В примере ниже — user_favorites — шорткод

[dynamichidden dynamichidden-816 CF7_GET key='user_favorites'] — скрытое
[dynamictext dynamictext-654 CF7_GET key='user_favorites'] — открытое

Событие после отправки формы

[warn]В новейших версиях плагина рекомендуется js-обработчики прописывать в функциях. Ниже описано подробнее.[/warn]

В каждой форме в Дополнительных настройках можно выставлять события после отправки формы:

on_sent_ok:"$('#backfon').addClass('fadeOut')" - скрыть затемнение фона
on_sent_ok:"$('.popup').addClass('fadeOutDown')" - скрыть всплывающее окно
on_sent_ok:"$('#order-product').hide()" - спрятать кнопку вызывающую форму
on_sent_ok:"setTimeout(function () { $('#backfon').hide(); $('.popup').hide(); }, 700)" - скрыть фон и окно
on_sent_ok:"setTimeout(function(){$('.thanks').fadeIn('fast')},500)" - показать сообщение после отправки
on_sent_ok:"setTimeout(function(){$('.thanks').fadeOut('slow')},4000)" - спрятать сообщение

Сообщение ставим в подвал

<div class="thanks">Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.</div>

CSS сообщения

.thanks {
    position: fixed;
    left: 50%;
    z-index: 99;
    font-size: 22px;
    background-color: #043871;
    color: #fff;
    width: 200px;
    margin-left: -100px;
    padding: 25px 50px;
    display: none;
}

Редирект на другую страницу после отправки

on_sent_ok: "location.replace('http://www.SITE.com');"
либо
on_sent_ok: «location='http://адрес_страницы/';»

Дублирующиеся письма

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

Исправить это можно скриптом (при многократном нажатии отправка будет происходить 1 раз):

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

		fixCF7MultiSubmit();

		function fixCF7MultiSubmit(){
			jQuery('input.wpcf7-submit[type="submit"]').click(function() {
				var disabled = jQuery(this).attr('data-disabled');
				if (disabled && disabled == "disabled") {
					return false;
				} else {
					jQuery(this).attr('data-disabled',"disabled");
					return true;
				}
			});
			jQuery('.wpcf7').bind("wpcf7submit",function(){
				jQuery(this).find('input.wpcf7-submit[type="submit"]').attr('data-disabled',"enabled");
			});
		}
	});
}(jQuery));

А также прописать стиль, чтобы при успешной отправке исчезала кнопка Submit:

.wpcf7-form.sent input[type="submit"] {display: none;}

Contact Form 7 Datepicker

Еще один плагин расширяющий функционал Contact Form 7, добавляющий полноценный функционал добавления полей даты и времени с настройками оформления этих полей. Сходу плагин не работал, не появлялись всплывающие календари при выборе поля. Проблема устранилась после добавления стиля
#ui-datepicker-div {z-index: 99 !important;}

!Важной особенностью является то что поле не должно быть доступно для фокусирования. Иначе в мобильных браузерах будет происходить переход на заполнение стандартной текстовой формы. Чтобы запретить фокус на форме — необходимо прописать ему свойство readonly.

Есть такой косяк: когда даем возможность выбирать год (change-year) в выпадающем списке года выводятся в диапазоне -10 +10. Исправить это можно параметром указывающем точный диапазон годов — year-range:1940:2020. А если указать в одном из параметров now, то это будет текущий год.

Обновления обработчика событий

До конца 2017 плагин переходит с системы Дополнительные настройки, в которых прописывались js-события при отправке формы. Теперь создатели плагина рекомендуют эти события прописывать в functions.php следующим образом:

Общий обработчик событий для всех форм Contact Form 7

add_action( 'wp_footer', 'mycustom_wp_footer' );

function mycustom_wp_footer() {
?>
<script type="text/javascript">
document.addEventListener( 'wpcf7mailsent', function( event ) {
ga( 'send', 'event', 'Contact Form', 'submit' );
}, false );
</script>
<?php
}

Локализованный обработчик для конкретной формы (например, для счетчиков Яндекс и Google, либо для индивидуальных уведомлениях при отправке). Добавляем проверку по ID формы.

add_action( 'wp_footer', 'mycustom_wp_footer' );

function mycustom_wp_footer() {
?>
<script type="text/javascript">
document.addEventListener( 'wpcf7mailsent', function( event ) {
if ( '123' == event.detail.contactFormId ) {
ga( 'send', 'event', 'Contact Form', 'submit' );
}
}, false );
</script>
<?php
}

Также эти же скрипты можно реализовать не в виде функций, а вставлять в файл скриптов

//Обработчик событий Contact Form 7

//Общий
document.addEventListener( 'wpcf7mailsent', function( event ) {

  //$('#backfon').addClass('fadeOut');
  //$('.popup').addClass('fadeOutDown');
  //setTimeout(function () { $('#backfon').hide(); $('.popup').hide(); }, 700);
  
setTimeout(function(){$('.thanks').fadeIn('fast')},500);
setTimeout(function(){$('.thanks').fadeOut('slow')},4000);
  
}, false );

//Для конкретной формы с ID 8062
document.addEventListener( 'wpcf7mailsent', function( event ) {
if ( '8062' == event.detail.contactFormId ) {

alert('Работает!');  
  
}
}, false );

Три закомментированные строки нужны, если форма сделана в виде всплывающего окна.

Обновленный обработчик с целями Яндекс

document.addEventListener( 'wpcf7mailsent', function( event ) {
 
if ( '66' == event.detail.contactFormId ) {
yaCounter44705752.reachGoal('zakazconfer'); return true; 
}

}, false );

Вложение файлов

В функционале Contact Form 7 есть возможность добавления «поля» Файл (Вложение). Выглядит поле примерно так:

[file file-481 limit:100000 filetypes:.doc|.docx|.xls|.xlsx]

limit — максимальный размер файла, причем 10000 — это 10 Kb, 100000 — 1 Mb
filetypes — допустимые расширения файлов для вложения.

Обязательно в настройках Письмо вставить в поле Прикреплённые файлы название полей [file-481]

Маска для телефона

Чтобы для поля с телефоном создать такую маску (+7 (___) ___-__-__), нужно сделать следующее:

  • Установить скрипт jquery.maskedinput.min
  • Прописать для телефонных полей (.wpcf7-tel — универсальный класс для полей с телефоном) простой скрипт:
// Маска для телефона 
$(document).ready(function() {  
	$('.wpcf7-tel').mask('+7 (999) 999-9999'); 
});

Разные адресаты в зависимости от выбора поля

Решение взято с сайта wp-kama.ru

Создаем выпадающий список и прописываем в нем пары наименование|адресат таким образом:

[select* menu-429 "Мэйл|raddis75@mail.ru" "Яндекс|raddis75@yandex.ru" "Гугл|raddis75@gmail.com"]

Пользователи будут видеть только наименования, а в настройках Письмо в поле адресат вставляем это поле, в него будет подставляться значения в виде почты.

Можно также прописать несколько ящиков в одном значении:

[select* menu-430 "Мэйл|raddis75@mail.ru,raddis75@yandex.ru,raddis75@gmail.com" "Яндекс|raddis75@yandex.ru" "Гугл|raddis75@gmail.com"]

Если из этого же поля нужно получить первое значение до слэша, например в шаблоне тела письма, то у названия поля нужно добавлять приставку _raw_

[menu-477] будет выводиться raddis75@mail.ru
[_raw_menu-477] будет выводиться Мэйл

Подключить скрипты и стили CF7 только когда есть форма

function rjs_lwp_contactform_css_js() {
    global $post;
    if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'contact-form-7') ) {
        wp_enqueue_script('contact-form-7');
         wp_enqueue_style('contact-form-7');

    }else{
        wp_dequeue_script( 'contact-form-7' );
        wp_dequeue_style( 'contact-form-7' );
    }
}
add_action( 'wp_enqueue_scripts', 'rjs_lwp_contactform_css_js');

Если стили CF7 итак изначально отключены, то можно добавлять свои, при инициализации формы

// Подключаем стили Contact Form, только когда есть форма
function rjs_lwp_contactform_css_js() {
    global $post;
    if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'contact-form-7') ) {
        wp_enqueue_script('contact-form-7');
		wp_enqueue_style( 'cf7-custom-style', get_template_directory_uri() . '/css/contact-form-7-custom-style.css' , array( ), '1.0' , 'screen' );

    }else{
        wp_dequeue_script( 'contact-form-7' );
    }
}
add_action( 'wp_enqueue_scripts', 'rjs_lwp_contactform_css_js');
[post_title] => Contact Form 7 [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => contact-form-7 [to_ping] => [pinged] => [post_modified] => 2020-03-16 14:40:25 [post_modified_gmt] => 2020-03-16 11:40:25 [post_content_filtered] => [post_parent] => 0 [guid] => http://opttour.ru/?p=2023 [menu_order] => 0 [post_type] => post [post_mime_type] => [comment_count] => 0 [filter] => raw ) ) [post_count] => 4 [current_post] => -1 [before_loop] => [in_the_loop] => [post] => WP_Post Object ( [ID] => 11198 [post_author] => 1 [post_date] => 2019-09-20 22:47:42 [post_date_gmt] => 2019-09-20 19:47:42 [post_content] =>

Создаем формы без использования плагинов (например Contact Form 7). Делаем форму Ajax.

Создание простой формы

<form class="form-container recall-form-validate">
	<h2>Заказать звонок</h2>
	<input class="form-field form-name" type="text"  name="name" placeholder="Ваше имя"><br />
	<input class="form-field form-tel" type="text"  name="tel" placeholder="Ваш телефон"><br />
	<div id="submit-ajax" class="submit-container">
		<input class="submit-button" type="submit" value="Отправить"/>
	</div>
</form>

Добавляем скрипт обработчик (с валидацией полей)

$(".submit-button").on("click", function (event) {
	event.preventDefault();
	var name = $(".form-name").val();
	var tel = $(".form-tel").val();

	if (name  === '') {
        	alert('Заполните поле с именем');
        	return false;
	}
	
	if (tel  === '') {
        	alert('Заполните поле с номером телефона');
        	return false;
	}
	
	if (tel.match(/[^0-9'".]/)) {
        	alert('Телефон заполнен не верно');
        	return false;
	}

	$.ajax({
		url: "/wp-admin/admin-ajax.php",
		method: 'post',
		data: {
			action: 'ajax_order',
			name: name,
			tel: tel
		},
		success: function (response) {
			$('#submit-ajax').html(response);
		}
	});
});

Прописываем функцию формы

function ajax_form(){
    $name = $_REQUEST['name'];
    $tel = $_REQUEST['tel'];
    $response = '';
    $thm  = 'Заказ звонка';
    $thm  = "=?utf-8?b?". base64_encode($thm) ."?=";
    $msg = "Имя: ".$name."<br/>
        Телефон: ".$tel ."<br/>";
    $mail_to = 'mail@mail.ru';
    $headers = "Content-Type: text/html; charset=utf-8\n";
    $headers .= 'From: SITE <no-replay@site.ru>' . "\r\n";

    // Отправляем почтовое сообщение
    if(mail($mail_to, $thm, $msg, $headers)) {
        $response = 'Сообщение отправлено';
	} else {
		$response = 'Ошибка при отправке';
	}
	
    // Сообщение о результате отправки почты
    if ( defined( 'DOING_AJAX' ) && DOING_AJAX ){
        echo $response;
        wp_die();
    }
}

add_action('wp_ajax_nopriv_ajax_order', 'ajax_form' );
add_action('wp_ajax_ajax_order', 'ajax_form' );

Данное решение взято с сайта inprocess.by

Отправка формы с двумя разными шаблонами

Чтобы отправить форму с двумя разными шаблонами, например администратору и покупателю, нужно сделать следующее:

1. Добавить в скрипт отправки еще одну функцию ajax с другим action

$.ajax({
	url: "/wp-admin/admin-ajax.php",
	method: 'post',
	data: {
		action: 'ajax_order_client',
		name: name,
		tel: tel
	}
});

2. Создать еще одну функцию отправки письма и привязать её к новому action (ajax_order_client)

add_action('wp_ajax_nopriv_ajax_order_client', 'ajax_form_client' );
add_action('wp_ajax_ajax_order_client', 'ajax_form_client' );

Валидация и подсветка полей

Проверки на заполненность различных полей:

// Отправка заявки
$(".submit-button").on("click", function (event) {
	event.preventDefault();
	var name = $(".form-name").val();
	var tel = $(".form-tel").val();
	var email = $(".form-email").val();
	
	if (name  === '') {
        alert('Заполните поле с именем');
        return false;
	}
	
	if (tel  === '') {
		alert('Заполните поле с номером телефона');
		return false;
	} else if (tel.match(/[^0-9'".]/)) {
        alert('Телефон заполнен не корректно');
        return false;		
	} else if (tel.length < 8) {
		alert('Слишком короткий номер');
		return false;
	} else if (!((tel.lastIndexOf("+7", 0) === 0) || (tel.lastIndexOf("8", 0) === 0))) {
		alert('Введите корректный номер в формате +79998887766 или 89998887766');
		return false;
	}
	
	if(email  === '') { 
		alert('Укажите свой E-Mail');
		return false;
	} else if ( !validateEmail(email) ) {
		alert('Введите корректный E-Mail');
		return false;		
	}

	if (!$("input[name='messenger']:checked").val()) {
		alert("Выберите удобрый для вас мессенджер"); 
		return false;
	}
	
	if (!$('input:checkbox[name="acceptance"]').is(':checked')) {
		alert('Вы должны ознакомиться с политикой конфиденциальности');
		return false;
	}
	
	

	$.ajax({
		url: "/wp-admin/admin-ajax.php",
		method: 'post',
		data: {
			action: 'ajax_order',
			name: name,
			tel: tel,
			email: email,
		},
		success: function (response) {
			$('#submit-ajax').html(response);
		}
	});
});


// Проверка E-mail
function validateEmail($email) {
	var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
	return emailReg.test( $email );
}

Подсветка полей

// Подсвечивание полей обязательных для заполнения
$(".submit-button").on("click", function (event) {
	var name = $(".form-name").val();
	var tel = $(".form-tel").val();
	var email = $(".form-email").val();
	
	$(".form-field").removeClass('validate novalidate');
	
	if (name  === '') {
        $(".form-name").addClass('novalidate');
	} else {
		$(".form-name").addClass('validate');
	}
	
	if (tel  === '') {
		$(".form-tel").addClass('novalidate');
	} else if (tel.match(/[^0-9'".]/)) {
        $(".form-tel").addClass('novalidate');		
	} else if (tel.length < 8) {
		$(".form-tel").addClass('novalidate');
	} else if (!((tel.lastIndexOf("+7", 0) === 0) || (tel.lastIndexOf("8", 0) === 0))) {
		$(".form-tel").addClass('novalidate');
	} else {
		$(".form-tel").addClass('validate');
	}
	
	if(email  === '') { 
		$(".form-email").addClass('novalidate');
	} else if ( !validateEmail(email) ) {
		$(".form-email").addClass('novalidate');		
	} else {
		$(".form-email").addClass('validate');
	}
});
[quest]Придумать единую функцию подсветки[/quest]

Ошибка при отправке

В одном из проектов, на выделенном сервере, столкнулся с тем что функция mail (и wp_mail) не отправляли письма. Решил это установкой плагина Easy WP SMTP (300 000), в котором прописал настройки SMTP созданного ящика почты домена.

Был случай, также на выделенном сервере, что не работала отправка функцией mail, но при этом wp_mail отправляется нормально.

Защита полей перед отправкой

Поля перед отправкой необходимо защищать:

$name = sanitize_text_field( $_REQUEST['name'] );
$tel = sanitize_text_field( $_REQUEST['tel'] );
$object = sanitize_text_field( $_REQUEST['object'] );

$quest = sanitize_textarea_field( $_REQUEST['quest'] );

$email = sanitize_email( $_REQUEST['email'] );

Дополнительное письмо отправителю

В некоторых специфических формах может потребоваться отправка дополнительного письма адресату с подтверждением получения заявки.

Оптимально это сделать посредством создание отдельной страны с шаблоном ответа и добавлять заголовок и содержимое страницы в виде заголовка и содержимого письма:

// Отправляем почтовое сообщение
if(wp_mail($mail_to, $thm, $msg, $headers)) {
	$response = 'Сообщение отправлено.<br>Мы свяжемся с вами в ближайшее время.';
	
	//Письмо отправителю
	$page = get_post(1511);
	wp_mail($email, $page->post_title, $page->post_content, $headers);

	wp_reset_postdata();
} else {
	$response = 'Ошибка при отправке';
}
[post_title] => Ajax форма без плагина [post_excerpt] => [post_status] => publish [comment_status] => open [ping_status] => open [post_password] => [post_name] => ajax-forma-bez-plagina [to_ping] => [pinged] => [post_modified] => 2022-09-25 12:08:40 [post_modified_gmt] => 2022-09-25 09:08:40 [post_content_filtered] => [post_parent] => 0 [guid] => https://opttour.ru/?p=11198 [menu_order] => 0 [post_type] => post [post_mime_type] => [comment_count] => 0 [filter] => raw ) [comment_count] => 0 [current_comment] => -1 [found_posts] => 19 [max_num_pages] => 5 [max_num_comment_pages] => 0 [is_single] => [is_preview] => [is_page] => [is_archive] => [is_date] => [is_year] => [is_month] => [is_day] => [is_time] => [is_author] => [is_category] => [is_tag] => [is_tax] => [is_search] => [is_feed] => [is_comment_feed] => [is_trackback] => [is_home] => 1 [is_privacy_policy] => [is_404] => [is_embed] => [is_paged] => [is_admin] => [is_attachment] => [is_singular] => [is_robots] => [is_favicon] => [is_posts_page] => [is_post_type_archive] => [query_vars_hash:WP_Query:private] => bb5e45881dd9e498358910078f47556b [query_vars_changed:WP_Query:private] => [thumbnails_cached] => [allow_query_attachment_by_filename:protected] => [stopwords:WP_Query:private] => [compat_fields:WP_Query:private] => Array ( [0] => query_vars_hash [1] => query_vars_changed ) [compat_methods:WP_Query:private] => Array ( [0] => init_query_flags [1] => parse_tax_query ) )
Watermark для изображений товаров (обзор плагинов)
Рекомендации для васWatermark для изображений товаров (обзор плагинов)Opttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.