В прошлой статье речь шла о проверке данных форм с помощью стандартной библиотеки фрэймворка CodeIgniter. Мы рассмотрели основные возможности библиотеки, создали страницу с формой и написали необходимый для ее проверки код.
Сегодня мы посмотрим, как решить эту же задачу без перезагрузки страницы с формой. Естественно будет использоваться технология ajax.
Давайте немного порассуждаем. Чем отличается ajax запрос от обычного запроса?
1) Ajax запрос можно выполнить только с помощью JavaScript.
2) Ответом сервера на обычный запрос должна быть html страница, а на ajax запрос – фрагмент данных (с разметкой или без нее).
Отсюда вывод. Чтобы добавить поддержку ajax нужно в клиентской части написать JavaScript функцию, которая прочтет данные из формы, отправит запрос и обработает ответ сервера, а в серверной части – изменить возвращаемые значения.
Примечание. Чтобы немного упростить себе жизнь, мы будем использовать библиотеку prototype для отправки запросов и обновления страницы.
Переходим к нашему примеру. Как вы помните, в прошлый раз мы создали форму с тремя полями для ввода личных данных пользователя (ник, полное имя, адрес email).
В этот раз мы используем эту же форму, только немного изменим html разметку.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"> <html xmlns="http://www.w3.org/1999/xhtml" lang="ru"> <head> <title>Проверка введенных данных</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="<?php echo base_url(); ?>prototype.js"></script> <script type="text/javascript" src="<?php echo base_url(); ?>scripts.js"></script> </head> <body> <?php echo form_open('#'); ?> <div id="status"></div> <div id="nic_err"></div> <p>Ник: <input type="text" name="usernic" id="usernic" value="" /></p> <div id="name_err"></div> <p>Полное имя: <input type="text" name="fullname" id="fullname" value="" /></p> <div id="email_err"></div> <p>eMail: <input type="text" name="usermail" id="usermail" value="" /></p> <p><input type="button" id="sendbtn" value="Отправить" onclick="sendData(<?php echo "'".base_url()."'"; ?>)" /></p> </form> </body> </html>
Прежде всего, перед каждым полем мы добавили блоки для отображения сообщений об ошибках (теги <div> в строках …). Сами сообщения мы будет вставлять с помощью JS.
Второе изменение коснулось кнопки «Отправить». Теперь она имеет тип button
, а не submit
и обработчик события onclick
, который вызывает функцию отправки данных (sendData
).
Сама функция sendData
находится в файле scripts.js
, который мы подключили в заголовке страницы вместе с библиотекой prototype (строки 6, 7).
Прежде чем, переходить к отправке сообщения необходимо определиться с форматом данных, в котором мы будем получать результаты обработки.
С отправкой данных все довольно просто. Нужно сформировать строку с параметрами обычного POST запроса.
А вот формат результатов обработки гораздо интереснее. Страница нашей формой содержит четыре блока, в которые могут быть вставлены описания ошибок. Удобнее всего вставлять эти данные, если содержимое каждого из полей находится в отдельных переменных (ячейках массива или структуре).
Т.е. нам нужно получить данные в формате, который мы сможем легко преобразовать в набор переменных. Идеально для этой цели подходит JSON.
Примечание. Подробнее почитать об этом формате можно в статье «Передача данных с помощью JSON».
Главное преимущество заключается в том, что и JavaScript и PHP содержат функции для преобразования данных в этот формат и обратно.
Таким образом, наша функция sendData
будет примет такой вид.
function sendData(baseURL) { //читаем данные из формы var n = $('usernic').value; var fn = $('fullname').value; var e = $('usermail').value; //формируем строку с параметрами запроса var pars = $H({usernic:n, fullname:fn, usermail:e}).toQueryString(); //отправляем ajax запрос new Ajax.Request(baseURL + "index.php/main/checkdata_ajax", {method:"post", parameters:pars, onSuccess:parseResponse}); }
В параметре функции мы передаем адрес сервера. А в строках с 3-7 мы формируем строку с параметрами.
После этого мы отправляем запрос. Ответ сервера передается функции parseResponse
, которая указана в параметре onSuccess
запроса.
Теперь рассмотрим функцию parseResponse
.
function parseResponse(transport) { var data = eval('(' + transport.responseText + ')'); //ошибок не было if (data.status == "OK") { $('status').innerHTML = "Данные сохранены"; //убираем сообщение об ошибках, если они остались после //предыдущей попытки $('nic_err').innerHTML = ""; $('name_err').innerHTML = ""; $('email_err').innerHTML = ""; } //ошибки были, показываем их описание else { $('status').innerHTML = "Пожалуйста, проверьте введенные данные"; $('nic_err').innerHTML = data.nic_err; $('name_err').innerHTML = data.name_err; $('email_err').innerHTML = data.email_err; } }
Во второй строке мы преобразуем строку в формате JSON в структуру данных с именем data
(с помощью функции eval
).
Наша структура данных имеет такие поля:
status
– результат обработки (может принимать два значения: «OK» и «ERR»);
nic_err
– описание ошибки в поле «ник»;
name_err
– описание ошибки в поле «полное имя»;
email_err
– описание ошибки в поле «email».
В строке 4 мы проверяем поле data.status
и в зависимости от результатов либо вставляем описание ошибок, либо убираем их.
Теперь рассмотрим серверный скрипт (checkdata_ajax
), который должен находится внутри контроллера (main.php).
function checkdata_ajax() { $this->load->library('validation'); $rules['usernic'] = "required|min_length[3]|checknic"; $rules['fullname'] = "required"; $rules['usermail'] = "required|valid_email"; $this->validation->set_rules($rules); $fields['usernic'] = "ник"; $fields['fullname'] = "полное имя"; $fields['usermail'] = "адрес email"; $this->validation->set_fields($fields); if ($this->validation->run() == TRUE) { //сохраняем введенные данные (например, в БД) //.......... //отправляем браузеру результаты обработки $res['status'] = "OK"; } else { $res['status'] = "ERR"; $res['nic_err'] = $this->validation->usernic_error; $res['name_err'] = $this->validation->fullname_error; $res['email_err'] = $this->validation->usermail_error; } echo json_encode($res); }
Первая часть метода не изменилась. Действительно, данные приходят в параметрах POST запроса и серверному скрипту без разницы как этот запрос отправлен.
Отличие от предыдущего примера заключается в том, что в этот раз мы не отправляем браузеру страницу, а формируем массив с результатами обработки, преобразовываем его в формат JSON и отправляем браузеру.
Примечание. На основе имен ключей в массиве будет создаваться структура данных в функции parseResponse
.
Как видите, добавление поддержки ajax не требует значительных усилий. В чем-то она даже проще классического варианта. Например, нам не нужно заполнять поля формы предыдущими значениями, т.к. введенные значения никуда не денутся (ведь мы все время находимся на одной и той же странице). Главный недостаток – это необходимость написания JavaScript кода, который может быть довольно сложным.