Форма с валидацией и отправкой на 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
Tags:
ajax, javascript, php, валидация, форма регистрации

You can't comment this post because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author's username will be hidden by an alias.