Форма с валидацией и отправкой на Ajax

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

Вот скриншот формы:

image

А вот скриншот той же формы, но с ошибками ввода:

image

Ссылка на скачивание и тестирование — внизу.

Забегая вперед, скажу, что в итоге вышло 7 файлов:
  1. jquery1.10.min.js
  2. jquery.form.validation.js
  3. site.js
  4. send.php
  5. style.css
  6. corner.gif
  7. index.php
  8. Начнем.

jquery1.10.min.js — мы подключаем библиотеку jQuery последней версии;

jquery.form.validation.js — «почти jQuery плагин» от Романа Янке;

site.js — тут я объединил все мною написанные скрипты, которые здесь использованы;

send.php — скрипт отправки данных из формы на почту;

style.css — стили для ошибок ввода;

corner.gif — уголок для оформления сообщения об ошибке валидации;

index.php — наш главный файл в котором расположена форма и объединены скрипты со стилями.

Сначала я покажу содержимое файлов, а затем все объясню.

Файл index.php:
<!DOCTYPE html>
<html lang="ru">
	<head>
		<title>Форма</title>
		<meta charset="UTF-8" />
		<link rel="stylesheet" href="./style.css" />
		<!--[if lt IE 9]> 
			<script type="text/javascript" src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
		<![endif]-->
		<script type="text/javascript" src="./jquery1.10.min.js"></script>
		<script type="text/javascript" src="./jquery.form.validation.js"></script>
		<script type="text/javascript" src="./site.js"></script>
	</head>
	<body>
		<form id="form" method="post" action="javascript:void(0);" onsubmit="ajax()">
			<p>Ваше имя</p>
			<p><input type="text" name="name" class="name" value="" /></p>
		 	<p>Ваш email</p>
			<p><input type="text" name="email" class="email" value="" /></p>
			<p>Тема</p>
			<p><input type="text" name="subject" class="subject" value="" /></p>
			<p>Сообщение</p>
			<p><textarea name="message" class="message"></textarea></p>
			<p><input type="submit" name="send" class="send" value="send"></p>
		</form>
		<div id="results"></div>
	</body>
</html>


При отправки формы мы перехватываем стандартное действие атрибута action и вызываем нашу функцию ajax();. Для работы нашей валидации каждому инпуту и полю ввода задаем отдельные классы или идентификаторы. А для серверного скрипта — пишем name.

Файл site.js:
function ajax() { //Ajax отправка формы
	var msg = $("#form").serialize();
	$.ajax({
		type: "POST",
		url: "./send.php",
		data: msg,
		success: function(data) {
			$("#results").html(data);
		},
		error:  function(xhr, str){
			alert("Возникла ошибка!");
		}
	});
}

jQuery.fn.notExists = function() { //Проверка на существование элемента
	return $(this).length == 0;
}

$(document).ready(function(){ //Валидация формы
	$(".send").validation(
		$(".name").validate({
			test: "blank letters", 
			invalid: function(){
				if($(this).nextAll(".error").notExists()) {
					$(this).after('<div class="error">Введите корректное имя</div>');
					$(this).nextAll(".error").delay(2000).fadeOut("slow");
					setTimeout(function () {
						$(".name").next(".error").remove();
					}, 2600);
				}
			},
			valid: function(){
				$(this).nextAll(".error").remove();
			}
		}),
		$(".email").validate({
			test: "blank email",
			invalid: function(){
				if($(this).nextAll(".error").notExists()) {
					$(this).after('<div class="error">Введите корректный email</div>');
					$(this).nextAll(".error").delay(2000).fadeOut("slow");
					setTimeout(function () {
						$(".email").next(".error").remove();
					}, 2600);
				}
			},
			valid: function(){
				$(this).nextAll(".error").remove();
			}
		}),
		$(".subject").validate({
			test: "blank", 
			invalid: function(){
				if($(this).nextAll(".error").notExists()) {
					$(this).after('<div class="error">Введите тему</div>');
					$(this).nextAll(".error").delay(2000).fadeOut("slow");
					setTimeout(function () {
						$(".subject").next(".error").remove();
					}, 2600);
				}
			},
			valid: function(){
				$(this).nextAll(".error").remove();
			}
		}),
		$(".message").validate({
			test: "blank", 
			invalid: function(){
				if($(this).nextAll(".error").notExists()) {
					$(this).after('<div class="error">Введите сообщение</div>');
					$(this).nextAll(".error").delay(2000).fadeOut("slow");
					setTimeout(function () {
						$(".message").next(".error").remove();
					}, 2600);
				}
			},
			valid: function(){
				$(this).nextAll(".error").remove();
			}
		})
	);
});


Так вот.

function ajax() { //Ajax отправка формы
	var msg = $("#form").serialize();
	$.ajax({
		type: "POST",
		url: "./send.php",
		data: msg,
		success: function(data) {
			$("#results").html(data);
		},
		error:  function(xhr, str){
			alert("Возникла ошибка!");
		}
	});
}


