Разработка web приложений. Как сделать редактор списка в стиле Web 2.0 (добавление новых записей)

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

Скриншот WebListEditor
Это третья часть цикла статей о создании web приложения, использующего технологию Ajax для редактирования списка.
В прошлых частях мы разобрали общую структуру приложения, работу с базой данных и структуру его основной страницы.

Примечание. Вы можете посмотреть демонстрационную версию редактора или скачать архив с файлами проекта.

Как вы, наверное, помните, внизу страницы размещена форма добавления новых записей в список. Разберем подробнее как реализовано создание новых записей.

Когда посетитель нажимает кнопку «Добавить», выполняется вызов функции addItem(), размещенной в файле tasks.js. Посмотрите на ее код:

function addItem() {
	//читаем введенное в форму значение
	var v = $('item_value').value;
	//формируем строку с параметрами запроса
	var pars = $H({value:v}).toQueryString();
	//выполняем запрос
	new Ajax.Request(
		"scripts/additem.php",
		{method:"post", parameters:pars, onSuccess:parseAddItemResponse}
	);
}


В строках 3 и 5 мы читаем текст, введенный в текстовое поле, и формируем строку с запроса. Код получился предельно короткий за счет использования библиотеки Prototype.

После этого выполняем Ajax запрос с помощью функции Request() объекта Ajax. В первом параметре этой функции мы указываем имя скрипта, который добавляет запись в БД. А во втором – параметры запроса:
method – метод отправки запроса;
parameters – сформированный ранее массив с параметрами (в данном случае, параметр только один – текст записи);
onSuccess – имя функции, которая будет вызвана после получения ответа от серверного скрипта.

Работу этой функции стоит разобрать подробнее, но вначале посмотрим, как работает additem.php.

require_once("dbdata.php");

$value = null;
$value = $_POST['value'];
$results = array();
if ($value != null && $value != "") {
	$value = htmlspecialchars($value);
	//добавляем запись в БД
	$con = connect();
	$addQuery = sprintf("INSERT INTO listitems(item) VALUES('%s')",
						mysql_real_escape_string($value));
	if (mysql_query($addQuery)) {
		$results['id'] = mysql_insert_id();
		$results['value'] = $value;
	}
	else {
		$results['error_mes'] = "Не могу добавить запись: ".mysql_error();
	}
}
else {
	$results['error_mes'] = 'Не задано значение записи';
}
if ($con != null) {
	mysql_close($con);
}
echo json_encode($results);

В строках 4,5 мы получаем текст записи из массива $_POST, и начинаем формировать массив с результатами.
Если в процессе работы скрипта возникают ошибки, мы создаем в массиве $results элемент error_mes и присваиваем ему описание ошибки.

После проверки текста записи мы с помощью функции htmlspecialchars преобразуем все специальные символы html в соответствующие эскейп последовательности. Эта простая операция позволяет сохранить дизайн страницы в нормальном состоянии 🙂 .

После этого, мы подключаемся к БД (строка 9) и формируем запрос. Для предотвращения SQL Injection используется функция mysql_real_escape_string.

Если запрос выполнен успешно, получаем id добавленной записи (функция mysql_insert_id) и формируем массив с результатами.

Перед отправкой результата мы преобразуем его в формат JSON (строка 26).

Примечание. Об использовании этого формата можно почитать в статьях Передача данных с помощью JSON и Использование JSON в web приложениях.

Теперь, когда с серверной частью разобрались, возвращаемся к функции parseAddItemResponse. Напомню, она вызывается автоматически после получения ответа от сервера.

