В данном уроке мы разберем, как создать гладкую форму подписки по е-mail. Форма будет использовать силу AJAX, так как мы будем отправлять данные на сервер, проверять их и возвращать ответ – и все без обновления страницы!
sourse
Шаг 1. План
Итак, мы планируем создать форму подписки по e-mail, но не простую, а супер-отзывчивую, заряженную AJAX форму. Что означает отсутствие каких-либо перезагрузок страницы, оповещение пользователя о статусе обновления в реальном времени, и использование мощности сервера для проверки данных. Вот что мы собираемся сделать:
Структура нашего проекта
Для успешного завершения проекта нам потребуется использовать несколько крутых веб технологий. В список входят JavaScript (с существенным использованием jQuery), AJAX, PHP, MySQL и JSON. Вот краткий список того, для чего используются данные технологии:
JavaScript – передача данных на сервер и разбор сообщений, полученных от сервера. Мы будем использовать jQuery для обработки вызовов AJAX и разбора JSON.
PHP – обработка данных, отправленных на сервер. Включает проверку данных (нужно убедиться, что все в порядке перед помещением их в базу данных) и обработку ответа для отправки обратно браузеру.
MySQL – сохранение данных о подписке.
JSON – склеивает все выше перечисленное.
Теперь можно начинать создавать проект!
Шаг 2. Установка базы данных
Первое, что надо сделать - установить базу данных. В данный момент мы хотим сохранять только адрес пользователя, дату и время его подписки. Открываем PHPMyAdmin (или другой инструмент для управления вашей базой данных MySQL) и создаем новую таблицу в базе данных с помощью следующего выражения:
CREATE TABLE `signups` (
`signups_id` int(10) NOT NULL AUTO_INCREMENT,
`signup_email_address` varchar(250) DEFAULT NULL,
`signup_date` date DEFAULT NULL,
`signup_time` time DEFAULT NULL,
PRIMARY KEY (`signups_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Выше приведенного кода должно быть достаточно для реализации наших желаний. Поле signups_id с автоинкрементом используется для назначения уникального идентификатора для каждой записи. Поле signup_email_address служит для хранения адреса пользователя, а поля signup_date и signup_time содержат дату и время подписки.
Шаг 3. HTML
<form id="newsletter-signup" action="?action=signup" method="post">
<fieldset>
<label for="signup-email">Подпишитесь на рассылку по e-mail новостей, предложений и событий:</label>
<input type="text" name="signup-email" id="signup-email" />
<input type="submit" id="signup-button" value="Подписаться!" />
<p id="signup-response"></p>
</fieldset>
</form>
Это минимум HTML кода, который нужен для работы (здесь не включены обязательные теги страницы. Также вам нужно будет загружать jQuery). Все что нужно - это поле ввода текста, кнопка отправки, и элемент для вывода сообщения. Очевидно, что нужно добавить метку для поля ввода. Также мы используем тег fieldset. Элемент вывода сообщения в данный момент пустой.
Вид формы
Пока форма выглядит плоской. Нужно добавить несколько правил CSS для придания лучшего ей вида:
* {
padding:0;
margin:0;
}
body {
font-size:12px;
font-family:Arial, Helvetica, sans-serif;
}
fieldset {
border:none;
}
form {
width:930px;
margin:20% auto;
padding:15px;
border:solid 6px #9FCBFF;
-moz-border-radius:6px;
-webkit-border-radius:6px;
border-radius:6px;
}
input {
border:none;
background-color:none;
}
#signup-email {
border:1px solid #999999;
color:#9E9E9E;
padding:5px;
margin-left:10px;
margin-right:4px;
}
#signup-email:focus {
border-color:#9FCBFF;
background-color:#DFEEFF;
background-image:none;
color:#000;
}
#signup-button {
background-color:#9FCBFF;
color:#FFF;
-moz-border-radius:10px;
-webkit-border-radius:10px;
border-radius:10px;
padding:5px;
text-shadow: 1px 1px 1px #5FA8FF;
}
#signup-button:hover {
cursor:pointer;
background-color:#7FB9FF;
}
#signup-response {
display:inline;
margin-left:4px;
padding-left:20px;
}
.response-waiting {
background:url("loading.gif") no-repeat;
}
.response-success {
background:url("tick.png") no-repeat;
}
.response-error {
background:url("cross.png") no-repeat;
}
Вид формы со стилями
Хотя сообщение пока не выводится, в нужный момент оно появится справа от кнопки "Подписаться":
Вывод сообщения
Шаг 4. Клей.
Теперь когда база данных и разметка организованы, нам надо решить, как они будут связаны в одно целое.
Как Javascript будет посылать и получать сообщения от совершенно другого языка программирования (PHP)? Для этих целей мы собираемся использовать JSON.
Что такое JSON?
JSON (JavaScript Object Notation - запись объекта Javascript) - это легкий, основанный на тексте открытый стандарт, разработанный для обмена данными в формате, удобном для чтения человеком (по замыслу очень похоже на XML). JSON часто используется для сериализации и передачи структурированных данных через сетевые соединения. В основном он используется для передачи данных между сервером и веб приложением, как альтернатива XML. JSON происходит из языка программирования Javascriptis для представления простых структур данных и ассоциированных массивов или объектов. Не смотря на свою связь с Javascript, он не зависит от языка программирования. Парсеры JSON существуют практически в каждом языке программирования. Пример JSON:
{"КЛЮЧ":"ЗНАЧЕНИЕ"}
Как можно заметить, он очень простой. Мы заключаем пару ключ-значение в фигурные скобки. Фигурные скобки означают, что это - объект. Все что находится между ними является частью объекта. Можно использовать несколько пар ключ-значение в объекте:
{"КЛЮЧ":"ЗНАЧЕНИЕ",
"КЛЮЧ_1":"ЗНАЧЕНИЕ_1",
"КЛЮЧ_2":"ЗНАЧЕНИЕ_2"}
Все что мы сделали - разделили пары ключ-значение с помощью запятой. Пары ключ-значение в действительности рассматриваются как члены объекта (объекта JSON). Вы можете использовать и более сложные структуры:
{"КЛЮЧ_1": {
"КЛЮЧ_2": "ЗНАЧЕНИЕ_2",
"КЛЮЧ_3": "ЗНАЧЕНИЕ_3",
"КЛЮЧ_4": {
"ЗНАЧЕНИЕ_4": [
{"ОБЪЕКТ_1_КЛЮЧ_1": "ОБЪЕКТ_1_ЗНАЧЕНИЕ_1", "ОБЪЕКТ_1_КЛЮЧ_2": "ОБЪЕКТ_1_ЗНАЧЕНИЕ_2"},
{"ОБЪЕКТ_2_КЛЮЧ_1": "ОБЪЕКТ_2_ЗНАЧЕНИЕ_1", "ОБЪЕКТ_2_КЛЮЧ_2": "ОБЪЕКТ_2_ЗНАЧЕНИЕ_2"},
{"ОБЪЕКТ_3_КЛЮЧ_1": "ОБЪЕКТ_3_ЗНАЧЕНИЕ_1", "ОБЪЕКТ_3_КЛЮЧ_2": "ОБЪЕКТ_3_ЗНАЧЕНИЕ_2"}
]
}
}}
Вот что здесь записано:
Значение, соответствующее КЛЮЧ_1 - объект.
Внутри данного объекта есть пары ключ-значение для КЛЮЧ_2 и КЛЮЧ_3.
КЛЮЧ_4 также имеет объект в качестве значения.
ЗНАЧЕНИЕ_4 является массивом 3-х объектов, которые содержат по две пары ключ-значение каждый.
Но для наших нужд такая структура не нужна.
Все, что нам нужно - это передать с сервера ответ JSON, содержащий два члена (пары ключ-значение): один для статуса и один для сообщения. Вот как он будет выглядеть:
{"status":"success","message":"Вы подписаны!"}
status является индикатором завершения процесса подписки - удачно или нет. message содержит сообщение соответствующее значению status. Если status имеет значение ‘success’, мы сообщаем пользователю, что он успешно подписан. Если status имеет значение ‘error’, то нужно сообщить пользователю о причинах ошибки. Но зачем иметь два члена, которые выполняют примерно одинаковые функции - message и status ? Есть две причины. Первая - мы хотим использовать класс для содержания сообщения ответа, то есть мы будем выводить зеленую галочку в случае успеха и красный крест в случае ошибки. Вторая причина - есть только одно сообщение об успехе операции, но в случае ошибки есть четыре варианта сообщения. Сообщение об ошибке может быть получено в следующих случаях:
Пользователь не ввел адрес e-mail
Пользователь ввел не правильный адрес e-mail.
Адрес введенный пользователем уже используется.
Есть какие-то технические ошибки и данные пользователя не могут быть проверены или добавлены в базу данных.
Чтобы избежать анализа текста сообщения и облегчения изменения текста сообщений в будущем нужно иметь индикатор, который сигнализирует о том, как завершилась операция, и текст сообщения.
Шаг 5. Подготавливаем все к действию.
Обычно, когда происходит отправка формы, браузер перенаправляется к действию формы. Но так как мы будем отправлять данные с использованием AJAX, то нужно прервать действие по умолчанию:
$(document).ready(function(){
$('#newsletter-signup').submit(function(){
//Здесь выполняется запрос AJAX
//предотвращаем отправку формы
return false;
})
})
Когда документ готов, и событие submit генерируется элементом с id newsletter-signup (то есть нашей формой), выполняется код внутри функции. Здесь будет вставлен вызов AJAX, обработчик ответа JSON, и еще ряд операций для обеспечения нужного функционирования. В данный момент в функции имеется только код return false. Таким образом останавливается отправка формы.
Теперь нужно установить переменные, которые мы будем использовать;
var form = $(this),
formData = form.serialize(),
formUrl = form.attr('action'),
formMethod = form.attr('method'),
responseMsg = $('#signup-response')
Здесь происходит объявление нескольких переменных. Просто пишем один раз ключевое слово var. Переменные служат для :
form – мы используем this обернутый в объект jQuery. this ссылается на элемент формы. Мы оборачиваем его объектом jQuery, чтобы использовать другие функции.
formdata – мы используем функцию jQuery serialize() для получения данных формы. В нашей простой форме функция serialize() берет все поля и их значения и размещает их в строке в виде пар ключ-значение. Затем мы будем отправлять данную строку на сервер.
formUrl – это URL, на который мы отправляем данные.
formMethod – это метод, который используется для отправки данных.
responseMsg – это элемент, который используется для вывода сообщения пользователю.
Мы получаем URL формы и метод формы таким образом, что нам не нужно будет изменять код JavaScript, если мы решим изменить где и как производить отправку данных на сервер в HTML. Элемент сообщения ответа сохраняется в переменной, поэтому поиск по структуре DOM производится только один раз. многочисленные запросы к структуре DOM только ухудшают производительность кода.
Так как мы собираемся использовать AJAX для отправки формы, нужно обеспечить индикацию для пользователя о том, что идет процесс. Для этого сообщение ответа получает значение ‘Пожалуйста, подождите...’ и класс ‘response-waiting’. Таким образом выводится отличный символ загрузки.
//Показываем соообщение с просьбой подождать
responseMsg.hide()
.addClass('response-waiting')
.text('Пожалуйста, подождите...')
.fadeIn(200);
Сначала мы скрываем элемент сообщения ответа, поэтому, когда мы устанавливаем текст, он не появляется сразу. Затем мы добавляем класс ‘response-waiting’. После чего устанавливаем текст ‘Пожалуйста, подождите...’ и проявляем элемент. Здесь используется связывание функций jQuery в цепочку. Код responseMsg может быть написан в одну строку, а разделение произведено только с целью наглядности.
Шаг 6. Отправляем на сервер.
Теперь у нас есть данные, мы индикацию процесса для посетителя. Будем использовать функцию jQuery для отправки данных на сервер.
$(document).ready(function(){
$('#newsletter-signup').submit(function(){
//Проверяем, не отправляется ли уже форма в текущий момент времени
if($(this).data('formstatus') !== 'submitting'){
//Устанавливаем переменные
var form = $(this),
formData = form.serialize(),
formUrl = form.attr('action'),
formMethod = form.attr('method'),
responseMsg = $('#signup-response');
//Добавляем дату к форме
form.data('formstatus','submitting');
//Показываем соообщение с просьбой подождать
responseMsg.hide()
.addClass('response-waiting')
.text('Пожалуйста, подождите...')
.fadeIn(200);
//Отправляем данные на сервер для проверки
$.ajax({
url: formUrl,
type: formMethod,
data: formData,
success:function(data){
// выполняем некоторые операции, когда вызов AJAX завершен
});
}
//Предотвращаем отправку формы
return false;
});
});
Магия заключается в следующем куске кода:
$.ajax({
url: formUrl,
type: formMethod,
data: formData,
success:function(data){
// выполняем некоторые операции, когда вызов AJAX завершен
});
Мы используем функцию $.ajax() для передачи данных на сервер. Данная функция обрабатывает сложный кросс браузерный запрос XML HTTP, который для нас не представляет интереса. Нужно повнимательнее посмотреть на объект JSON…
Нам нужно передать некоторую информацию функции $.ajax() о том , что делать и как делать. Вы можете пережать несколько параметров функции $.ajax(), но в рамках данного урока мы передаем только URL, тип, данные и параметр success.
url – адрес URL, на который отправляются данные. Мы ранее сохранили его в переменной formURL.
type – метод, который используется для отправки данных на сервер. Мы сохранили его ранее в переменной formMethod.
data – данные, которые передаются на сервер. Мы сохранили их ранее в переменной formData.
success - это возвратная функция. Она вызывается если вызов AJAX прошел успешно. В данной функции мы обрабатываем ответ JSON, полученный от сервера.
Шаг 7: Функция success
Как только мы передадим данные на сервер, он отправит сообщение для нас. Сообщение будет строкой в формате JSON. К счастью, jQuery имеет функцию для разбора JSON.
success:function(data){
//Устанавливаем перменные
var responseData = jQuery.parseJSON(data),
klass = '';
}
Аргумент data, который передается функции, является ответом JSON, возвращаемым сервером. В данной функции первое, что надо сделать - это установить две переменные:
responseData - она содержит разобранный ответ JSON. Функция $.parseJSON() преобразует наш ответ JSON в объект JavaScript.
klass - данная переменная получит значение позже. Она содержит имя класса, которое будет использоваться для элемента, содержащего сообщение ответа. Примечание: имя 'class' является зарезервированными словом в JavaScript и не может быть использовано для наименования переменнных.
Затем нам нужно определить, какой класс CSS нужно использовать для элемента сообщения ответа. Класс будет зависеть от статуса ответа сервера. Если статус имеет значение 'success,' то будет установлен класс 'response-success,' в случае значения статуса 'error', мы установим класс 'response-error'.
//Состояния ответа
switch(responseData.status){
case 'error':
klass = 'response-error';
break;
case 'success':
klass = 'response-success';
break;
}
Классы CSS, которые используются для сообщения статуса, выглядят следующим образом:
Классы CSS сообщения
Первый класс (.response-loading) соответствует сообщению о процессе загрузки, второй (.response-success) - сообщению об успехе операции, а третий (.response-error) - сообщению об ошибке.
Мы используем оператор switch для определения класса, который надо использовать для сообщения. Можно использовать оператор if, но в данном случае все же лучше подходит switch. Условия, которые мы хотим сравнивать между собой находятся в responseData.status. responseData является объектом, а status - свойство объекта. Данный объект создается функцией $.parseJSON() на основе полученного ответа JSON. Данный ответ имеет два члена: status и message, которые будут конвертированы в свойства объекта responseData. В операторе switch есть два варианта для сравнения с responseData.status. Если responseData.status эквивалентен строке 'error', то переменной klass будет присвоено 'response-error'. Если responseData.status эквивалентен строке 'success' , то переменной klass будет приисвоено значение 'response-success'. Теперь все готово к тому, чтобы вывести сообщение пользователю.
//Выводим сообщение ответа
responseMsg.fadeOut(200,function(){
$(this).removeClass('response-waiting')
.addClass(klass)
.text(responseData.message)
.fadeIn(200,function(){
//Устанавливаем таймаут для скрытия сообщения ответа
setTimeout(function(){
responseMsg.fadeOut(200,function(){
$(this).removeClass(klass);
});
},3000)
})
})
Первая задача, которую надо решить - погасить элемент сообщения, так как он содержит строку 'Пожалуйста, подождите ...'. Как только операция завершится, мы удаляем класс 'response-waiting', и добавляем либо класс 'error', либо класс 'success' , устанавливаем текст полученного от сервера сообщения, и снова выводим элемент сообщения. Все это выполняется в возвратной функции метода fadeOut(). Как только сообщение будет выведено на экран, мы устанавливаем таймер на 3 секунды чтобы убрать сообщение, потому что нам не нужно, чтобы оно висело вечно. убирается сообщение с экрана функцией обратным вызовом fadeIn().
Как вы можете видеть, мы широко используем возвратные функции jQuery. Таким образом гарантируется, что все выполняется в правильном порядке и в нужное время. Без использования возвратных функций синхронизация событий значительно усложнится.
На этом работа с Javascript закончена. Мы установили переменные и сообщение о статусе операции, передали данные через AJAX, получили ответ JSON, разобрали JSON, и вывели сообщение об успешности операции для пользователя. вот полный код Javascript:
$(document).ready(function(){
$('#newsletter-signup').submit(function(){
//Проверяем, не отправляется ли уже форма в текущий момент времени
if($(this).data('formstatus') !== 'submitting'){
//Устанавливаем переменные
var form = $(this),
formData = form.serialize(),
formUrl = form.attr('action'),
formMethod = form.attr('method'),
responseMsg = $('#signup-response');
//Добавляем дату к форме
form.data('formstatus','submitting');
//Показываем соообщение с просьбой подождать
responseMsg.hide()
.addClass('response-waiting')
.text('Пожалуйста, подождите...')
.fadeIn(200);
//Отправляем данные на сервер для проверки
$.ajax({
url: formUrl,
type: formMethod,
data: formData,
success:function(data){
//Устанавливаем переменные
var responseData = jQuery.parseJSON(data),
klass = '';
//Состояния ответа
switch(responseData.status){
case 'error':
klass = 'response-error';
break;
case 'success':
klass = 'response-success';
break;
}
//Показываем сообщение ответа
responseMsg.fadeOut(200,function(){
$(this).removeClass('response-waiting')
.addClass(klass)
.text(responseData.message)
.fadeIn(200,function(){
//Устанавливаем таймаут для скрытия сообщения ответа
setTimeout(function(){
responseMsg.fadeOut(200,function(){
$(this).removeClass(klass);
form.data('formstatus','idle');
});
},3000)
});
});
}
});
}
//Предотвращаем отправку формы
return false;
});
});
Шаг 8: Проверка на сервере
Теперь у нас есть готовый код HTML, и JavaScript готовый для отправки/получения данных. Нужно написать серверную часть кода для обраобтки переданных данных, и формирования ответа JSON для отправки обратно JavaScript. В рамках данного урока будем использовать PHP на серверной стороне.
if($_GET['action'] == 'signup'){
mysql_connect('localhost','ИМЯ_ПОЛЬЗОВАТЕЛЯ','ПАРОЛЬ');
mysql_select_db('БАЗА_ДАННЫХ_ДЛЯ _ХРАНЕНИЯ_ПОДПИСОК');
//Подчищаем данные
$email = mysql_real_escape_string($_POST['signup-email']);
//Выполняем операции
exit;
}
Здесь мы проверяем, если в строке запроса (мы используем массив $_GET) параметр action эквивалентен 'signup', то выполняем данный код. Это отличный способ инкапсулировать наш вызов AJAX. Сначала мы устанавливаем соединение с MySQL с помощью функции PHP mysql_connect(). Нужно задать имя хоста, имя пользователя базы данных и пароль. Ошибки будут проверяться далее по действию скрипта. Затем, мы выбираем базу данных с помощью функции mysql_select_db().
Затем мы получаем код доступа к базе данных. Здесь используется функция mysql_real_escape_string() для зачистки данных, передаваемых на сервер. Таким образом из данных исключается все, что может быть классифицировано как небезопасное. Так как мы передаем данные на сервер, то мы используем масиив $_POST для доступа к адресу. $_POST['signup-email'] позволяет получить адрес, и мы сохраняем его в переменной $email. Последняя строка кода - это выражение exit. Таким образом останавливается выполнение скрипта. Это нужно, если у нас есть много кода, а нужно выполнять лишь часть и игнорировать все остальное. Это важно для сохранения скорости вызова AJAX. Далее нам нужно проверить данные, чтобы не вставить в базу данных повторяющиеся записи.
//Проверяем адрес email
if(empty($email)){
$status = "error";
$message = "Вы не ввели адрес email!";
}
else if(!preg_match('/^[^\W][a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\@[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\.[a-zA-Z]{2,4}$/', $email)){ //validate email address - check if is a valid email address
$status = "error";
$message = "Вы ввели неправильный адрес email!";
}
else {
$existingSignup = mysql_query("SELECT * FROM signups WHERE signup_email_address='$email'");
if(mysql_num_rows($existingSignup) < 1){
//Вставляем данные в базу
}
else { //если пользователь уже подписан
$status = "error";
$message = "Данный адрес уже зарегистрирован!";
}
}
Нам нужно провести три проверки здесь:
Убедиться, что пользователь действительно передал адрес email
Убедиться, что переданный адрес e-mail - правильный
Убедиться, что переданный адрес e-mail еще не подисан
Мы используем серию выражений if. Первый if использует функцию PHP empty() для проверки того, что переменная $email действительно содержит что-то. Если переменная эквивалентна пустой строке, 0, '0', false или null, функция возвращает true (что соотвтетсвует пустой строке). Если мы имеем пустую строку, то мы устанавливаем переменной $status значение 'error' и переменной $messageзначение 'Вы не ввели адрес email!'. Если переменная не пустая, то далее следует проверка на правильность email адреса. Для этого используется функция PHP preg_match(). Мы передаем функции регулярное выражение (длинную строку с безумным набором символов) и наш адрес email. Если адрес email соответствует регулярному выражению, функция возвращает 1 (что эквивалентно true). Иначе функция возвращает 0 (что эквивалентно false). В нашем случае, если функция preg_match() возвращает false, то мы знаем, что адрес email неправильный; следовательно нужно установить значение 'error' переменной $status и переменной $message значение 'Вы ввели неправильный адрес email!'. Иначе мы можем перейти к следующей проверке, которая требует запроса к базе данных для проверки наличия в ней адреса email. Мы используем функцию PHP mysql_query(), которая принимает запрос SQL, запрашивает базу данных и возвращает данные. Нам не нужно ничего знать о данных, возвращаемых функцией mysql_query(), нам нужно только знать, сколько записей получено. Если функция возвратила более 0 записей, значит email адрес уже использовался для подписки, и нам нужно установить переменные $status и $message соответственно. Но если никаких записей не было найдено, то мы можем вставлять данные в базу.
Мы используем функцию PHP mysql_num_rows() для определения количества найденых запросом записей. Все что нужно -это передать функции переменную $existingSignup, в которой содержится результат выполнения запроса. Результат выполнения функции используется в выражении if для сравнения с 1.
Шаг 9: Вставляем данные в базу
После прохождения всех проверок данные должны быть вставлены в базу:
$date = date('Y-m-d');
$time = date('H:i:s');
$insertSignup = mysql_query("INSERT INTO signups (signup_email_address, signup_date, signup_time) VALUES ('$email','$date','$time')");
if($insertSignup){ //если вставка прошла успешно
$status = "success";
$message = "Вы подписаны!";
}
else { //если вставка прошла неудачно
$status = "error";
$message = "Ой! Произошла техническая ошибка!";
}
Сначала получаем текущую дату и время, форматируем их. А затем происходит вставка данных. Для этого используется функция mysql_query(), которой передается запрос SQL. Так как используется выражение SQL INSERT, функция возвращает true в случае успеха и false в случае неудачи. Остается только проверить возвращенной значение и установить значение переменных $status и $message соответственно. Мы не сообщаем пользователю о том, какая конкретно произошла ошибка. Таким образом сообщение об ошибке будет генерироваться и в случае проблем соединения с базой данных.
Шаг 10: Отсылаем обратно ответ
На предыдущем шаге определены две переменные: $status и $message. Значения этих переменных мы будем кодировать как JSON для отправки обратно пользователю. Переменные будут помещены в ассоциированный массив, таким образом мы зададим значащие имена ключам членов JSON.
$data = array(
'status' => $status,
'message' => $message
);
Не обязательно записывать ассоциированный массив подобным образом, в рамках урока так нагляднее. Теперь нужно передать массив функции PHP json_encode(). Таким образом ассоциированный массив конвертируется в форматированную строку JSON. Затем она возвращается обратно браузеру, с помощью использования echo.
echo json_encode($data);
Серверная часть кода завершена. Код должен выглядеть следующим образом:
//Вызов ajax signup
if($_GET['action'] == 'signup'){
mysql_connect('localhost','ИМЯ_ПОЛЬЗОВАТЕЛЯ','ПАРОЛЬ');
mysql_select_db('БАЗА_ДАННЫХ_ДЛЯ _ХРАНЕНИЯ_ПОДПИСОК');
//Подчищаем данные
$email = mysql_real_escape_string($_POST['signup-email']);
//Проверяем адрес email
if(empty($email)){
$status = "error";
$message = "Вы не ввели адрес email!";
}
else if(!preg_match('/^[^\W][a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\@[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\.[a-zA-Z]{2,4}$/', $email)){ //validate email address - check if is a valid email address
$status = "error";
$message = "Вы ввели неправильный адрес email!";
}
else {
$existingSignup = mysql_query("SELECT * FROM signups WHERE signup_email_address='$email'");
if(mysql_num_rows($existingSignup) < 1){
$date = date('Y-m-d');
$time = date('H:i:s');
$insertSignup = mysql_query("INSERT INTO signups (signup_email_address, signup_date, signup_time) VALUES ('$email','$date','$time')");
if($insertSignup){ //если вставка прошла успешно
$status = "success";
$message = "Вы подписаны!";
}
else { //если вставка прошла неудачно
$status = "error";
$message = "Ой! Произошла техническая ошибка!";
}
}
else { //если пользователь уже подписан
$status = "error";
$message = "Данный адрес уже зарегистрирован!";
}
}
//возвращаем ответ json
$data = array(
'status' => $status,
'message' => $message
);
echo json_encode($data);
exit;
}
Здесь представлен весь код, который нужен для работы формы подписки.
Хотя наш код работает и форма делает то что нужно, необходимо еще кое-что улучшить в нашей форме.
Если пользователь нажмет кнопку "Подписаться" еще раз до того, как запрос AJAX завершится, мы получим прелестный сбой алгоритма. Элемент сообщения будет включаться выключаться, но таймаут не будет сбрасываться. Это выглядит глупо и генерирует ненужные запросы к серверу. В действительности нужно предотвратить отправку формы, пока не завершилось выполнение текущего процесса.
Шаг 11: Останавливаем множественную отправку формы
Предотвратить множественную отправку формы очень просто. Все, что нужно - это проверить статус формы в момент отправки. Для этого мы сохраняем статус формы с помощью функции jQuery data(). Данная функция позволяет сохранять и получать произвольные данные ассоциированные с соответствующим элементом в формате ключ-значение. Мы используем ключ 'formstatus', а его значение может быть 'submitting' или 'idle'. Если 'formstatus' эквивалентен 'submitting', то форма не будет отправляться. Как только форма отправляется, нужно установить 'formstatus' значение 'submitting'. А когда процесс завершится, установим 'formstatus' значение 'idle'. Вот наш законченный код JavaScript.
$(document).ready(function(){
$('#newsletter-signup').submit(function(){
//Проверяем, не отправляется ли уже форма в текущий момент времени
if($(this).data('formstatus') !== 'submitting'){
//Устанавливаем переменные
var form = $(this),
formData = form.serialize(),
formUrl = form.attr('action'),
formMethod = form.attr('method'),
responseMsg = $('#signup-response');
//Устанавливаем статус формы
form.data('formstatus','submitting');
//Показываем соообщение с просьбой подождать
responseMsg.hide()
.addClass('response-waiting')
.text('Пожалуйста, подождите...')
.fadeIn(200);
//Отправляем данные на сервер для проверки
$.ajax({
url: formUrl,
type: formMethod,
data: formData,
success:function(data){
//Устанавливаем переменные
var responseData = jQuery.parseJSON(data),
klass = '';
//Состояния ответа
switch(responseData.status){
case 'error':
klass = 'response-error';
break;
case 'success':
klass = 'response-success';
break;
}
//Показываем сообщение ответа
responseMsg.fadeOut(200,function(){
$(this).removeClass('response-waiting')
.addClass(klass)
.text(responseData.message)
.fadeIn(200,function(){
//Устанавливаем таймаут для скрытия сообщения ответа
setTimeout(function(){
responseMsg.fadeOut(200,function(){
$(this).removeClass(klass);
form.data('formstatus','idle');
});
},3000)
});
});
}
});
}
//Предотвращаем отправку формы
return false;
});
});
Готово!