PHP

Красивая форма подписки с помощью PHP, jQuery и CSS3

Сегодня мы создадим красивую форму, которая также прекрасно будет работать при отключенном JS. То есть первым делом мы сделаем так, чтобы форма работала без JS и без подержки CSS3, а далее уже будем накладывать слоями разные фишки, AJAX и jQuery.

В данной форме также есть пользовательские всплывающие подсказки для валидации.

Шаг 1 - XHTML

Первый шаг заключается в создании скелета нашей формы. Она должна быть простой и очень юзабильной :)
<div id="carbonForm">
<h1>Signup</h1>
<form action="submit.php" method="post" id="signupForm">
<div class="fieldContainer">
<div class="formRow"></div>
<!-- Two more formRow divs -->
</div>
<div class="signupButton">
<input type="submit" name="submit" id="submit" value="Signup" />
</div>
</form>
</div>

div carbonForm - главный контейнер формы. Он центрирован на странице с помощью CSS свойства margin, а по вертикали с помощью jQuery.

Внутри у на заголовок и форма с div fieldContainer. Внутри него три div formRow, у которых следующая разметка:
<div class="formRow">
<div class="label">
<label for="name">Name:</label>
</div>
<div class="field">
<input type="text" name="name" id="name" />
</div>
</div>

Каждая пара элементов label и input размещена внутри оберток, которые выровнены по левому краю. Важно, чтобы название текстовых полей были такими же как и id, так как это используется при отображении всплывающих ошибок.

Шаг 2 - CSS

Форма сильно зависит от CSS для достижения такого красивого эффекта. Целая череда CSS3 свойств используется тут. Ранее такого эффекта можно было добиться только с помощью Photoshop. Здесь представлена только наиболее интересные стили:
#carbonForm{
	/* Главный контейнер */
	background-color:#1C1C1C;
	border:1px solid #080808;
	margin:20px auto;
	padding:20px;
	width:500px;

	-moz-box-shadow:0 0 1px #444 inset;
	-webkit-box-shadow:0 0 1px #444 inset;
	box-shadow:0 0 1px #444 inset;
}

.fieldContainer{
	/* Светлая закругленная секция, которая содержит поля */
	background-color:#1E1E1E;
	border:1px solid #0E0E0E;
	padding:30px 10px;

	/* CSS3 тени, используется для внутреннего свечения */
	-moz-box-shadow:0 0 20px #292929 inset;
	-webkit-box-shadow:0 0 20px #292929 inset;
	box-shadow:0 0 20px #292929 inset;
}

#carbonForm,.fieldContainer,.errorTip{
	/* Закругления div */
	-moz-border-radius:12px;
	-webkit-border-radius:12px;
	border-radius:12px;
}

.formRow{
	height:35px;
	padding:10px;
	position:relative;
}

.label{
	float:left;
	padding:0 20px 0 0;
	text-align:right;
	width:70px;
}

label{
	font-family:Century Gothic,Myriad Pro,Arial,Helvetica,sans-serif;
	font-size:11px;
	letter-spacing:1px;
	line-height:35px; /* Neat line height trick */
}

.field{
	float:left;
}

.field input{
	/* Текстовый ячейки */
	border:1px solid white;
	color:#666666;
	font-family:Arial,Helvetica,sans-serif;
	font-size:22px;
	padding:4px 5px;
	background:url("img/box_bg.png") repeat-x scroll left top #FFFFFF;
	outline:none;
}

#submit{
	/* Кнопка отправки */
	border:1px solid #f4f4f4;
	cursor:pointer;
	height:40px;
	text-indent:-9999px;
	text-transform:uppercase;
	width:110px;

	background:url("img/submit.png") no-repeat center center #d0ecfd;

	-moz-border-radius:6px;
	-webkit-border-radius:6px;
	border-radius:6px;
}

#submit.active{
	/* Добавляем прелоадер после нажатия на кнопку */
	background-image:url("img/preloader.gif");
}

input:hover,
input:focus{
	/* CSS3 эффект свечения */
	-moz-box-shadow:0 0 8px lightblue;
	-webkit-box-shadow:0 0 8px lightblue;
	box-shadow:0 0 8px lightblue;
}

Большинство из этих стилей понятны с первого взгляда. Возможно для Вас будет интересен момент с использованием кнопки отправки.

Для того, чтобы спрятать текст (в нашем случае "Signup") мы можем использовать трюк с отрицательным text-indent, но в IE это работает только, если мы укажем правило text-transform:uppercase. Мы также добавляем прозрачный фон состоящий из текста "Submit", который сменяется вращающимся gif прелоадером, если кнопке присвоен класс "active".

Шаг 3 - jQuery

После подключения библиотеки у нас идет файл script.js.

