На этом шаге мы рассмотрим способ изменения адреса доставки.
На странице, имитирующей корзину с покупками, кроме всего прочего присутствует форма ввода адреса доставки. Фактически на момент загрузки страницы это вообще не форма, и без поддержки JavaScript она остается небольшим прямоугольником (рисунок 1), спрятанным с правой стороны области содержимого страницы и содержащим ссылку на страницу, где пользователь сможет отредактировать адрес доставки.
Но при наличии поддержки JavaScript и с использованием всей мощи библиотеки jQuery, имеющейся в нашем распоряжении, мы можем превратить такую маленькую ссылку в полноценную форму. Мы сделаем это, запросив форму из страницы РНР. Обычно данные, которыми заполняется форма, сохраняются в базе данных, но исключительно в демонстрационных целях мы будем хранить некоторые статические данные непосредственно в массиве РНР.
Чтобы воспроизвести форму внутри области с заголовком Доставить по адресу, мы использовали метод $.get() внутри обработчика события .click():
$(document).ready(function() { $('#shipping-name').click(function() { $.get('../cgi-bin/shipping.php', function(data) { $('#shipping-name').remove(); $(data).hide().appendTo('#shipping').slideDown(); }); return false; }); });
При вызове методом $.get(), прежде чем вывести большую часть страницы, сценарий РНР (shipping.php) на стороне сервера проверяет наличие переменной $_SERVER['HTTP_X_REQUESTED_WITH'], и в случае ее отсутствия возвращает только часть страницы - саму форму.
Внутри функции обратного вызова, которая передается методу $.get(), мы удаляем имя, на котором только что был выполнен щелчок, и на его место вставляем форму с данными, полученную от сценария shipping.php. Чтобы предотвратить действие по умолчанию (загрузку страницы, указанной в атрибуте href), предусмотренное для обработки щелчка на ссылке, мы добавили инструкцию return false. После этого область с заголовком Доставить по адресу превращается в форму, доступную для редактирования, как показано на рисунке 1 (щелкните по ссылке).
Теперь пользователь может отредактировать адрес доставки, не покидая страницу.
Следующий шаг - отправка формы и доставка отредактированных данных обратно на сервер с помощью jQuery. Мы начнем с сериализации данных, присутствующих в форме, и сохранения результата в переменной postData. Затем мы отправим данные на сервер, еще раз воспользовавшись сценарием shipping.php:
$(document).ready(function() { $('shipping form').submit(function() { var postData = $(this).serialize(); $.post('shipping.php', postData); return false; }; });
В данный момент есть смысл удалить форму из страницы и вернуть область с заголовком Доставить по адресу в начальное состояние. Это можно реализовать внутри функции обратного вызова, которая передается только что использованному методу $.post():
$(document).ready(function() { $('shipping form').submit(function() { var postData = $(this).serialize(); $.post('shipping.php', postData, function(data) { $('#shipping form').remove(); $(data).appendTo('#shipping'); }); return false; }; });
Но она не работает! Дело в том, что в нашей реализации мы подключили обработчик события .submit() к форме Доставить по адресу сразу же после загрузки дерева DOM, но форма не будет включена в дерево DOM, пока пользователь не щелкнет на имени в ссылке Доставить по адресу. Событие не может быть подключено к тому, чего не существует.
Для преодоления этой проблемы можно поместить программный код, создающий форму, в функцию с именем editShipping(), а реализацию отправки формы и ее удаления - в функцию с именем saveShipping(). Тогда мы сможем использовать функцию saveShipping() в функции обратного вызова метода $.get() уже после того, как форма будет создана. Точно так же можно выполнить привязку функции editShipping() сразу же после создания дерева DOM и после повторного создания ссылки Редактировать адрес доставки в функции обратного вызова метода $.post():
$(document).ready(function() { var editShipping = function() { $.get('shipping.php', function(data) { $('#shipping-name').remove(); $(data).hide().appendTo('#shipping').slideDown(); $('#shipping form').submit(saveShipping); }); return false; }; var saveShipping = function() { var postData = $(this).serialize() + '&op=Save'; $.post('shipping.php', postData, function(data) { $('#shipping form').remove(); $(data).appendTo('#shipping'); $('#shipping-name').click(editShipping); }); return false; }; $('#shipping-name').click(editShipping); });
Рис.1. Окончательная версия
Полный текст этого примера можно взять здесь.Этот программный код образован с применением шаблона циклических ссылок, в котором две функции позволяют друг другу повторно подключать себя в качестве соответствующих обработчиков событий.
На следующем шаге мы приведем окончательную версию приложения.