function parseAddItemResponse(transport) {
	var data = eval('(' + transport.responseText + ')');
	//проверяем были ли ошибки
	if (data.error_mes == null) {
		//удаляем сообщение об ошибке (если оно осталось после
		//предыдущего вызова)
		var errMes = $('err_mes');
		if (errMes != null) {
			Element.remove(errMes);
		}
		//удаляем строку "нет записей" (если она есть)
		var noItems = $('noItems');
		if (noItems != null) {
			Element.remove(noItems);
		}
		//вставляем полученный результат в конец списка
		var list = $('list');
		if (list == null) {
			var content = $('content');
			var newItem = new Insertion.Bottom(content, "<ul id=\"list\"></ul>");
			list = $('list');
		}
		//вставляем новый элемент в конец списка
		new Insertion.Bottom(list,
			"<li id='listNum_" + (editors.length) + "'><div class='itemNum'>" +
			(editors.length + 1) + "</div>" +
			"<div class='itemValue' " +
			"onclick='closeOtherEditors(" + editors.length +
			")' id='itemId_" + data.id + "'>" +
			data.value + "</div>" +
			"<a href='#' class='deleteLink' onclick='deleteItem(" +
			data.id + ")'><img src='css/images/delete.gif'" +
			"alt='Удалить' title='Удалить' /></a></li>");
		//создаем редактор для нового элемента и добавляем его в массив
		editors.push(addEditor("itemId_" + data.id, data.id));
		//подсвечиваем вставленный элемент
		var items = $$('#list li');
		new Effect.Highlight(items.last(),
			{startcolor:"#FDFFB9", endcolor:"#FFFFFF", duration:2.0});
	}
	else {
		//выводим сообщение об ошибке
		var form = $('add_item_form');
		new Insertion.After(form, "<div id=\"err_mes\">" +
			data.error_mes + "</div>");
	}
}

В параметре transport передается ответ сервера. С помощью функции eval() мы преобразуем строку с результатами в массив.

В строке 4 выполняем проверку на наличие ошибок, и если они были, выводим их описание (строки 41-46).

Если запись была успешно добавлена, начинаем формировать список с результатами. Прежде всего, удаляем сообщение об ошибке, если оно осталось после предыдущего вызова (строки 7-10). Затем создаем список, если он еще не создан (строки 17-22). После этого вставляем новый элемент внутрь списка (строки 24-33).

Естественно, при вставке нового элемента в список, мы должны сформировать такую же разметку, как и в файле index.php. Для определения порядкового номера элемента в списке мы используем параметр length массива editors, т.к. его длина всегда совпадает с количеством элементов в списке.

Добавление новых элементов на страницу выполняется функцией Insertion.Bottom(), которая вставляет текст, указанный во втором параметре, в конец элемента, заданного в первом параметре.

Удаление выполняем с помощью функции Element.remove(), которая удаляет элемент, указанный в ее первом параметре.

В строке 35 создаем встраиваемый редактор для нового элемента и добавляем его в массив editors.
После этого подсвечиваем вставленный элемент (строки 38, 39).

Подведем промежуточный итог. Добавление новой записи осуществляется в следующем порядке:
1) функция addItem() выполняет Ajax запрос;
2) скрипт additem.php принимает этот запрос и добавляет запись в БД;
3) функция parseAddItemResponse добавляет созданную запись на страницу.

В следующий раз мы рассмотрим редактирование существующих записей списка.

Интересно почитать

