CodeIgniter + AJAX. Проверка данных форм без перезагрузки страниц

Владимир | | Ajax, CodeIgniter, PHP.

Проверка данных форм (Ajax)
В прошлой статье речь шла о проверке данных форм с помощью стандартной библиотеки фрэймворка 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 кода, который может быть довольно сложным.