среда, 20 декабря 2006 г.

Редактирование на месте при помощи Ajax и Prototypes

В этой статье я покажу вам как использовать популярный файл Prototype.js чтобы использовать Ajax-технику, называемую "редактирование на месте", но для начала, давайте подробно рассмотрем саму технику. Редактирование на месте, как и множество других Ajax функций, использует XmlHttpRequest объект для того чтобы вызвать внешнюю страницу, отправить и получить от нее информацию. Первым делом я познакомлю вас с архитектурой этого приложения. Т.к. мы используем базу данных и PHP для создания слоя обмена данными, начнем так:

Самый первый слой - MysqlDB класс, который содержите необходимые методя для работы с базой данных. В то время как наша статья ставит основной целью объяснение техники редактирования на месте, и, в частности, использование Ajax, мы сконцентрируем наше внимание на brains.php, который содержит Ajax_Interface PHP класс (который, как вы могли уже заметить, наследет MysqlDB класс). На верхнем уровне происходит вызов index.php, который включает в себя brains.php, а так же functions.js и prototype.js. Когда brains.php включается в файле index.php, происходит инициализация методов, которые теперь могут быть использованы в index.php.

Давайте продолжим, обращая наше внимание на следующие PHP файлы: Ajax_Interface.php и brains.php. Вообще в этом приложении я решил не пользоваться классами. Для начана взглянем на функцию print_records() - она устанавливает значения для страницы после загрузки, показывая что сейчас хранится в базе данных.

function print_records() {

$this->get_records();
$products = $this->rs;
$id = $products['product_id'];
$name = $products['name'];

do {
$id = $products['product_id'];
$name = $products['name'];
$field = 'field_'.$id;

echo '<input type="text" name"?" id="'.$id.'" value="'.$name.'"
onClick="changeClass(\''.$id.'\', \'show\')"
onBlur="changeClass(\''.$id.'\', 'hide\')"
onKeyPress="checkLength(this)" class="text" maxlength="60" readonly />';
echo "\n";
} while ($products = $this->fetch_array($this->result));
}


Здесь мы использовали цикл чтобы выывести каждую строку из базы данных.Обратите внимение, что события onBlur и onClick - это основа нашей техники. Когда происходит событие onClick функция изменяет текст на поле для ввода (changeClass). Событие onBlur заканчивает процесс обновления текста, используя ту же самую функцию. Давайте взглянем на changeClass:

function changeClass(id, action) {
if (action=="hide") {
$(id).className = "text";
save(id);
} else {
$('status').innerHTML ='';
$(id).className = "input";
$(id).readOnly = false;
}
}


Нажимая на тексте, мы изменяем CSS класс и получаем поле для ввода. Когда мы теряем фокус (событие onBlur), мы переключаем наше поле обратно в не-редактируемому виду. Обратите внимание на функцию save(), которая вызывается после того как произошло событие onBlur:

function save(id){
var new_content = $F(id);
var success = function(t){
$('ddiv').innerHTML = t.responseText + 'supposed to be here';
}
var failure = function(t){ alert('update failed'); }
var url = 'http://localhost/ajax/prototype/include/brains.php';
var pars = 'edit=go&content='+new_content+'&product_id='+id;

var myAjax = new Ajax.Request(
url,
{
method: 'get',
parameters: pars,
onComplete: update_page
} );
}


Обратите внимание на функции S() и $F(). Эти функции служат для более короткого и удобного обращения к элементам DOM. Если вы не еще не знакомы с этими функциями и хотите больше узнать о возможностях Prototype.js, рекомендую прочитать основы работы с Prototypes на русском или ознакомиться с документацией по этой библиотеке.

Теперь давайте взглянем на переменные url и parts. Url - адрес, который будет вызван, parts - параметры, переданные по этому адресу. После создания Ajax-запроса (функция из Prototypes), мы устанавливаем для события onComplete функцию, которая вызовет обновление страницы. Давайте глянем как будет обработан наш запрос со стороны PHP:

if ($_GET['edit'] == 'go')  {
$result = $ai->save();
header('Content-Type: text/xml');
// создаем XML заголовок
echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
echo "<response>";
echo $result;
echo "</response>";
}


Когда мы получаем уведомление о необходимости изменить данные через $_GET переменную, мы вызываем метод $ai->save(). Этот метод просто получает текущий элемент для редактирования и обновляет базу данных на основе данных, полученных из вызова объекта XmlHttpRequest. Затем мы возвращаем данные полученные из базы данных в виде xml:

function save() {
$query = 'update product SET name="'.$_GET['content'].'"
where product_id = '.$_GET['product_id'].' LIMIT 1';

$this->query($query);
$output = '<pID>'.$_GET['product_id'].'</pID>.
<value>'.$_GET['content'].'</value>';

return $output;
}


Последнее, что я хотел бы вам показать - как происходит обновление div-а, который будет содержать обновленную информацию из базы данных:

function update_page(originalRequest) {
var rXML = originalRequest.responseXML;
var pIDs = rXML.getElementsByTagName('pID').item(0);
var pID = pIDs.firstChild.data;

//предупреждаем('i have ' + pID + ' to update');
var values = rXML.getElementsByTagName('value').item(0);
var value = values.firstChild.data;
//предупреждаем('i have ' + value + 'as a return value');

$(pID).innerHTML = value;
$('status').innerHTML = 'update complete';
}


Первым делом я разделил xml информацию по названиям нод. Я так же обновил div, который при первой загрузке страницы был пустым (div select), для того, чтобы вы могли увидеть текст "обновление завершено" после завершения обновления. Но самое главное - я обновил содержание измененного элемента.

Скачать полный исходный код примера.

Оригинал: phpbuilder.com

3 комментария:

Unknown комментирует...

не плохая библиотека, но я сней мало работал но точно знаю, что когда состоится релиз нашего сайта то на ней будет интерактивная карта полностью написанная на ajax технологии (оная в стадии тестирования).

Анонимный комментирует...

Всё очень интиресно НО - скачал ваши файлы, постаавил, всё ок - работает, но не пишет! В инпуте инфу ввожу - фокус теряю, инпут становится просто текстом, но в базу запись не происходит! :(

В чём может быть проблема?

Анонимный комментирует...

Этот код в обще отсутствует в файлах котоыре лежат в архиве:


function save(id){
var new_content = $F(id);
var success = function(t){
$('ddiv').innerHTML = t.responseText + 'supposed to be here';
}
var failure = function(t){ alert('update failed'); }
var url = 'http://localhost/ajax/prototype/include/brains.php';
var pars = 'edit=go&content='+new_content+'&product_id='+id;

var myAjax = new Ajax.Request(
url,
{
method: 'get',
parameters: pars,
onComplete: update_page
} );
}