Вводим новую переменную msg, собираем в ней все полученные данные с полей формы функцией serialize(), у тега form у нас стоит id=«form», далее используем метод jQuery.ajax, соответственно метод отправки POST, url — путь к PHP скрипту, data — тут данные, которые нужно отправить на сервер, в нашем случае это данные с формы. В случае успешного результата (success), выводим в блок #results данные, которые поступили с сервера, например, отчет об отправке. А если произошла ошибка (error), то соответственно выводим сообщение об ошибке.

Далее, создадим функцию:

jQuery.fn.notExists = function() { //Проверка на существование элемента
	return $(this).length == 0;
}

Например, если на странице не существует блок с class="error", то создадим его:

if($(".error").notExists()) {
    $(this).after('<div class="error"></div>');
}

По готовности DOM:

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

Инициализируем «почти плагин» и вешаем его на кнопку отправить, мы задали у нее class="send":

$(".send").validation();

Далее вешаем функцию validate(); на КАЖДОЕ поле нашей формы — задаем полям либо классы либо идентификаторы, кому как нужно. В параметр test мы можем передать следующие значения:
  • blank Поле должно быть заполнено
  • email Поле должно быть заполнено + это должен быть валидный емэйл
  • maxlength# Устанваливает максимальное количество символов в поле — #
  • minlength# Устанавливает минимальное количество символов в поле — #
  • lengthrange#-# Устанавливает диапазон длины значение от # до # символов
  • digits Принимает только цифтры
  • letters Принимает только буквы
  • Рег выражение Можно задать любое регулярное выражение для проверки поля
  • Функции Можно задать любую функцию для проверки, которая вернет true/false
  • Объекты jQuery Укажите любое поле, чтобы проверить текущее значение поля со значением указанного.

Так же можно комбинировать данные значения.

Есть два необязательных параметра: valid — если всё ок и invalid — если не ок

Далее — функции, которые я написал.

Первая функция

Если после инпута с классом .name нет элементов с классом .error, то добавляем после инпута блок с этим классом и сообщением об ошибке внутри и через 2 секунды скрываем его от посторонних глаз с помощью функции fadeOut(); далее, через паузу в 2.6 секунд, мы удаляем этот блок из дерева DOM. Почему именно 2.6 секунд? У нас блок исчезает через 2 секнды с помощью fadeOut(«slow»); а slow длится 0.6 секунд. Вот и получается 2.6. Кстати, все значения здесь в миллисекундах.

Вторая функция

Пользователь все правильно ввел, сообщение об ошибке нужно убрать из дерева DOM.

$(".name").validate({
	test: "blank letters", 
	invalid: function(){
		if($(this).nextAll(".error").notExists()) {
			$(this).after('<div class="error">Введите корректное имя</div>');
			$(this).nextAll(".error").delay(2000).fadeOut("slow");
			setTimeout(function () {
				$(".name").next(".error").remove();
			}, 2600);
		}
	},
	valid: function(){
		$(this).nextAll(".error").remove();
	}
});

Можно написать очень много таких функций для полей любого типа. Идем дальше. Скрипт отправки данных на почту:

Скрипт
<?php
if (!isset($_POST['name']) or empty($_POST['name'])) {
	$error1 = "Имя?<br />";
} else $error1 = NULL;

if (!isset($_POST['email']) or empty($_POST['email'])) {
	$error2 = "Email?<br />";
} else $error2 = NULL;

if (!isset($_POST['subject']) or empty($_POST['subject'])) {
	$error3 = "Тема?<br />";
} else $error3 = NULL;

if (!isset($_POST['message']) or empty($_POST['message'])) {
	$error4 = "Сообщение?<br />";
} else $error4 = NULL;

if (empty($error1) and empty($error2) and empty($error3) and empty($error4)) {
	$subject = $_POST['subject'];
	$name    = $_POST['name'];
	$email   = $_POST['email'];
	$message = "Имя: {$name}, email: {$email}, сообщение: {$_POST['message']}";
	if (mail("email@domain.zone", $subject, $message)) {
		echo "Отправлено!";
	} else echo "Ошибка!";
} else {
	echo $error1.$error2.$error3.$error4;
}
?>


Здесь, думаю, все понятно. Сначала проверяем на заполненность и существование данных из формы, обязательно нужно делать проверку на сервере.

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

Теперь файл стилевого оформления:
input {
	outline:none;
}

.invalid {
	background: rgba(255, 0, 0, 0.4);
}

input, textarea{
	width: 200px;
}

.error{
	position: absolute;
	width: 200px;
	height: 30px;
	text-align: center;
	line-height: 30px;
	margin-left: 10px;
	display: inline-block;
	vertical-align: top;
	background: #ebf5ff;
	border: 1px solid #b1d3f5;
}

.error::before{
	content: url(./corner.gif);
	width: 13px;
	height: 6px;
	position: absolute;
	top: 8px;
	left: -10px;
}


Здесь ничего объяснять не буду — все и так понятно.

Может быть, моя статья кому-нибудь понравится.

Протестировать можно здесь: jsfiddle.net/mCNF4/8

Скачать можно здесь: zombiqwerty.ru/files/form.zip
Теги:
ajax, javascript, php, валидация, форма регистрации

Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.