script.js
$(document).ready(function(){
	// $(document).ready() выполняется после загрузки страницы

	// Привязываем слежение за отправкой формы:
	$('#signupForm').submit(function(e){

		// Если прошлая отправка еще не завершилась:
		if($('#submit').hasClass('active')) return false;

		// Добавляем класс active dyjgrt. Будем отображать gif прелоадер:
		$('#submit').addClass('active');

		// Убираем текущие сообщения об ошибках
		$('.errorTip').remove();

		// Выдаем запрос POST ajax для submit.php:
		$.post($('#signupForm').attr('action'),
			$('#signupForm').serialize()+'&fromAjax=1',function(response){

			if(!response.status)
			{
				// Если случилась ошибка

				// Проходим через все текстовые ячейки,
				// и проверяем где именно ошибка
				$('input[type!=submit]').each(function(){
					var elem = $(this);
					var id = elem.attr('id');

					if(response[id])
						showTooltip(elem,response[id]);
				});
			}
			else location.replace(response.redirectURL);

			$('#submit').removeClass('active');
		},'json');

		e.preventDefault();
	});

	$(window).resize();
});

// Центрируем вертикально форму при каждом изменении размеров браузера:
$(window).resize(function(){
	var cf = $('#carbonForm');

	$('#carbonForm').css('margin-top',($(window).height()-cf.outerHeight())/2)
});

// Вспомогательная функция, которая отвечает за всплывающие ошибки:
function showTooltip(elem,txt)
{
	// elem - текстовая ячейка, txt - текст ошибки
	$('<div class="errorTip">').html(txt).appendTo(elem.closest('.formRow'));
}

Нажатие на кнопку отправки (или же нажатие кнопки Enter после заполнения полей) отправляет форму. Функция, которая привязана к отправке предотвращает форму от e.preventDefault() и выдает запрос для submit.php.

Возвращенный ответ расценивается как код JSON (объект JavaScript), который содержит специально свойство status. В зависимости от его значения, скрипт или же показывает ошибки при заполнении или же перенаправляет браузер на указанную страницу.

Текст сообщений об ошибках
{
	"status"	: 0,	// Обозначает, что возникла ошибка
	"email"		: "Please fill in a valid email!",		// Сообщение об ошибке
	"pass"		: "Please fill in a valid password!"	// Сообщение об ошибке
}

Всплывающий ошибки генерируются скриптом при прохождении по всем текстовым ячейкам и при проверки существования их id в качестве свойств. Если они существуют - создается ошибка с помощью функции showTooltip().

Также обратите внимание как мы используем метод serialize() на строке 18 для отправки всех полей за один раз. Также на этой же строке мы устанавливаем fromAjax=1, что сообщит PHP о необходимости возврата ответа как JSON.

Шаг 4 - PHP

Эта форма хороша тем, что прекрасно работает даже без JavaScript. Она работает потому, что атрибут action имеет также значение submit.php. Это означает, что нам необходимо только внедрить проверку.

submit.php
// Сообщения об ошибках:
error_reporting(E_ALL^E_NOTICE);

// По этому УРЛу переходит пользователь
// после удачного заполнения и отправки формы:

$redirectURL = 'http://demo.tutorialzine.com/2010/04/carbon-signup-form/demo.html';

$errors = array();

// Проверяем введенные данные, и, если есть ошибки, добавляем их в массив $errors:

if(!$_POST['name'] || strlen($_POST['name'])<3 || strlen($_POST['name'])>50)
{
	$errors['name']='Please fill in a valid name!<br />Must be between 3 and 50 characters.';
}

if(!$_POST['email'] || !preg_match("/^[\.A-z0-9_\-\+]+[@][A-z0-9_\-]+([.][A-z0-9_\-]+)+[A-z]{1,4}$/", $_POST['email']))
{
	$errors['email']='Please fill in a valid email!';
}

if(!$_POST['pass'] || strlen($_POST['pass'])<5)
{
	$errors['pass']='Please fill in a valid password!<br />Must be at least 5 characters long.';
}

// Проверяем был ли запрос с помощью AJAX

if($_POST['fromAjax'])
{
	if(count($errors))
	{
		$errString = array();
		foreach($errors as $k=>$v)
		{
			// The name of the field that caused the error, and the
			// error text are grouped as key/value pair for the JSON response:
			$errString[]='"'.$k.'":"'.$v.'"';
		}

		// JSON ответ об ошибке:
		die	('{"status":0,'.join(',',$errString).'}');
	}

	// JSON удачный ответ. Возвращает УРЛ для редиректа:
	echo '{"status":1,"redirectURL":"'.$redirectURL.'"}';

	exit;
}

// Если запрос был не AJAX (из за отключенного JS скорее всего):

if(count($errors))
{
	echo '<h2>'.join('<br /><br />',$errors).'</h2>';
	exit;
}

// Переправляем пользователей вручную после удачной отправки:

header("Location: ".$redirectURL);

Все полученные ошибки добавляются в массив $errors. И они потом отображаются на экране.

Вот и все готово! Пользуйтесь!
Добавлено: 22 Августа 2013 07:04:23 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...