<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JSToolbox - все о JavaScript &#187; AJAX</title>
	<atom:link href="http://www.jstoolbox.com/category/ajax/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jstoolbox.com</link>
	<description>Блог о программировании вообще и о JavaScript в частности, уроки, статьи, заметки, база знаний.</description>
	<lastBuildDate>Wed, 28 Jul 2010 22:33:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Реализация бесконечной прокрутки на jQuery</title>
		<link>http://www.jstoolbox.com/2009/04/18/realizaciya-beskonechnoj-prokrutki-na-jquery/</link>
		<comments>http://www.jstoolbox.com/2009/04/18/realizaciya-beskonechnoj-prokrutki-na-jquery/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 21:44:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[бесконечная прокрутка]]></category>
		<category><![CDATA[юзабилити]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=428</guid>
		<description><![CDATA[<p>Всем вам должны быть хорошо известны интерфейсы просмотра лент новостей, записей блогов, в которых новые записи подгружаются по мере чтения. Новые данные подгружаются в тот момент, когда полоса прокрутки достигает самого низа. Хорошим примером такого интерфейса является <a href="http://reader.google.com" rel="nofollow">Google Reader</a>, а также сайт <a href="http://dzone.com" rel="nofollow">DZone</a>. Сегодня я покажу, как можно сделать такой интерфейс при помощи jQuery. Приложение будет имитировать работу блога, в котором при загрузке страницы, посредством AJAX будут загружаться первые 10 записей, а остальные будут подгружаться по мере чтения.</p>]]></description>
			<content:encoded><![CDATA[<p>Всем вам должны быть хорошо известны интерфейсы просмотра лент новостей, записей блогов, в которых новые записи подгружаются по мере чтения. Новые данные подгружаются в тот момент, когда полоса прокрутки достигает самого низа. Хорошим примером такого интерфейса является <a href="http://reader.google.com" rel="nofollow">Google Reader</a>, а также сайт <a href="http://dzone.com" rel="nofollow">DZone</a>. Сегодня я покажу, как можно сделать такой интерфейс при помощи jQuery. Приложение будет имитировать работу блога, в котором при загрузке страницы, посредством AJAX будут загружаться первые 10 записей, а остальные будут подгружаться по мере чтения.</p>
<p><span id="more-428"></span><br />
<br/></p>
<p>Начнем с создания простой HTML страницы, в теле которой имеется всего лишь один <em>div</em> &#8211; в него будут подгружаться записи. В этот div добавим элемент <em>&lt;div id=&#8221;loader&#8221;&gt;</em>, для того, чтобы использовать его как индикатора ожидания.</p>
<pre class="prettyprint">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
&lt;html>
&lt;head>
	&lt;script type="text/javascript" src="jquery.js">&lt;/script>

	&lt;style type="text/css">
	#blog {border:1px solid #aaf;background:#f9f9f9;padding:4px}
	.post {border:1px solid #aaa;background:#fff;padding:4px;margin: 2px 0}
	#loading {height: 40px}
	&lt;/style>
&lt;/head>

&lt;body id="hello_body">

	&lt;div id="blog">
		&lt;div id="loading" style="display:none">Loading....&lt;/div>
	&lt;/div>
&lt;/body>
&lt;/html>
</pre>
<p>Здесь также подключаем скрипт <em>jquery.js</em>, а также стили для блога и записей.</p>
<p>Далее переходим к созданию скрипта, вся функциональность которого будет заключена в объект <em>engine</em>:</p>
<pre class="prettyprint">
var engine = {
	posts : [],
	target : null,
	busy : false,
	count : 5
}
</pre>
<p>В переменных объекта <em>engine</em> хранятся различные параметры работы скрипта &#8211; количество подгружаемых за один раз записей (<strong>count</strong>), элемент, в который эти записи должны добавляться (<strong>target</strong>), состояние скрипта (<strong>busy</strong>), и массив записей (<strong>post</strong>).</p>
<p>Инициализация скрипта будет производиться функцией <strong>init</strong>:</p>
<pre class="prettyprint">
init : function(posts, target){
	if (!target)
		return;

	this.target = $(target);

	this.append(posts);

	var that = this;
	$(window).scroll(function(){
		if ($(document).height() - $(window).height() <= $(window).scrollTop() + 50) {
			that.scrollPosition = $(window).scrollTop();
			that.get();
		}
	});
}
</pre>
<p>Функция принимает два параметра - массив записей и элемент, в который записи должны быть добавлены. В конце функции добавляется обработчик события <em>onscroll</em> для объекта <em>window</em>. Его задача - определять положение полосы прокрутки, и если она находится в крайнем нижнем положении, то вызывать функцию подгрузки записей <strong>get()</strong>. Фунция <strong>get()</strong> отправляет AJAX запрос на сервер и, получая в ответ записи блога, добавляет их в элемент <em>target</em>:</p>
<pre class="prettyprint">
get : function() {
	if (!this.target || this.busy) return;

	if (this.posts &#038;&#038; this.posts.length) {
		var lastId = this.posts[this.posts.length-1].id;
	} else {
		var lastId = 0;
	}

	this.setBusy(true);

	var that = this;
	$.getJSON('getposts.php', {count:this.count, last:lastId},
		function(data){
			if (data.length > 0) {
				that.append(data);
			}
			that.setBusy(false);
		}
	);
}
</pre>
<p>Данные о всех записях, которые загружаются с сервера, хранятся в переменной <em>engine.posts</em>. Перед отправкой очередного запроса на сервер, функция <strong>get()</strong> получает id последнего элемента в этом списке (<em>lastId</em>), для того чтобы передать его в параметрах запроса. Это нужно для того, чтобы серверный скрипт знал, какие записи уже получены, и какие элементы нужно отправить.</p>
<p>Как в функции <strong>init()</strong>, так и в функции <strong>get()</strong>, для отображения записей используется функция <strong>append()</strong>, которая в связке с <strong>render()</strong> создает HTML код записи и добавляет его в целевой элемент (target):</p>
<pre class="prettyprint">
append : function(posts){
	posts = (posts instanceof Array) ? posts : [];
	this.posts = this.posts.concat(posts);

	for (var i=0, len = posts.length; i < len; i++) {
		this.target.append(this.render(posts[i]));
	}

	if (this.scrollPosition !== undefined &#038;&#038; this.scrollPosition !== null) {
		$(window).scrollTop(this.scrollPosition);
	}
},

render : function(obj){
	var xhtml = '&lt;div class="post" id=post_'+obj.id+'>';
	if (obj.title) {
		xhtml += '&lt;h2>'+obj.title+'&lt;/h2>';
	}
	if (obj.posted_at) {
		xhtml += '&lt;div class="posted_at">Posted on: '+obj.posted_at+'&lt;/div>';
	}
	if (obj.comments_count) {
		xhtml += '&lt;div class="comments_count">Comments: ' + obj.comments_count + '&lt;/div>';
	}
	xhtml += '&lt;div class="content">' + obj.content + '&lt;/div>';
	xhtml += '&lt;/div>';

	return xhtml;
}
</pre>
<p>Еще стоит упомянуть одну небольшую деталь: в обработчике события <strong>onscroll</strong> я сохраняя позицию полосы прокрутки, чтобы потом, после добавления новых записей, восстановить её. Это нужно для того, чтобы положение полосы прокрутки не изменялось, при добавлении новых записей в конец списка:</p>
<pre class="prettyprint">
// сохраняем значение в обработчике onscroll
that.scrollPosition = $(window).scrollTop();

.......

// восстанавливаем значение в функции append
if (this.scrollPosition !== undefined &#038;&#038; this.scrollPosition !== null) {
	$(window).scrollTop(this.scrollPosition);
}
</pre>
<p>Теперь, после того, как скрипт создан, можно использовать его. Так же как и для большинства скриптов jQuery, добавляем код инициализации  в фукнцию <strong>ready()</strong>:</p>
<pre class="prettyprint">
$(document).ready(function(){
	engine.init(null, $("#blog"));
	engine.get();
});
</pre>
<p>Вот пожалуй и все описание скрипта, как видите он совсем не сложный. Демо приложения можно посмотреть здесь: <a href="/demo/endless/">смотреть демо</a>. Полностью скрипт доступен на <a href="http://gist.github.com/97794">github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2009/04/18/realizaciya-beskonechnoj-prokrutki-na-jquery/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Управление табличными данными при помощи jQuery</title>
		<link>http://www.jstoolbox.com/2009/01/22/upravlenie-tablichnymi-dannymi-pri-pomoshhi-jquery/</link>
		<comments>http://www.jstoolbox.com/2009/01/22/upravlenie-tablichnymi-dannymi-pri-pomoshhi-jquery/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 15:33:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Уроки]]></category>
		<category><![CDATA[tableFormSynch]]></category>
		<category><![CDATA[туториал]]></category>
		<category><![CDATA[урок]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=355</guid>
		<description><![CDATA[<p>В одной из прошлых статей я <a href="http://www.jstoolbox.com/2008/12/21/redaktiruemyj-kontent-na-jquery/">писал</a> о том, как сделать текст на странице динамически редактируемым. Там был представлен метод редактирования при помощи плагина <a href="http://www.appelsiini.net/projects/jeditable">jEditable</a>. Таким образом можно динамически редактировать любой блок текста на странице. Однако если речь идет о табличных данных, то гораздо удобнее использовать другое решение - плагин <a href="http://www.swartzfager.org/blog/jQuery/plugins/tableFormSynch/">tableFormSynch</a>. Этот плагин связывает таблицу с формой, давая возможность динамически редактировать данные в таблице, а также добавлять и удалять записи.</p>]]></description>
			<content:encoded><![CDATA[<p style="margin: 0 0 4px 4px; padding: 2px; border: 1px solid red"><strong>Update:</strong> Внимание! Эта статья устаревшая, а плагин, который здесь используется уже не поддерживается автором и имеет неисправленные ошибки.</p>
<p>В одной из прошлых статей я <a href="http://www.jstoolbox.com/2008/12/21/redaktiruemyj-kontent-na-jquery/">писал</a> о том, как сделать текст на странице динамически редактируемым. Там был представлен метод редактирования при помощи плагина <a href="http://www.appelsiini.net/projects/jeditable">jEditable</a>. Таким образом можно динамически редактировать любой блок текста на странице. Однако если речь идет о табличных данных, то гораздо удобнее использовать другое решение &#8211; плагин <a href="http://www.swartzfager.org/blog/jQuery/plugins/tableFormSynch/">tableFormSynch</a>. Этот плагин связывает таблицу с формой, давая возможность динамически редактировать данные в таблице, а также добавлять и удалять записи.</p>
<p>В этой статье я покажу, как сделать простое приложение, реализующее редактирование, добавление и удаление записей таблицы, сохраняя данные при помощи AJAX. Чтобы создать приложение нам будут нужны библиотека <a href="http://jquery.com">jQuery</a>, плагин <a href="http://plugins.jquery.com/project/metadata">metadata</a> (требуется для работы плагина tableFormSynch), а также <a href="http://malsup.com/jquery/form/">jQuery Form Plugin</a> для сохранения данных формы через AJAX. Но прежде чем мы начнем, предлагаю посмотреть на готовый результат. <a href="http://www.jstoolbox.com/demo/tablesynch/index.php" title="Демо пример">Смотреть демо пример</a>.</p>
<p><span id="more-355"></span></p>
<p>Итак, начинаем с того, что создаем HTML страницу и подключаем к ней необходимые нам скрипты:</p>
<pre class="prettyprint">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
&lt;html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="ru-RU">

&lt;head profile="http://gmpg.org/xfn/11">
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

&lt;script type="text/javascript" src="jquery-1.2.6.min.js">&lt;/script>
&lt;script type="text/javascript" src="jquery.metadata.min.js">&lt;/script>
&lt;script type="text/javascript" src="jquery.tableFormSynch.documented.js">&lt;/script>
&lt;script type="text/javascript" src="jquery.form.js">&lt;/script>

&lt;/head>
&lt;body>

&lt;/body>
&lt;/html>
</pre>
<p>Далее добавляем табличные данные, которые мы собираемся редактировать, плюс сюда же добавляем ссылки на редактирование и удаление записи. Здесь есть обязательные условия: для каждой строки таблицы нужно указать ID записи в атрибуте <em>id</em> и метаданные (то есть все данные записи) в атрибуте <em>class</em>. И еще &#8211; все строки таблицы должны быть обязательно заключены в тэги <em>&lt;tbody&gt;</em>:</p>
<pre class="prettyprint">
&lt;tr id="1" class="{personId:1,first_name:'Иван',last_name:'Иванов',position:'Программист'}">
	&lt;td>Иван&lt;/td>
	&lt;td>Иванов&lt;/td>
	&lt;td>Программист&lt;/td>
	&lt;td>&lt;a href="#" class="edit">Редактировать&lt;/a> | &lt;a href="#" class="delete">удалить&lt;/a>&lt;/td>
&lt;/tr>
</pre>
<p>Следующий шаг &#8211; создание формы: она будет располагаться в последней строке таблицы и при загрузке страницы будет не видна. Появляться она будет по надобности, при нажатии на ссылки &#8220;добавить запись&#8221; или &#8220;редактировать&#8221;. Форма будет иметь все нужные поля (в нашем случае текстовые поля) и три кнопки &#8211; &#8220;добавить&#8221; и &#8220;редактировать&#8221;, которые появляются в зависимости от выбранного действия, а также &#8220;отмена&#8221;, по нажатию на которую форма будет исчезать.</p>
<pre class="prettyprint">
&lt;form id="rowEditForm" action="save.php" method="post">
&lt;table width="100%" cellpadding="0" cellspacing="0" border="0" id="demoTable" class="tablesCorp">

&lt;!-- строки таблицы -->

&lt;tr id="editableRow">
	&lt;td>&lt;input type="hidden" name="personId" value="0"/>&lt;input type="text" name="first_name" value=""/>&lt;/td>
	&lt;td>&lt;input type="text" name="last_name" value=""/>&lt;/td>
	&lt;td>&lt;input type="text" name="position" value=""/>&lt;/td>
	&lt;td>
		&lt;input id="updateBtn" type="submit" name="update" value="Обновить"/>
		&lt;input id="addBtn" type="submit" name="add" value="Добавить"/>
		&lt;input id="cancelBtn" type="button" name="cancel" value="Отмена"/>
		&lt;img id="loading" src="loading.gif" />
	&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/form>
</pre>
<p>Ну и самая малость &#8211; под таблицей размещаем ссылку &#8220;добавить запись&#8221;:</p>
<pre class="prettyprint">
&lt;a href="#" class="add">Добавить запись&lt;/a>
</pre>
<p>Теперь приступим к созданию скрипта нашего приложения. Как полагается для скриптов, написанных под jQuery, заключаем весь наш код в функцию <strong>$.ready()</strong>, и первое, что мы туда поместим, это вызов функции <strong>bindTableToForm()</strong>, которая связывает таблицу с формой:</p>
<pre class="prettyprint">
$(document).ready(function() {

	$("#demoTable").bindTableToForm($("#rowEditForm"),"personId");

});
</pre>
<p>Первым параметром в функцию мы передаем форму, а вторым &#8211; название ключевого поля записи, в нашем случае это ID пользователя.</p>
<p>Далее, создаем фукнцию редактирования. Добавляем ко всем ссылкам &#8220;редактировать&#8221; обработчик, который будет показывать форму редактирования под нужной строкой. Форму заполняем данными при помощи функции <strong>populateForm()</strong>и здесь же показываем конпку &#8220;редактировать&#8221; и прячем конпку &#8220;добавить&#8221;. Таким образом мы переводим форму в режим редактирования. Ну и для красоты подкрашиваем редактируемую строку бледно розовым цветом:</p>
<pre class="prettyprint">
$("a.edit").click(function() {

	$("#addBtn").hide();
	$("#updateBtn").show();

	$(this).populateForm();

	var row = $(this).parent().parent();
	row.find('td').css('background-color','#faa');
	$('#editableRow').insertAfter(row).fadeIn('slow');

	// отмена действия по умолчанию
	return false;
});
</pre>
<p>При нажатии на кнопку &#8220;обновить&#8221;, данные формы будут отправляться на сервер через AJAX, и при успешном сохранении, запись в таблице будет обновляться. Выполняем это все в обработчике <em>onclick</em> кнопки:</p>
<pre class="prettyprint">
$("#updateBtn").click(function() {
	$('#rowEditForm').ajaxForm({
		beforeSubmit : function(){
			$('#loading').show();
		},
		success : function(response){
			$('#loading').hide();
			if (response == 1)
				$("#rowEditForm").updateRow();
			else
				alert('Ошибка сохранения данных');

			var rowId = $("input[name='personId']").val();
			var row = $('tr#'+rowId).find('td').css('background-color','#F5F5F5');
			$('#editableRow').fadeOut('slow');
		}
	});
});
</pre>
<p>Здесь мы используем функцию <strong>ajaxForm()</strong> для выполнения AJAX запроса с данными формы. При успешном сохранении данных, сервер возвращает значение 1, в любом другом случае, трактуем результат как ошибку. Данные в таблице обновляем фукнцией <strong>updateRow()</strong>.</p>
<p>Далее реализовуем добавление новой записи. Всё делаем также, как и для обновления, только вместо того, чтобы заполнять форму, очищаем её функцией <strong>clearForm()</strong>. Ну и естественно, вместо кнопки &#8220;редактировать&#8221; делаем активной кнопку &#8220;добавить&#8221;:</p>
<pre class="prettyprint">
$("a.add").click(function() {
	$("#addBtn").show();
	$("#updateBtn").hide();

	// очищаем форму
	$("#rowEditForm").clearForm();
	$("input[name='personId']").val(0);

	$('#demoTable tbody').append($('#editableRow'));
	$('#editableRow').fadeIn('slow');

	return false;
});
</pre>
<p>Обработчик для кнопки &#8220;добавить&#8221; также мало чем отличается от функции обновления, за исключением того, что сервер возвращает ID новой записи, который затем передается в функцию <strong>addRow()</strong> для добавления записи:</p>
<pre class="prettyprint">
$("#addBtn").click(function() {
	$('#rowEditForm').ajaxForm({
		beforeSubmit : function(){
			$('#loading').show();
		},
		success : function(response){
			$('#loading').hide();
			if (response == 0)
				alert('Ошибка добавления данных');
			else
				$("#rowEditForm").addRow(response);

			$('#editableRow').fadeOut('slow');
		}
	});
});
</pre>
<p>Теперь выполним удаление записи &#8211; используем для этого функцию <strong>deleteRow()</strong>. Для отправки запроса на сервер будем использовать функцию <strong>$.post()</strong>, которая будет отправлять запрос в отдельный файл <em>delete.php</em>. Последний выполняет удаление записи и возвращает 1 если запись удалилась, и 0 если произошла ошибка. В самом начале функции мы получаем ID записи которую необходимо удалить, затем передаем это значение в функцию <strong>$.post()</strong> в качестве параметра <em>personId</em>, который будет установлен переменной в POST:</p>
<pre class="prettyprint">
$("a.delete").click(function() {

	var id = $(this).parent().parent().attr('id');

	var that = $(this);
	$.post('delete.php',
		{personId : id},
		function(data){
			if (data == 1)
				that.deleteRow();
			else
				alert('Ошибка удаления записи');
		});
	return false;
});
</pre>
<p>Ну и последняя, самая простая функция &#8211; &#8220;отмена&#8221;. Здесь мы просто прячем форму и закрашиваем все строки формы в стандартный цвет:</p>
<pre class="prettyprint">
$("#cancelBtn").click(function(){
	$("#editableRow").fadeOut("slow");
	$(".tablesCorp td").css('background-color','#F5F5F5');
});
</pre>
<p>Посмотреть скрипт полностью можно <a href="http://www.jstoolbox.com/demo/tablesynch/script.js">здесь</a>.</p>
<p>После этого нужно еще установить пару обязательных стилей:</p>
<pre class="prettyprint">
#editableRow {display:none}
#addBtn {display:none}
</pre>
<p>Первая строка прячет форму редактирования, а вторая кнопку &#8220;добавить&#8221;, которые в начале работы должны быть скрытыми.</p>
<p>Вот и все, наше приложение готово. Буду рад услышать Ваши замечания <img src='http://www.jstoolbox.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> <br/><br />
До встречи!</p>
<p  style="margin: 0 0 4px 4px; padding: 2px; border: 1px solid red"><strong>Update:</strong> Внимание! Эта статья устаревшая, а плагин, который здесь используется уже не поддерживается автором и имеет неисправленные ошибки.</p>
<p><a href="http://www.jstoolbox.com/demo/tablesynch/index.php" class="demo">смотреть демо</a><a href="http://www.jstoolbox.com/download/synch.zip" class="download">скачать демо</a></p>
<div class="postLinks">
<strong>Спонсор статьи:</strong><br/>Автошколы, автокурсы и <a href="http://avtobip.ru/">автоинструкторы Москвы</a><br/>Курсы MBA, бизнес школа <a href="http://ukraine.ibr-network.com/">мба одесса</a><br/><a href="http://voditel.info/">Инструктор по вождению</a> &#8211; обучение вождению автомобиля в Москве</div>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2009/01/22/upravlenie-tablichnymi-dannymi-pri-pomoshhi-jquery/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
		<item>
		<title>Редактируемый контент на jQuery</title>
		<link>http://www.jstoolbox.com/2008/12/21/redaktiruemyj-kontent-na-jquery/</link>
		<comments>http://www.jstoolbox.com/2008/12/21/redaktiruemyj-kontent-na-jquery/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 22:58:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=296</guid>
		<description><![CDATA[Этот простой туториал посвящен тому, как сделать любой текст на странице динамически редактируемым. В общем виде работает это так: пользователь щелкает мышью по тексту, который нужно отредактировать, в результате чего на этом месте появляется форма для редактирования. После того, как пользователь внес изменения, он нажимает кнопку OK и скрипт автоматически отправляет AJAX запрос на сервер, [...]]]></description>
			<content:encoded><![CDATA[<p>Этот простой туториал посвящен тому, как сделать любой текст на странице динамически редактируемым. В общем виде работает это так: пользователь щелкает мышью по тексту, который нужно отредактировать, в результате чего на этом месте появляется форма для редактирования. После того, как пользователь внес изменения, он нажимает кнопку <em>OK</em> и скрипт автоматически отправляет AJAX запрос на сервер, сохраняя введенные данные. После этого форма исчезает, а на её месте остается отредактированный текст.</p>
<p>Для выполнения такой задачи, нам понадобятся библиотека <a href="http://jquery.com" title="Библиотека jQuery">jQuery</a> и плагин <a href="http://www.appelsiini.net/projects/jeditable" title="Jeditable">Jeditable</a>.</p>
<p><span id="more-296"></span></p>
<p>Начнем с создания HTML страницы, в которой выделим текст, который необходимо редактировать, заключив его в <strong>&lt;div&gt;</strong> с классом <strong>editable</strong>. Здесь же подключаем нужные нам скрипты <em>jquery.js</em> и <em>jquery.jeditable.js</em>:</p>
<pre class="prettyprint">
&lt;html>
&lt;head>
&lt;script type="text/javascript" src="jquery.js">&lt;/script>
&lt;script type="text/javascript" src="jquery.jeditable.js">&lt;/script>
&lt;/head>
&lt;body>
&lt;div class="editable">
Lorem ipsum dolor sit amet, consectetur adipiscing elit....
&lt;/div>
&lt;hr/>
&lt;div class="editable">
Aenean ut mauris nec nisl varius volutpat....
&lt;/div>
&lt;hr/>
&lt;div class="editable">
Aenean pharetra. Curabitur non turpis....
&lt;/div>
&lt;/body>
&lt;/html>
</pre>
<p>Далее пишем скрипт, который будет инициализировать нужные нам блоки текста:</p>
<pre class="prettyprint">
$(document).ready(function() {
     	$(".editable").editable("/jedit/file.php",
		{
			type      : 'textarea',
		        cancel    : 'Отмена',
		        submit    : 'OK',
		        indicator : '<img src="loading.gif">',
			tooltip : "Щелкните чтоб отредактировать этот текст"
		}
	);
});
</pre>
<p>Здесь селектор <strong>$(&#8221;.editable&#8221;)</strong> выделяет нужные нам блоки кода, а фукнция editable инициализирует их с указанными параметрами. Первый параметр &#8211; это URL, на который будет отправляться AJAX запрос при сохранении изменений. Второй параметр &#8211; это опции. Вкратце опишу, что они значат:</p>
<ul>
<li><em>type</em> &#8211; указывает на тип элемента редактирования. По умолчанию используется простое текстовое поле (&lt;input type=&#8221;text&#8221;&gt;), но можно указать и textarea, как сделано в нашем примере. Также, эта опция может иметь значение select  (будет рассмотрено ниже)</li>
<li><em>cancel</em> &#8211; указывает на то, что нужно отображать кнопку &#8220;отмена&#8221;. По умолчанию кнопки нет, отменить редактирование можно клавишей <strong>Esc</strong>.</li>
<li><em>ОК</em> &#8211; указывает на то, что нужно отображать кнопку &#8220;ОК&#8221;, то есть кнопку сохранения изменений. По умолчанию кнопки нет, сохранить изменения можно клавишей <strong>Enter</strong>.</li>
<li><em>indicator</em> &#8211; индикатор ожидания &#8211; форматированный текст (допускаются HTML теги), который будет отображаться при отправке запроса на сервер. Здесь я использовал <strong>&lt;img&gt;</strong> чтобы показать анимированный индикатор.</li>
<li><em>tooltip</em> &#8211; всплывающая подсказка, которая будет показана при наведении мышки на редактируемый блок текста.</li>
</ul>
<p>AJAX запрос, который отправляется на сервер, имеет два параметра: <em>id</em> и <em>value</em>:</p>
<pre class="prettyprint">
id=elements_id&#038;value=user_edited_content
</pre>
<p>Если вы хотите изменить названия этих двух параметров, то это можно сделать, присвоив нужные значения опциям <em>id</em> и <em>name</em>:</p>
<pre class="prettyprint">
 $(document).ready(function() {
     $('.edit').editable('http://www.example.com/save.php', {
         id   : 'elementid',
         name : 'newvalue'
     });
 });
</pre>
<p>Теперь представьте себе ситуацию, когда пользователю нужно отредактировать какой то короткий кусок текста, однако вводить не что попало, а выбирать некоторое определенное значение. В этом случае было бы удобно вместо текстового поля показывать выпадающий список. Это можно сделать, указав в качестве опции <em>type</em> значение <em>select</em>, а в параметре <em>data</em> указать объект со всеми значениями для списка:</p>
<pre class="prettyprint">
$('#country').editable('/jedit/country.php', {
	data   : " {'U':'Украина','B':'Белоруссия','R':'Россия', 'selected':'U'}",
	type   : 'select',
	submit : 'OK',
        indicator : '<img src="loading.gif">',
	tooltip : "Щелкните чтоб выбрать страну"
});
</pre>
<p>Обратите внимание на значение <strong>&#8217;selected&#8217;</strong> в объекте <em>data</em>. Таким образом указывается элемент списка, который должен быть выбран. В результате при щелчке мышки на таком тексте, вместо него появится выпадающий список. Пользователю остается только выбрать один из предлагаемых вариантов и сохранить свой выбор, нажав ОК.</p>
<p><a href="/demo/jedit/index.php" title="Смотреть демо" class="demo">Смотреть демо</a></p>
<div class="postLinks">
<strong>Спонсор статьи</strong>:<br/><br />
Биржа труда &#8211; <a href="http://nikolaev.netbee.ua/">работа николаев</a><br/><br />
Эксперт-Смета: <a href="http://www.expertsoft.com.ua/smeta/46/">расчет смет</a><br/><br />
Клиника Оксфорд Медикал &#8211; <a href="http://www.oxford-med.com.ua/ManHealth.asp?ID=1">потенция лечение</a>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2008/12/21/redaktiruemyj-kontent-na-jquery/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Новый плагин для Mootools &#8211; Request.Queue</title>
		<link>http://www.jstoolbox.com/2008/12/07/mootools-request-queue/</link>
		<comments>http://www.jstoolbox.com/2008/12/07/mootools-request-queue/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 21:16:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[MooTools]]></category>
		<category><![CDATA[Плагины]]></category>
		<category><![CDATA[плагин]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/?p=281</guid>
		<description><![CDATA[<p><a href="http://www.clientcide.com/code-snippets/ajax/new-plugin-requestqueue/">Request.Queue</a> - это новый плагин для библиотеки <a href="http://mootools.net">Mootools</a>, который позволяет последовательно отправлять AJAX запросы на сервер. Работает это так: пользователь создает некоторое количество запросов  <strong>Request</strong>, которые должны быть отправлены на сервер один за одним, затем добавляет их в очередь <strong>Request.Queue</strong>, после чего для каждого запроса вызывается метод <strong>send()</strong> в том порядке, в котором они должны быть отправлены.</p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.clientcide.com/code-snippets/ajax/new-plugin-requestqueue/">Request.Queue</a> &#8211; это новый плагин для библиотеки <a href="http://mootools.net">Mootools</a>, который позволяет последовательно отправлять AJAX запросы на сервер. Работает это так: пользователь создает некоторое количество запросов  <strong>Request</strong>, которые должны быть отправлены на сервер один за одним, затем добавляет их в очередь <strong>Request.Queue</strong>, после чего для каждого запроса вызывается метод <strong>send()</strong> в том порядке, в котором они должны быть отправлены.</p>
<p><span id="more-281"></span></p>
<p>Рассмотрим следующий пример:</p>
<pre class="prettyprint">
var num1 = new Request({ url: '/wiki/simple.php', data: {num: 1, sleep: 1}, method: 'get',
    onComplete: function(response){ console.log(response) } });
var num2 = new Request({ url: '/wiki/simple.php', data: {num: 2, sleep: 1}, method: 'get',
    onComplete: function(response){ console.log(response) } });
var num3 = new Request({ url: '/wiki/simple.php', data: {num: 3, sleep: 1}, method: 'get',
    onComplete: function(response){ console.log(response) } });
var myQueue = new Request.Queue();
// можно добавлять запросы по одному
myQueue.addRequest('num1', num1);
// ... или сразу несколько
myQueue.addRequests({ num2: num2, num3: num3 });
num1.send();
num2.send();
num3.send();
</pre>
<p>В этом примере очередь запросов будет отправлять по очереди запросы <em>num1</em>, <em>num2</em>, <em>num3</em>. Каждый из них будет отправляться только после того, как предыдущий завершился.</p>
<p>Стоит отметить, что <strong>Request.Queue</strong> может отправлять не только по одному запросу за раз, а и по нескольку, если указать для него опцию <strong>concurrent</strong> (по умолчанию равняется 1). Кроме этой опции, есть также <strong>stopOnFailure</strong> и <strong>autoAdvance</strong> (обе по умолчанию равны <em>true</em>). Первая приостанавливает отправку запросов при возникновении ошибки, при этом возобновить отправку запросов можно при помощи функции <strong>resume()</strong>. Если установить эту опцию в <em>false</em>, то запросы будут отправляться даже если один из них завершился с ошибкой. Вторая опция &#8211; <strong>autoAdvance</strong> автоматически отправляет следующий запрос. Если установить опцию в <em>false</em>, то отправить следующий запрос в очереди можно будет используя функцию <strong>runNext()</strong>.</p>
<p>Как вы уже видели из предыдущего примера, запросы можно добавлять при помощи функций <strong>addRequest()</strong> и <strong>addRequests()</strong>. Удалять запросы из очереди можно при помощи функции <strong>removeRequest()</strong>:</p>
<pre class="prettyprint">
var foo = new Request();
myRequestQueue.addRequest('fooRequest', foo);
myRequestQueue.removeRequest(foo);
// или
myRequestQueue.removeRequest('fooRequest');
</pre>
<p>Если вам нужно полностью очистить очередь запросов, то это можно сделать одной функцией &#8211; <strong>clear()</strong>:</p>
<pre class="prettyprint">
myRequestQueue.clear();
</pre>
<p>Также, объектам Request.Queue можно назначать следующие события:</p>
<ul>
<li>onRequestStart</li>
<li>onRequestEnd</li>
<li>onRequestSuccess</li>
<li>onRequestComplete</li>
<li>onRequestCancel</li>
<li>onRequestException</li>
<li>onRequestFailure</li>
</ul>
<p>Узнать подробнее о всех функциях и событиях можно в <a href="http://www.clientcide.com/docs/Request/Request.Queue" title="Документация к плагину Request.Queue">документации</a>. Скачать скрипт можно <a href="http://www.clientcide.com/js" title="Скачать скрипт">здесь</a> &#8211; просто отметьте в списке доступных для скачивания плагинов Request.Queue и жмите Download.</p>
<div class="postLinks"><strong>Спонсор статьи</strong>:<br/>Профессиональное <a href="http://netpeak.net/">продвижение сайтов</a>, раскрутка в поисковых системах, оптимизация интернет-магазинов.<br/><a href="http://www.vashsad.ua/rus/useful_clauses_landscape_5.html">Живая изгородь</a> своими руками на сайте &#8220;Ваш Сад&#8221;.<br/><a href="http://dvdray.com.ua/">Интернет-магазин dvd</a> &#8211; купить dvd-диски в киеве, продажа фильмов DVD почтой, dvd в украине.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2008/12/07/mootools-request-queue/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Постраничная навигация на jQuery</title>
		<link>http://www.jstoolbox.com/2008/10/20/postranichnaya-navigaciya-na-jquery/</link>
		<comments>http://www.jstoolbox.com/2008/10/20/postranichnaya-navigaciya-na-jquery/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 19:56:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[пагинатор]]></category>
		<category><![CDATA[постраничная навигация]]></category>

		<guid isPermaLink="false">http://www.jstoolbox.com/2008/10/20/postranichnaya-navigaciya-na-jquery/</guid>
		<description><![CDATA[В последнее время мне пришлось столкнуться с проблемой постраничной навигации (pagination), и, дабы не изобретать велосипед, я сразу же решил поискать готовые решения. Как оказалось, их не так уж и много. В конце концов, я остановил свой выбор на приемлемом для меня решении, о котором и пойдет речь в этой статье. Сие решение представляет собой [...]]]></description>
			<content:encoded><![CDATA[<p>В последнее время мне пришлось столкнуться с проблемой постраничной навигации (pagination), и, дабы не изобретать велосипед, я сразу же решил поискать готовые решения. Как оказалось, их не так уж и много. В конце концов, я остановил свой выбор на приемлемом для меня <a href="http://loveandtheft.org/2008/09/17/jquery-javascript-customizeable-ajax-pageination/">решении</a>, о котором и пойдет речь в этой статье. Сие решение представляет собой скрипт, использующий <a href="http://jquery.com">jQuery</a> и способный обеспечивать быструю и простую навигацию используя AJAX. Я несколько изменил исходный скрипт, чтобы получить таблицу с одинаковым количеством строк (в исходном варианте таблица всегда имела размер в зависимости от количества получаемых данных), плюс я добавил эффекты затухания при прорисовке.</p>
<div class="entry_picture" style="width:347px"><img src='http://www.jstoolbox.com/wp-content/uploads/2008/10/paginator.png' alt='Пагинатор на jQuery' /></div>
<p>Чтобы получить представление о конечном результате этого туториала, предлагаю вам взглянуть на <a href="/demo/jquery-pagination/index.php" title="Демо пример пагинатора на jQuery">демо</a>.</p>
<p><span id="more-229"></span></p>
<p>Создание постраничной навигации начнем собственно с таблицы, которую мы будем заполнять данными:</p>
<pre class="prettyprint">
&lt;table id="list" width="100%" cellspacing="0">
	&lt;caption>Таблица 1: Некоторые произвольные данные&lt;/caption>
	&lt;thead>
		&lt;tr>
			&lt;th scope="col">Название&lt;/th>
			&lt;th scope="col">Автор&lt;/th>
			&lt;th scope="col">Дата&lt;/th>
			&lt;th scope="col">ID&lt;/th>
		&lt;/tr>
	&lt;/thead>
	&lt;tbody>
	&lt;tr>&lt;td scope="row" class="spec">&lt;span>&lt;/span>&lt;/td>&lt;td>&lt;span>&lt;/span>&lt;/td>&lt;td>&lt;span>&lt;/span>&lt;/td>&lt;td>&lt;span>&lt;/span>&lt;/td>&lt;/tr>
	&lt;!-- еще девять таких же строк -->
	&lt;/tbody>
	&lt;tfoot>
		&lt;tr>
			&lt;td colspan="4">
				&lt;ul class="paginator">&lt;/ul>
			&lt;/td>
		&lt;/tr>
	&lt;/tfoot>
&lt;/table>
</pre>
<p>Как видите, это самая обыкновенная пустая таблица, внутри каждой ячейки которой находится элемент <strong>&lt;span></strong>. Сразу же после загрузки страницы, эта таблица будет заполняться данными получаемыми из AJAX запроса. Пустой контейнер <strong>ul</strong> с классом <strong>paginator</strong> будет использоваться для хранения ссылок навигации. Эти ссылки будут обновляться после каждого обновления таблицы.</p>
<p>Далее подключаем скрипт пагинатора:</p>
<pre class="prettyprint">
jQuery.fn.pageinate = function (settings) {

	// Настройки по умолчанию
	var settings = jQuery.extend({
		row: function (container, item, i) {},
		page: function (i) {},
		url: "",
		show: 10,
		start_page:1
	}, settings);

	// элемент, который будет использоваться для пагинатора
	settings.pagelist_selector = jQuery(settings.pagelist_selector);

	return this.each(function(_, element){
		// jQuery-wrap element
		element = $(element);

		var page_link_callback_creator = function(i) {
			return function() {
				$(this).html('&nbsp;');
				$(this).attr('class','waiting');
				update(i);
			}
		};

		var update = function (page) {

			jQuery.getJSON(settings.url, {page:page, show:settings.show}, function(data){
				// Обрабатываем результаты JSON запроса
				pages = data['pages'];
				posts = data['posts'];

				// прорисовка строк таблицы
				for (var i=0; i < settings.show; i++) {
					if (posts[i])
						settings.row(element, posts[i], i);
					else
						settings.row(element, false, i);
				}

				settings.pagelist_selector.fadeOut(100, function(){
					settings.pagelist_selector.html("");
					// создание пагинатора
					for (i=1; i <= pages; i++) {
						selected = page==i
						page_link = settings.page(i, selected);
						settings.pagelist_selector.append(page_link);

						if(!selected) {
							page_link.click(page_link_callback_creator(i));
						}
					}
					settings.pagelist_selector.fadeIn(100);
				});
			});
		};

		// Первоначальное получение данных
		update(settings.start_page);
	});
}
</pre>
<p>Код пагинатора реализован в виде jQuery плагина. В самом начале определяются настройки пагинатора - количество строк на странице (<strong>show</strong>), с какой страницы начинать просмотр (<strong>start_page</strong>), url для AJAX запросов (<strong>url</strong>). Однако основными параметрами в этих опциях являются обработчики <strong>row</strong> и <strong>page</strong>, которые нужны для прорисовки строк таблицы и пагинатора.</p>
<p>Плагин работает следующим образом: в самом последней строке плагина вызывается функция <strong>update()</strong>, которая выполняет AJAX запрос к серверу (адрес указан в опции <em>url</em>). Полученные от сервера данные в формате JSON обрабатываются и добавляются в таблицу:</p>
<pre class="prettyprint">
// прорисовка строк таблицы
for (var i=0; i < settings.show; i++) {
	if (posts[i])
		settings.row(element, posts[i], i);
	else
		settings.row(element, false, i);
}
</pre>
<p>После этого происходит прорисовка пагинатора, используя эффекты затухания (<strong>fadeOut</strong> и <strong>fadeIn</strong>).</p>
<p>Теперь рассмотрим скрипт в котором мы будем использвать созданный нами плагин:</p>
<pre class="prettyprint">
$(document).ready(function(){

	$("#list tbody").pageinate({
		url: "server.php",
		pagelist_selector: "#list ul",
		start_page: 1,

		row:function(container, item, i){
			$("#list tbody tr:eq("+i+") td").each(function(i){
				if (!item)
					$(this).html('&lt;span>&nbsp;&lt;/span>');
				else {
					switch (i){
						case 0:
							$(this).html('&lt;span>'+item['title']+'&lt;/span>');
							break;
						case 1:
							$(this).html('&lt;span>'+item['author']+'&lt;/span>');
							break;
						case 2:
							$(this).html('&lt;span>'+item['date']+'&lt;/span>');
							break;
						case 3:
							$(this).html('&lt;span>'+item['id']+'&lt;/span>');
							break;
					}
				}
			});
		},

		page:function(id, selected) {
			return $('&lt;li class="'+(selected?"selected":"")+'">'+id+'&lt;/li>');
		}
	});

});
</pre>
<p>Вызывается он обычным для jQuery образом, указывая все перечисленные выше опции - url, pagelist_selector и т.п.:</p>
<pre class="prettyprint">
$("#list tbody").pageinate({});
</pre>
<p>В качестве обработчиков <strong>row()</strong> и <strong>page()</strong> указываем функции, рисующие строку и пагинатор. Как видите, функции несложные, в особенности page(), где просто создается новый элемент <em>li</em> с номером страницы. Если страница текущая, то для созданного элемента указывается класс <em>selected</em>. Обработчик row() несколько сложнее - он целиком и полностью зависит от получаемых от сервера данных. В самом начале функция получает указатели на все ячейки строки (аргумент <em>i</em> указывает на строку таблицы), в которую нужно поместить значение:</p>
<pre class="prettyprint">
$("#list tbody tr:eq("+i+") td").each(function(i){})
</pre>
<p>Затем, используя функцию <strong>each()</strong> поочередно добавляем нужные нам данные в соответствующие ячейки используя конструкцию <strong>switch</strong>. Если в функцию передан пустой аргумент <strong>item</strong> (пустая ячейка), то в содержимое ячейки очищается (визуально - <em>span</em> там нужен, чтобы пустая ячейка имела те же размеры что и заполненая):</p>
<pre class="prettyprint">
if (!item)
	$(this).html('&lt;span>&nbsp;&lt;/span>');
</pre>
<p>Конечно же, это не полнофункциональный пагинатор, как мы его привыкли видеть в обычных приложениях, но я думаю недостающие функции, как ссылки "Вперед" и "Назад", несложно написать самостоятельно.</p>
<p>На сегодня это все.<br/>До встречи!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jstoolbox.com/2008/10/20/postranichnaya-navigaciya-na-jquery/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>