Владивосток авто предлагает новые автомобили по доступным ценам
Продажа дачных участков в подмосковье — быстрый способ заработать
Успешная карьера — залог хорошего настроения

  • мило…

  • мило…

  • hyperion

    спасибо! статья очень помогла!

  • hyperion

    спасибо! статья очень помогла!

  • Jelena

    Ja ne mogu ponjat' v 4em oshibka, no pri dobavlenii zapisi ona avtomati4eski ne pojavljaetsja. Tol'ko esli vru4nuju sdelat' refresh:(

    • Запись не появляется на демонстрационном сайте? Я только что проверил. Вроде все нормально.
      Каким браузером вы пользуетесь?

  • Jelena

    Ja ne mogu ponjat' v 4em oshibka, no pri dobavlenii zapisi ona avtomati4eski ne pojavljaetsja. Tol'ko esli vru4nuju sdelat' refresh:(

    • Запись не появляется на демонстрационном сайте? Я только что проверил. Вроде все нормально.
      Каким браузером вы пользуетесь?

  • Огромная и продуманная подборка видео, в которой все могут сохранить себе порно видео на свой вкус. Темы видео разнообразные и порадуют даже самый притязательный вкус.

  • Огромная и продуманная подборка видео, в которой все могут сохранить себе порно видео на свой вкус. Темы видео разнообразные и порадуют даже самый притязательный вкус.

  • NoviceCoder

    Подскажите, а как реализовать вместо появления записи, появление выпадающего списка, и лишь после выбора одного из значений, добавление этого значения в базу?

    • В одном из видеороликов на официальном сайте CodeIgniter приведен такой пример. Правда там решена обратная задача, т.е. в выпадающий список вставляются данные из БД, но код будет очень похожий.
      Вам нужно:
      1) разместить на странице выпадающий список
      2) при возникновении события onclick на элементе списка отправлять ajax запрос php скрипту, который будет сохранять данные
      3) после получения ответа обновить страницу

      • NoviceCoder

        Огромное спасибо, теперь ясно в каком направлении двигаться.

  • NoviceCoder

    Подскажите, а как реализовать вместо появления записи, появление выпадающего списка, и лишь после выбора одного из значений, добавление этого значения в базу?

    • В одном из видеороликов на официальном сайте CodeIgniter приведен такой пример. Правда там решена обратная задача, т.е. в выпадающий список вставляются данные из БД, но код будет очень похожий.
      Вам нужно:
      1) разместить на странице выпадающий список
      2) при возникновении события onclick на элементе списка отправлять ajax запрос php скрипту, который будет сохранять данные
      3) после получения ответа обновить страницу

      • NoviceCoder

        Огромное спасибо, теперь ясно в каком направлении двигаться.

  • Для Вас музыкальные сайты,музыкальные сайты,небывалый музыкальный сайт,музыкальные новинки.

  • Для Вас музыкальные сайты,музыкальные сайты,небывалый музыкальный сайт,музыкальные новинки.

  • B2B Portal fuer b2b Germany.Erweiterten Sie Ihre Einkaufsquellen oder finden Sie Ihre neue Marktplaetze.

  • B2B Portal fuer b2b Germany.Erweiterten Sie Ihre Einkaufsquellen oder finden Sie Ihre neue Marktplaetze.

  • Дизайнер интерьера предлагает авторский дизайн интерьера в КиевеЭлитная студия дизайна интерьера и её опытный дизайнер-декоратор реализует авторский дизайн интерьера коттеджей Киев, сотворив уютный дом

  • Дизайнер интерьера предлагает авторский дизайн интерьера в КиевеЭлитная студия дизайна интерьера и её опытный дизайнер-декоратор реализует авторский дизайн интерьера коттеджей Киев, сотворив уютный дом

  • Sashatkachuk95

    Подскажите пожалуста!
    Как сделать так, что бы есле я поставил в текстареи (поле куда вводить текст) энтер, то и в блоке где выводится надпись он появился.
    вот так :
    Тест
    Тест

  • 1) Добавить к тексту тег pre

    2) Заменить перенос строки на тег br

  • Sashatkachuk95

    Вставлять в форму (в браузере)?

  • Sashatkachuk95

    если так, то ничего не поменялось
    http://radikal.ru/F/s42.radikal.ru/i097/1008/1c

  • Правильно, в моем примере ничего не поменяется, т.к. все спец. символы экранируются. Поэтому вы видите теги вместо форматированного текста.

    Я имел ввиду, что нужно к тексту, полученному из БД добавить теги pre. Причем делать это не обязательно на сервере, можно и с помощью JS.

    Например, рассмотрим добавление новой записи (последний листинг в этой статье). Замените в строке 30
    data.value
    на
    '< pre>' + data.value + '< /pre>'

  • Sashatkachuk95

    Удалось сделать задуманное по вашим рекомендациям. Спасибо.
    А не подскажите как сделать так, что бы при редактировании текста выводилось не инпут а текстареа?

  • Sashatkachuk95

    И сразу ещё вопрос. Как сделать так, что бы первые 2 записи выводились в один столбик, а другие 2 во второй?

  • Sashatkachuk95

    И сразу ещё вопрос. Как сделать так, что бы первые 2 записи выводились в один столбик, а другие 2 во второй?

  • Нужно указать это в настройках при создании встроенного редактора.

    Ajax.InPlaceEditor(…, {rows:15,cols:40});

    Посмотреть список параметров можно здесь.

  • Наверное, вы имели ввиду в одну строку. Но в любом случае, нужно менять разметку.
    В этом примере для вывода записей используется список (теги li), вам, наверное, лучше всего подойдет таблица.