<?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>jQuery и другое... &#187; jQuery</title>
	<atom:link href="http://www.linkexchanger.su/category/jquery/feed" rel="self" type="application/rss+xml" />
	<link>http://www.linkexchanger.su</link>
	<description>css, html, php, javascript, jQuery, ajax ... - решения, примеры, рецепты</description>
	<lastBuildDate>Sun, 08 Jan 2012 13:25:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>jQuery. Сборник рецептов (+ CD-ROM)</title>
		<link>http://www.linkexchanger.su/2011/842.html</link>
		<comments>http://www.linkexchanger.su/2011/842.html#comments</comments>
		<pubDate>Tue, 02 Aug 2011 09:21:13 +0000</pubDate>
		<dc:creator>Gennady</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery UI]]></category>
		<category><![CDATA[jQuery документация]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[документация jQuery]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/?p=842</guid>
		<description><![CDATA[В августе в интернет-магазинах должна появиться в продаже книга jQuery. Сборник рецептов (+ CD-ROM). Это второе издание книги, которая вышла в издательстве &#171;БХВ-Петербург&#187; чуть более года назад. Второе издание дорабатывалось мной с учетом замечаний и пожеланий читателей и вновь появившихся возможностей.

Геннадий Самков
jQuery. Сборник рецептов (+ CD-ROM)
Издательство: БХВ-Петербург, 2011 г.
Мягкая обложка, 416 стр.
ISBN 978-5-9775-0732-5
Тираж: 1500 экз.
Формат: [...]]]></description>
			<content:encoded><![CDATA[<p>В августе в интернет-магазинах должна появиться в продаже книга <strong>jQuery. Сборник рецептов (+ CD-ROM)</strong>. Это <strong>второе издание</strong> книги, которая вышла в издательстве &laquo;БХВ-Петербург&raquo; чуть более года назад. Второе издание дорабатывалось мной с учетом замечаний и пожеланий читателей и вновь появившихся возможностей.</p>
<ul style="float: right; width: 200px">
<li>Геннадий Самков</li>
<li>jQuery. Сборник рецептов (+ CD-ROM)</li>
<li>Издательство: БХВ-Петербург, 2011 г.</li>
<li>Мягкая обложка, 416 стр.</li>
<li>ISBN 978-5-9775-0732-5</li>
<li>Тираж: 1500 экз.</li>
<li>Формат: 70&#215;100/16</li>
</ul>
<p><a href="http://www.ozon.ru/context/detail/id/6843919/?partner=lexsu&#038;from=bar" title="jQuery. Сборник рецептов" target="_blank"><img style="border:1px solid #333;" src="http://www.linkexchanger.su/wp-content/uploads/2011/07/jquery2.jpg" alt="jQuery. Сборник рецептов" /></a><span id="more-842"></span></p>
<p><strong>Аннотация:</strong><br />
Книга является сборником решений наиболее часто встречающихся задач при веб-программировании пользовательских интерфейсов с использованием библиотеки jQuery. Рассмотрены практически все методы и вспомогательные функции jQuery, в том числе обеспечивающие взаимодействие jQuery и AJAX. Подробно рассказано о надстройке UI jQuery. Приведено большое количество примеров использования плагинов для jQuery &#8211; создание графиков и диаграмм, фотогалерей, меню, работа с таймерами и cookies, обработка табличных данных и др. Во втором издании в примерах используется библиотека jQuery версий 1.4.4 и 1.5.2, а также надстройка UI jQuery 1.8.9.<br />
Компакт-диск содержит примеры из книги, файлы библиотеки jQuery 1.4.4 и 1.5.2, файлы надстройки UI jQuery 1.8.9, а также файлы расширений сторонних разработчиков.</p>
<p>От себя могу добавить, что книга написана в таком же духе, как и <a href="http://www.linkexchanger.su/2010/115.html">первое издание</a>, т.е. примеры, примеры и еще раз примеры плюс подробные разъяснения&#8230;.</p>
<p><a target="_blank" href="http://mmedia.ozon.ru/multimedia/book_file/1003104287.pdf">Отрывок книги в PDF</a></p>
<p><strong>Полное содержание:</strong></p>
<table border="0" width="100%">
<tr>
<td>Введение</td>
<td>7</td>
</tr>
<tr>
<td>Структура книги</td>
<td>7</td>
</tr>
<tr>
<td>Как работать с книгой</td>
<td>8</td>
</tr>
<tr>
<td>Источники информации</td>
<td>9</td>
</tr>
<tr>
<td>Благодарности</td>
<td>10</td>
</tr>
<tr>
<td>
<h3>ЧАСТЬ I. МЕТОДЫ БИБЛИОТЕКИ JQUERY</h3>
</td>
<td>11</td>
</tr>
<tr>
<td>
<h3>Глава 1. Выбор элементов</h3>
</td>
<td>13</td>
</tr>
<tr>
<td>1.1. Базовые правила</td>
<td>13</td>
</tr>
<tr>
<td>1.2. Выбор элементов с учетом иерархии</td>
<td>20</td>
</tr>
<tr>
<td>1.3. Основные фильтры</td>
<td>24</td>
</tr>
<tr>
<td>1.4. Фильтрация по содержимому</td>
<td>30</td>
</tr>
<tr>
<td>1.5. Фильтры видимых и невидимых элементов</td>
<td>34</td>
</tr>
<tr>
<td>1.6. Селекторы атрибутов</td>
<td>36</td>
</tr>
<tr>
<td>1.7. Фильтры элементов форм</td>
<td>40</td>
</tr>
<tr>
<td>1.8. Фильтры состояния элементов форм</td>
<td>43</td>
</tr>
<tr>
<td>1.9. Фильтры элементов-потомков</td>
<td>47</td>
</tr>
<tr>
<td>
<h3>Глава 2. Атрибуты элементов</h3>
</td>
<td>53</td>
</tr>
<tr>
<td>2.1. Управление атрибутами элементов</td>
<td>53</td>
</tr>
<tr>
<td>2.2. Работа с атрибутом class</td>
<td>57</td>
</tr>
<tr>
<td>2.3. Работа с HTML и текстом</td>
<td>59</td>
</tr>
<tr>
<td>2.4. Работа с атрибутом value</td>
<td>61</td>
</tr>
<tr>
<td>
<h3>Глава 3. Визуальные эффекты</h3>
</td>
<td>67</td>
</tr>
<tr>
<td>3.1. Как показывать и скрывать элементы</td>
<td>67</td>
</tr>
<tr>
<td>3.2. Эффекты &laquo;скольжения&raquo; и &laquo;затухания&raquo;</td>
<td>70</td>
</tr>
<tr>
<td>3.3. Создание анимации</td>
<td>74</td>
</tr>
<tr>
<td>3.4. Эффекты UI jQuery</td>
<td>79</td>
</tr>
<tr>
<td>
<h3>Глава 4. Работа с CSS-свойствами</h3>
</td>
<td>84</td>
</tr>
<tr>
<td>4.1. Как получать и устанавливать значения CSS-свойств элементов</td>
<td>84</td>
</tr>
<tr>
<td>4.2. Ширина и высота элементов</td>
<td>88</td>
</tr>
<tr>
<td>4.3. Позиционирование элементов</td>
<td>90</td>
</tr>
<tr>
<td>
<h3>Глава 5. Работа с данными в jQuery</h3>
</td>
<td>94</td>
</tr>
<tr>
<td>5.1. Сохранение и извлечение данных</td>
<td>94</td>
</tr>
<tr>
<td>
<h3>Глава 6. Манипуляции над элементами</h3>
</td>
<td>98</td>
</tr>
<tr>
<td>6.1. Изменение содержимого элементов</td>
<td>98</td>
</tr>
<tr>
<td>6.2. Как вставлять элементы в DOM</td>
<td>101</td>
</tr>
<tr>
<td>6.3. Замена, удаление и копирование элементов</td>
<td>111</td>
</tr>
<tr>
<td>
<h3>Глава 7. Перемещение по элементам</h3>
</td>
<td>118</td>
</tr>
<tr>
<td>7.1. Поиск нужных элементов в DOM</td>
<td>118</td>
</tr>
<tr>
<td>7.2. Фильтрация элементов набора</td>
<td>128</td>
</tr>
<tr>
<td>7.3. Прочие методы</td>
<td>138</td>
</tr>
<tr>
<td>
<h3>Глава 8. События и их обработка</h3>
</td>
<td>144</td>
</tr>
<tr>
<td>8.1. События документа</td>
<td>144</td>
</tr>
<tr>
<td>8.2. Назначение, удаление и вызов событий</td>
<td>146</td>
</tr>
<tr>
<td>8.3. События мыши, клавиатуры, браузера и форм</td>
<td>156</td>
</tr>
<tr>
<td>
<h3>Глава 9. Взаимодействие jQuery и AJAX</h3>
</td>
<td>165</td>
</tr>
<tr>
<td>9.1. Сокращенные методы</td>
<td>165</td>
</tr>
<tr>
<td>9.2. Вспомогательные функции $.ajax() и $ajaxSetup()</td>
<td>178</td>
</tr>
<tr>
<td>9.3. События AJAX</td>
<td>187</td>
</tr>
<tr>
<td>9.4. Полезные вспомогательные функции</td>
<td>192</td>
</tr>
<tr>
<td>
<h3>Глава 10. Полезные вспомогательные функции и методы jQuery</h3>
</td>
<td>195</td>
</tr>
<tr>
<td>10.1. Некоторые операции с массивами и объектами в jQuery</td>
<td>195</td>
</tr>
<tr>
<td>10.2. Некоторые операции с наборами элементов в jQuery</td>
<td>208</td>
</tr>
<tr>
<td>10.3. Другие полезные вспомогательные функции</td>
<td>214</td>
</tr>
<tr>
<td>
<h3>ЧАСТЬ II. РАСШИРЕНИЯ ДЛЯ БИБЛИОТЕКИ JQUERY</h3>
</td>
<td>219</td>
</tr>
<tr>
<td>
<h3>Глава 11. Меню для веб-сайта</h3>
</td>
<td>221</td>
</tr>
<tr>
<td>11.1. Плагин jQuery Superfish</td>
<td>221</td>
</tr>
<tr>
<td>
<h3>Глава 12. Работа с таблицами</h3>
</td>
<td>230</td>
</tr>
<tr>
<td>12.1. Плагин jqGrid</td>
<td>230</td>
</tr>
<tr>
<td>
<h3>Глава 13. Графики и диаграммы</h3>
</td>
<td>250</td>
</tr>
<tr>
<td>13.1. Плагин jqPlot</td>
<td>250</td>
</tr>
<tr>
<td>
<h3>Глава 14. AJAX-формы</h3>
</td>
<td>262</td>
</tr>
<tr>
<td>14.1. Плагин jQuery Form</td>
<td>262</td>
</tr>
<tr>
<td>14.2. Плагин jQuery Validate</td>
<td>267</td>
</tr>
<tr>
<td>14.3. Плагин jQuery Uploadify</td>
<td>273</td>
</tr>
<tr>
<td>
<h3>Глава 15. Фотогалерея для сайта</h3>
</td>
<td>282</td>
</tr>
<tr>
<td>15.1. Фотогалерея FancyBox</td>
<td>282</td>
</tr>
<tr>
<td>
<h3>Глава 16. Несколько полезных плагинов</h3>
</td>
<td>297</td>
</tr>
<tr>
<td>16.1. jQuery Cookie</td>
<td>297</td>
</tr>
<tr>
<td>16.2. jQuery Timers</td>
<td>299</td>
</tr>
<tr>
<td>16.3. jQuery Cluetip</td>
<td>302</td>
</tr>
<tr>
<td>
<h3>Глава 17. UI jQuery — виджеты</h3>
</td>
<td>308</td>
</tr>
<tr>
<td>17.1. Виджет Accordion</td>
<td>308</td>
</tr>
<tr>
<td>17.2. Виджет Datepicker</td>
<td>318</td>
</tr>
<tr>
<td>17.3. Виджет Dialog</td>
<td>329</td>
</tr>
<tr>
<td>17.4. Виджет Progressbar</td>
<td>337</td>
</tr>
<tr>
<td>17.5. Виджет Slider</td>
<td>340</td>
</tr>
<tr>
<td>17.6. Виджет Tabs</td>
<td>346</td>
</tr>
<tr>
<td>17.7. Виджет Button</td>
<td>356</td>
</tr>
<tr>
<td>17.8. Виджет Autocomplete</td>
<td>361</td>
</tr>
<tr>
<td>
<h3>Глава 18. UI jQuery — взаимодействие с элементами страницы</h3>
</td>
<td>370</td>
</tr>
<tr>
<td>18.1. Draggable — перемещение элементов</td>
<td>370</td>
</tr>
<tr>
<td>18.2. Droppable — &laquo;сброс&raquo; элементов</td>
<td>379</td>
</tr>
<tr>
<td>18.3. Resizable — изменение размеров элементов</td>
<td>386</td>
</tr>
<tr>
<td>18.4. Selectable — выбор элементов</td>
<td>392</td>
</tr>
<tr>
<td>18.5. Sortable — сортировка элементов</td>
<td>399</td>
</tr>
<tr>
<td>Приложение. Описание компакт-диска</td>
<td>409</td>
</tr>
<tr>
<td>Литература</td>
<td>411</td>
</tr>
<tr>
<td>Предметный указатель</td>
<td>412</td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2011/842.html/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>jQuery UI – плагин Autocomplete</title>
		<link>http://www.linkexchanger.su/2011/700.html</link>
		<comments>http://www.linkexchanger.su/2011/700.html#comments</comments>
		<pubDate>Mon, 04 Apr 2011 11:22:46 +0000</pubDate>
		<dc:creator>Gennady</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery UI]]></category>
		<category><![CDATA[autocomplete]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/?p=700</guid>
		<description><![CDATA[Очень давно не писал ничего в блоге и вот наконец выбрал немного времени, чтобы рассказать о виджете Autocomplete, который был включен в состав jQuery UI – надстройки над JavaScript-библиотекой jQuery.

Виджет Autocomplete помогает организовать список подходящих значений при заполнении пользователем поля ввода.
Для начала посетим страницу настраиваемой закачки на сайте jQuery UI, чтобы получить необходимые нам файлы. [...]]]></description>
			<content:encoded><![CDATA[<p>Очень давно не писал ничего в блоге и вот наконец выбрал немного времени, чтобы рассказать о виджете Autocomplete, который был включен в состав jQuery UI – надстройки над JavaScript-библиотекой jQuery.</p>
<p><img src="http://www.linkexchanger.su/wp-content/uploads/2011/04/autocomplete.jpg" alt="UI jQuery - виджет Autocomplete" /></p>
<p>Виджет Autocomplete помогает организовать список подходящих значений при заполнении пользователем поля ввода.</p>
<p><span id="more-700"></span>Для начала посетим страницу <a href="http://jqueryui.com/download">настраиваемой закачки</a> на сайте jQuery UI, чтобы получить необходимые нам файлы. Щелкаем на ссылке Deselect all component, чтобы не закачивать лишнее, а затем выбираем только то, что нам потребуется – отмечаем чекбокс Autocomplete и видим, что вместе с ним отметились чекбоксы Core, Widget и Position. Работа виджета Autocomplete зависит от этих файлов.</p>
<p>Кроме этого, справа есть выпадающий список, где можно выбрать понравившуюся тему оформления. Если все готово, кликаем кнопку Download и получаем архив. Возможности виджета можно оценить в <a href="http://jqueryui.com/demos/autocomplete/">демо-галерее</a> на сайте разработчика. Я лишь постараюсь по-русски и как можно более простым языком объяснить, как заставить все это работать.</p>
<p>Итак, сначала в разделе HEAD потребуется подключить несколько файлов, которые есть в архиве.</p>
<pre class="brush: xml;">&lt;link type=&quot;text/css&quot; href=&quot;css/ui-lightness/jquery-ui-1.8.9.custom.css&quot; rel=&quot;stylesheet&quot; /&gt;
&lt;script src=&quot;js/jquery-1.4.4.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/jquery-ui-1.8.9.custom.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</pre>
<p>Сначала мы подключили файл стилевого оформления виджета, затем файл библиотеки jQuery. Третий подключенный файл необходим, чтобы реализовать Autocomplete.</p>
<p>Виджет Autocomplete не требует сложной HTML-разметки. Достаточно всего лишь поля для ввода текста, т.е. обычного элемента input, который имеет значение text в атрибуте type. Дополнительную разметку можно добавить, чтобы использовать стили в соответствии с выбранной темой оформления.</p>
<pre class="brush: xml;">&lt;div class=&quot;ui-widget&quot;&gt;
	&lt;label for=&quot;tags&quot;&gt;Tags: &lt;/label&gt;
	&lt;input id=&quot;tags&quot; type=&quot;text&quot; /&gt;
&lt;/div&gt;</pre>
<p>Для начала разберем самый простой случай использования виджета &#8211; когда для формирования списка подсказок используются локальные данные.</p>
<pre class="brush: jscript;">&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
  var availableTags = [&quot;ActionScript&quot;,&quot;AppleScript&quot;,&quot;Asp&quot;,&quot;BASIC&quot;,
  &quot;C&quot;,&quot;C++&quot;,&quot;Clojure&quot;,&quot;COBOL&quot;,&quot;ColdFusion&quot;,&quot;Erlang&quot;,&quot;Fortran&quot;,
  &quot;Groovy&quot;,&quot;Haskell&quot;,&quot;Java&quot;,&quot;JavaScript&quot;,&quot;Lisp&quot;,&quot;Perl&quot;,&quot;PHP&quot;,
  &quot;Python&quot;,&quot;Ruby&quot;,&quot;Scala&quot;,&quot;Scheme&quot;];

  $(&quot;#tags&quot;).autocomplete({
    source: availableTags
  });
});
&lt;/script&gt;</pre>
<p>В переменной <strong>availableTags</strong> приготовили массив с подсказками. Затем выбрали элемент <strong>input</strong> по его идентификатору и применили метод <strong>autocomplete</strong>, которому сразу передали объект с настройками. Пока этот объект с единственным свойством <strong>source</strong>, которое определяет источник данных. В нашем случае указан массив <strong>availableTags</strong>.</p>
<p>На самом деле мы можем немного поднастроить виджет, используя другие свойства объекта настроек. Вот список этих свойств:</p>
<p><strong>source</strong> &#8211; опция не имеет значения по умолчанию и должна быть обязательно определена. Значением опции может являться строка, массив или функция. В любом случае в этой опции должен быть указан источник данных.<br />
<strong>minLength</strong> &#8211; значение по умолчанию 1. В этой опции указывается количество символов, которое должно быть введено в поле ввода прежде, чем активизируются подсказки. Значение 0 полезно при использовании локальных данных при списках из нескольких позиций. Это значение должно быть увеличено при использовании запросов к серверу для получения данных и при использовании больших списков, где одному введенному символу может соответствовать несколько тысяч наименований.<br />
<strong>delay</strong> &#8211; значение по умолчанию 300. В этой опции указывается количество миллисекунд, которое должно пройти после нажатия очередной клавиши, чтобы активизировался запрос на получение данных. Нулевое значение имеет смысл при использовании локальных данных. При использовании запросов к серверу нулевое значение в этой опции может породить серьезную нагрузку<br />
<strong>appendTo</strong> &#8211; значение по умолчанию ‘body’. В качестве значения этой опции может быть использован селектор jQuery. Определяет, к какому элементу должен быть добавлен выпадающий список подсказок.<br />
<strong>disabled</strong> &#8211; значение по умолчанию false. Если установить значение true, то при инициализации функциональность виджета Autocomplete будет недоступна, однако может быть включена впоследствии, например, при выполнении какого-либо условия.</p>
<p>Дальше посмотрим, как виджет может реагировать на события.</p>
<pre class="brush: jscript;">&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
  var availableTags = [&quot;ActionScript&quot;,&quot;AppleScript&quot;,&quot;Asp&quot;,&quot;BASIC&quot;,
  &quot;C&quot;,&quot;C++&quot;,&quot;Clojure&quot;,&quot;COBOL&quot;,&quot;ColdFusion&quot;,&quot;Erlang&quot;,&quot;Fortran&quot;,
  &quot;Groovy&quot;,&quot;Haskell&quot;,&quot;Java&quot;,&quot;JavaScript&quot;,&quot;Lisp&quot;,&quot;Perl&quot;,&quot;PHP&quot;,
  &quot;Python&quot;,&quot;Ruby&quot;,&quot;Scala&quot;,&quot;Scheme&quot;];
  $(&quot;#tags&quot;).autocomplete({
    source: availableTags,
    select: function(event, ui) {
      alert('Событие: ' + event.type +
            ',\nзначение: ' + ui.item.value);
    }
  });
});
&lt;/script&gt;</pre>
<p>Здесь мы добавили свойство <strong>select</strong>, где определили функцию, которая будет вызываться в тот момент, когда пользователь выберет какое-либо значение из списка подсказок. функция принимает два аргумента: первый — объект <strong>event</strong>, второй — специальный объект <strong>ui</strong>. Организовав доступ к свойствам этих объектов, можно получить полезную информацию (мы выводим ее в окне предупреждения).</p>
<p>Это не единственное событие на которое умеет реагировать виджет &#8211; вот полный их список, где указано название свойства в объекте с настройками, название события в event.type и описание события:</p>
<p><strong>create</strong> &#8211; Событие <em>autocompletecreate</em> наступает в момент инициализации.<br />
<strong>search</strong> &#8211; событие <em>autocompletesearch</em> наступает перед выполнением запроса. Если функция, определенная в этой опции вернет false, запрос не будет отправлен.<br />
<strong>open</strong> &#8211; событие	<em>autocompleteopen</em> наступает в момент, когда открывается выпадающий список подсказок.<br />
<strong>focus</strong> &#8211; событие <em>autocompletefocus</em> наступает всякий раз, когда один из пунктов списка подсказок получает фокус.<br />
<strong>select</strong> &#8211; событие <em>autocompleteselect</em> наступает, когда выбран один из пунктов списка подсказок.<br />
<strong>close</strong> &#8211; событие <em>autocompleteclose</em> наступает, когда список подсказок закры-вается. Событие наступает независимо от того, был выбран один из пунктов или нет.<br />
<strong>change</strong> &#8211; событие <em>autocompletechange</em> наступает после того, как выбран один из пунктов списка. Событие всегда наступает после close.</p>
<p>Есть у виджета и некоторые методы, с помощью которых можно еще более расширить его функциональность.</p>
<p>Для примера добавьте в HTML-разметку пару кнопок:</p>
<pre class="brush: xml;">&lt;button id=&quot;search&quot;&gt;Искать &quot;as&quot;&lt;/button&gt;
&lt;button id=&quot;close&quot;&gt;Закрыть&lt;/button&gt;
&lt;div class=&quot;ui-widget&quot;&gt;
	&lt;label for=&quot;tags&quot;&gt;Tags: &lt;/label&gt;
	&lt;input id=&quot;tags&quot; type=&quot;text&quot; /&gt;
&lt;/div&gt;</pre>
<p>И вот такой JS-код:</p>
<pre class="brush: jscript;">&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
  var availableTags = [&quot;ActionScript&quot;,&quot;AppleScript&quot;,&quot;Asp&quot;,&quot;BASIC&quot;,
  &quot;C&quot;,&quot;C++&quot;,&quot;Clojure&quot;,&quot;COBOL&quot;,&quot;ColdFusion&quot;,&quot;Erlang&quot;,&quot;Fortran&quot;,
  &quot;Groovy&quot;,&quot;Haskell&quot;,&quot;Java&quot;,&quot;JavaScript&quot;,&quot;Lisp&quot;,&quot;Perl&quot;,&quot;PHP&quot;,
  &quot;Python&quot;,&quot;Ruby&quot;,&quot;Scala&quot;,&quot;Scheme&quot;];
  $(&quot;#tags&quot;).autocomplete({
    source: availableTags,
    minLength: 0
  });
  $(&quot;#search&quot;).click(function(){
    $(&quot;#tags&quot;).autocomplete(&quot;search&quot;, &quot;as&quot;);
  });
  $(&quot;#close&quot;).click(function(){
    $(&quot;#tags&quot;).autocomplete(&quot;close&quot;);
  });
});
&lt;/script&gt;</pre>
<p>Теперь, щелкая по кнопке <strong>Искать &laquo;as&raquo;</strong> мы можем имитировать действия пользователя, как если бы он ввел символы <strong>&laquo;as&raquo;</strong> в элементе <strong>input</strong>. Щелкнув по кнопке <strong>Закрыть</strong> &#8211; закрываем список подсказок, если он был открыт ранее.</p>
<p>Ниже приведены описания всех доступных методов:</p>
<p><strong>destroy</strong> &#8211; .autocomplete( &#8216;destroy&#8217; ) полностью удаляет всю функциональность виджета Autocomplete. Возвращает элементы в состояние, предшествующее инициализации.<br />
<strong>disable</strong> &#8211; .autocomplete(&#8216;disable&#8217;) временно запрещает использование всей функциональности виджета. Вновь разрешить ее можно с помощью метода enable.<br />
<strong>enable</strong> &#8211; .autocomplete(&#8216;enable&#8217;) разрешает использование всей функциональности виджета, если ранее она была запрещена методом disable.<br />
<strong>option</strong> &#8211; .autocomplete(&#8216;option&#8217;, optionName, [value]) с помощью этого метода можно установить значение любой опции виджета после инициализации.<br />
<strong>option</strong>  &#8211; .autocomplete(&#8216;option&#8217;, optionName) с помощью этого метода можно получить значение любой опции виджета после инициализации.<br />
<strong>widget</strong> &#8211; .autocomplete(&#8216;widget&#8217;) с помощью этого метода можно получить доступ к объекту, который представляет собой элемент с функциональностью Autocomplete.<br />
<strong>search</strong> &#8211; .autocomplete(&#8217;search, [value]&#8216;) с помощью этого метода без передачи второго па-раметра можно открыть весь список. Если передать во втором параметре строку символов, то будет открыт список с подходящими подсказками.<br />
<strong>close</strong> &#8211; .autocomplete(&#8216;close&#8217;) закрывает список подсказок, если он был открыт ранее.</p>
<p>В общем теперь мы знаем как настраивать виджет и управлять им, но пока мы использовали исключительно локальные данные для формирования списка подсказок. Для изучения возможностей &#8211; подойдет, но для реальной работы &#8211; вряд ли. В реальной работе наверняка потребуется формировать подсказки из данных, хранящихся на своем сервере, а может быть и вообще не на своем <img src='http://www.linkexchanger.su/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Опция <strong>source</strong>, которая, напомню, является обязательной и определяет источник данных, может принимать также строку, где содержится url, к которому следует отправлять запрос. А еще в <strong>source</strong> можно определить свою функцию, которая будет делать, то что надо именно Вам. Вот этот, пожалуй самый гибкий способ мы и разберем. Попробуем получить в виде списка подсказок какие-либо данные с сервера <strong>geonames.org</strong></p>
<p>Я приведу полностью рабочий код и попробую разъяснить, как и что работает.</p>
<pre class="brush: xml;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; lang=&quot;ru&quot; xml:lang=&quot;ru&quot;&gt;
&lt;head&gt;
&lt;title&gt;example-17-8-4&lt;/title&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;link type=&quot;text/css&quot; href=&quot;css/ui-lightness/jquery-ui-1.8.9.custom.css&quot; rel=&quot;stylesheet&quot; /&gt;
&lt;script src=&quot;js/jquery-1.4.4.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/jquery-ui-1.8.9.custom.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;style type=&quot;text/css&quot;&gt;
.ui-autocomplete-loading {
  background: #FFF url('css/ui-lightness/images/ui-anim_basic_16x16.gif') right center no-repeat;
}
#city { width: 25em; }
#log { height: 200px; width: 600px; overflow: auto; }
&lt;/style&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(function() {
  $(&quot;#city&quot;).autocomplete({
    source: function(request,response) {
      $.ajax({
        url: &quot;http://ws.geonames.org/searchJSON&quot;,
        dataType: &quot;jsonp&quot;,
        data: {
          featureClass: &quot;P&quot;,
          style: &quot;full&quot;,
          maxRows: 12,
          name_startsWith: request.term
        },
        success: function(data) {
          response($.map(data.geonames, function(item) {
            return {
              label: item.name + &quot;, &quot; + item.countryName,
              value: item.name + &quot; (&quot; + item.countryName + &quot;)&quot; + &quot; [&quot; + item.lat + &quot;, &quot; + item.lng + &quot;]&quot;
            }
          }));
        }
      });
    },
    minLength: 3,
    select: function(event,ui) {
      $(&quot;&lt;p/&gt;&quot;).text(ui.item ? ui.item.value : &quot;Ничего не выбрано!&quot;).prependTo(&quot;#log&quot;);
      $(&quot;#log&quot;).attr(&quot;scrollTop&quot;, 0);
    }
  });
});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;ui-widget&quot;&gt;
  &lt;label for=&quot;city&quot;&gt;Город: &lt;/label&gt;&lt;input id=&quot;city&quot; /&gt;&lt;br /&gt;
  &lt;span style=&quot;font-size:.8em;&quot;&gt;Поддерживается &lt;a href=&quot;http://geonames.org&quot;&gt;geonames.org&lt;/a&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div id=&quot;log&quot; class=&quot;ui-widget ui-widget-content&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Сначала смотрим на HTML-разметку. В первом элементе <strong>div</strong> нас интересует только элемент <strong>input</strong> с идентификатором <strong>city</strong>. Сюда будем вводить начальные буквы (на латинице) населенного пункта, информацию о котором мы хотели бы получить. Элемент <strong>div</strong> с идентификатором <strong>log</strong> используем для занесения в него полученной информации.</p>
<p>Если смотреть JavaScript-код, то увидим, что объект с настройками содержит три свойства — обязательное свойство <strong>source</strong>, а также свойства <strong>minLength</strong> и <strong>select</strong>.<br />
Мы займемся рассмотрением только свойства <strong>source</strong>, где можно написать свою функцию. Эта функция принимает два аргумента. Первый аргумент — <strong>request</strong> — объект, содержащий единственное свойство <strong>term</strong>, в котором хранится строка, введенная пользователем в поле ввода. Второй аргумент — <strong>response</strong> — функция, с помощью которой будет обрабатываться полученный ответ.</p>
<p>Внутри функции, определенной в свойстве <strong>source</strong> мы имеем практически неограниченную свободу действий. А поэтому, не мудрствуя, пишем там ajax-запрос к <strong>url</strong> http://ws.geonames.org/searchJSON, в опции <strong>dataType</strong> указываем, что в ответе ожидаем получить данные в формате JSON. В опции <strong>data</strong> определяем объект с параметрами запроса, который будет отправляться на указанный <strong>url</strong> (<em>почему параметры именно такие &#8211; надо смотреть документацию по API на сервере geonames.org</em>). В последнем параметре передаем <strong>request.term</strong> &#8211; то, что ввел пользователь.</p>
<p>В следующей опции ajax-запроса &#8211; опции <strong>success</strong>, вызываем функцию обработки ответа <strong>response</strong>. В аргументе, который мы передаем этой функции, мы можем обрабатывать данные, полученные в ответе сервера так, как нам будет угодно. Мы используем метод <strong>$.map</strong> чтобы применить некоторую функцию к каждому элементу объекта, переданному в первом аргументе. Внутри функции мы можем обращаться к свойствам объекта — <strong>item.countryName</strong>, <strong>item.lng</strong>, <strong>item.lat</strong> (<em>почему свойства именно такие &#8211; см. документацию по API, которую предоставляет веб-сервис</em>). Функция, которую мы написали, для каждого элемента возвращает объект, содержащий два свойствами, которые мы определили самостоятельно, используя полученные данные. Из получившегося массива таких объектов и строится список подсказок.</p>
<p>В общем, вот так как-то&#8230; В заключение, большая человеческая просьба &#8211; в комментариях пожалуйста, можете похвалить или поругать в принципе. Если же Вы хотите задать технический вопрос, то задавайте его на <a href="http://www.linkexchanger.su/forum/">форуме jQuery</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2011/700.html/feed</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>jQuery 1.5 Released</title>
		<link>http://www.linkexchanger.su/2011/685.html</link>
		<comments>http://www.linkexchanger.su/2011/685.html#comments</comments>
		<pubDate>Sun, 06 Feb 2011 17:32:21 +0000</pubDate>
		<dc:creator>Андрей</dc:creator>
				<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/?p=685</guid>
		<description><![CDATA[В соответствии с графиком в конце января состоялся релиз очередной версии библиотеки jQuery 1.5.
В новой версии исправлено 83 бага и закрыто 460 тикетов. Дополнена документация jQuery API.
Полностью был переработан модуль AJAX. Наиболее заметные изменения коснулись метода jQuery.ajax (jQuery.get, jQuery.post и пр.), сейчас эти методы возвращают объект jqXHR, который предоставляет доступ к объекту XMLHttpRequest.
Также модуль AJAX [...]]]></description>
			<content:encoded><![CDATA[<p>В соответствии с графиком в конце января состоялся релиз очередной версии библиотеки jQuery 1.5.<span id="more-685"></span></p>
<p>В новой версии исправлено 83 бага и закрыто 460 тикетов. Дополнена документация jQuery API.</p>
<p>Полностью был переработан модуль AJAX. Наиболее заметные изменения коснулись метода jQuery.ajax (jQuery.get, jQuery.post и пр.), сейчас эти методы возвращают объект jqXHR, который предоставляет доступ к объекту XMLHttpRequest.</p>
<p>Также модуль AJAX расширен за счёт возможностей назначать упорядоченные обработчики, фильтры и транспорты данных. Эти новшества должны предоставить больше возможностей для написания новых ajax плагинов.</p>
<div style="margin-left: 20px">
<h2>Extending Ajax &#8211; расширение Ajax</h2>
<p>В jQuery 1.5 $.ajax() предоставляет три способа расширения функциональности отправки, получения и управления ajax-запросами:<br />
<strong>Prefilters</strong><br />
обработка события перед отправкой запроса.<br />
<strong>Converters</strong><br />
обработка событий, которые возникают в ответ на определенный тип полученных данных, отличающийся от ожидаемого.<br />
<strong>Transports</strong><br />
новое в 1.5, они используются при проблемах с ajax-запросами и в крайнем случае.</p>
</div>
<p>Ещё одним нововведением стали deferred objects &#8211; это инструемнт, который позволяет создавать очередь задач, которые будут выполнены позже. Таким образом становится возможно работать со значениями, которые не могут быть получены немедленно (например, при асинхронных запросах ajax), и назначать несколько обработчиков, которые будут вызваны при получении таких &laquo;отложенных&raquo; значений.</p>
<div style="margin-left: 20px">
<h2>Deferred Objects</h2>
<p>Методы создания deferred объекта: <strong>$.Deferred()</strong> &#8211; создаёт новый  deferred объект, <strong>$.when( deferreds )</strong> &#8211; принимает в качестве аргументов deferred объекты и создаёт новый, который будет выполнен после всех переданных аргументами или отменен, как только будет отменен хотя бы один из переданных аргументов.</p>
<p>Методы добавления обработчиков в очередь к deferred объекту: <strong>deferred.done( doneCallbacks )</strong> &#8211; добавить обработчик успешного выполнения, <strong>deferred.fail( failCallbacks )</strong> &#8211; добавить обработчик ошибочного завершения, <strong>deferred.then( doneCallbacks, failCallbacks )</strong> &#8211; добавить обработчики обоих типов. В эти методы аргументом можно передавать как одну функцию, так и массив из нескольких функций.</p>
<p>Методы вызова обработчиков из очереди deferred объекта: <strong>deferred.resolve( args )</strong>, <strong>deferred.resolve( context, args )</strong> &#8211; вызвать обработчики успешного выполнения, <strong>deferred.reject( args )</strong>, <strong>deferred.rejectWith( context, args )</strong> &#8211; вызвать обработчики ошибочного завершения, где <strong>args</strong> &#8211; это аргументы, передаваемые в обработчик, а <strong>context</strong> &#8211; это контекст вызова обработчиков (доступен через this внутри функции обработчика)</p>
</div>
<p>Теперь jQuery предоставляет новую функциональность &#8211; <strong>jQuery.sub()</strong>, благодаря которой можно создавать и изменять дубликат jQuery, поддерживающий весь его API. Например, можно это использовать для переопределения исходных методов jQuery без влияния на на других пользователей, вызывающих эти же методы, или создавать скрытое API для плагинов без коллизий пересечения имён объектов.</p>
<p>В этом релизе была увеличена скорость работы методов обхода DOM: .children(), .prev(), .next()</p>
<p>В заключении, команда jQuery сделала некоторые изменения во внутренней системе сборки библиотеки. Проделана работа в сторону стандартизации всех процессов сборки на серверной среде NodeJS, которая сильно впечатлила команду jQuery. Разработчики особенно ценят то, что им удалось снизить зависимость от устаревшей системы Java/Rhino и перейти на многообещающую JavaScript-среду. Дополнительно к этому также осуществлен переход к использованию UglifyJS взамен Google Closure Compiler, всвязи с чем заметны некоторые улучшения в плане размера файла библиотеки.</p>
<p>Ссылка на официальную новость: <a href="http://blog.jquery.com/2011/01/31/jquery-15-released/">JQUERY 1.5 RELEASED</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2011/685.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>jQuery Templates plugin: Template Tags</title>
		<link>http://www.linkexchanger.su/2010/644.html</link>
		<comments>http://www.linkexchanger.su/2010/644.html#comments</comments>
		<pubDate>Tue, 09 Nov 2010 12:22:25 +0000</pubDate>
		<dc:creator>Андрей</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery документация]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery Plugins]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/?p=644</guid>
		<description><![CDATA[В прошлой статье я рассказал основы использования плагина jQuery Templates plugin и обещал описать возможности синтаксиса шаблонов, чем сегодня и займусь. В этой статье помимо описания инструкций шаблонов будет много примеров, а в конце есть ссылка на демонстрационную страницу с &#171;живыми&#187; примерами &#8211; там их можно посмотреть, поредактировать, поэкспериментировать, попробовать собственные примеры.
Синтаксис шаблонов довольно функционален. [...]]]></description>
			<content:encoded><![CDATA[<p>В <a href="/2010/619.html">прошлой статье</a> я рассказал основы использования плагина <strong>jQuery Templates plugin</strong> и обещал описать возможности синтаксиса шаблонов, чем сегодня и займусь. В этой статье помимо описания инструкций шаблонов будет много примеров, а <a href="#demoLinks">в конце</a> есть ссылка на демонстрационную страницу с &laquo;живыми&raquo; примерами &#8211; там их можно посмотреть, поредактировать, поэкспериментировать, попробовать собственные примеры.</p>
<p>Синтаксис шаблонов довольно функционален. В теле шаблона разработчик может обращаться к полям объекта, к полям полей объекта, вызывать методы объекта и его полей, обращаться к внешним объектам JavaScript и jQuery, просто писать JS-выражения. Кроме всего этого внутри шаблона можно итеративно выводить коллекции, организовать условный вывод, использовать вложенные шаблоны. Но давайте обо всём по порядку.</p>
<p><span id="more-644"></span></p>
<h2>Примеры в статье</h2>
<p>Все примеры я буду приводить ключевыми кусками, чтобы не загромождать материал повторяющимися частями кода. В примере будут присутствовать <strong>текст шаблона</strong>, <strong>JSON данных</strong>, при необходимости <strong>JSON опций</strong> (параметр <strong><em>options</em></strong><em> </em>метода <strong><em>.tmpl( ) </em></strong>) и <strong>результат</strong>. В общем случае полный код примера будет выглядеть так:</p>
<pre class="brush: xml;">
&lt;script type=&quot;text/x-jquery-tmpl&quot;&gt;
    &lt;li&gt; ЭТО ТЕКСТ ШАБЛОНА &lt;/li&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
var data = [
    // ЭТО МАССИВ ДАННЫХ
];
var options = {
    // ЭТО ОПЦИИ
};
$(function() {
    // ПРИМЕНЕНИЕ ШАБЛОНА И ВЫВОД РЕЗУЛЬТАТА:
    $('script[type=&quot;text/x-jquery-tmpl&quot;]').tmpl(data, options).appendTo($('.output').empty());
});
&lt;/script&gt;
&lt;ul class=&quot;output&quot;&gt;&lt;/ul&gt;
</pre>
<p>Так будет полностью выглядеть приведенный ниже <strong>пример 1.</strong>:</p>
<pre class="brush: xml;">
&lt;script type=&quot;text/x-jquery-tmpl&quot;&gt;
    &lt;li&gt;${Name} ({{html Desc}}); вычисления: ${p1 + p2 + 10}&lt;/li&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
var data = [
    { Name: &quot;obj1&quot;, Desc: &quot;&lt;em&gt;Object one&lt;/em&gt;&quot;, p1: 1, p2: 10 },
    { Name: &quot;&lt;em&gt;obj2&lt;/em&gt;&quot;, Desc: &quot;&lt;strong&gt;Object two&lt;/strong&gt;&quot;, p1: 3.3, p2: 5 }
];
var options = {
};
$(function() {
    $('script[type=&quot;text/x-jquery-tmpl&quot;]').tmpl(data, options).appendTo($('.output').empty());
});
&lt;/script&gt;
&lt;ul class=&quot;output&quot;&gt;&lt;/ul&gt;
</pre>
<h2>Вставка данных в шаблон ${}, {{= }}, {{html }}</h2>
<p>С помощью этих инструкции можно вставить в шаблон значение поля объекта данных, результат работы метода или результат вычисления некоторого js-выражения, внутри инструкции можно обращаться к глобальным объектам JS, а также к служебным объектам, созданным при обработке шаблона.</p>
<p>Прежде чем перейти к примерам, хочу немного акцентировать внимание на сходстве и разнице этих инструкций. Все три инструкции предназначены для вывода результата в эту точку шаблона. <strong>${<em>expression</em>}</strong> и <strong>{{= <em>expression</em>}}</strong> эквивалентны (первая инструкция &#8211; это сокращённая форма второй), результат вставляется в шаблон в виде текста, если в тексте встречаются символы разметки (&lt;  &gt;  &amp; и пр.), то они будут заменены на соответствующие спецсимволы (&amp;lt;  &amp;gt;  &amp;amp; и пр.). Для вставки же разметки с сохранением html-кода нужно использовать инструкцию <strong>{{html <em>expression</em>}}</strong>.</p>
<h3>Пример 1. Вывод данных с разметкой и без</h3>
<p>Шаблон:</p>
<pre class="brush: xml;">&lt;li&gt;${Name} ({{html Desc}}); вычисления: ${p1 + p2 + 10}&lt;/li&gt;</pre>
<p>Данные:</p>
<pre class="brush: jscript;">[
    { Name: &quot;obj1&quot;, Desc: &quot;&lt;em&gt;Object one&lt;/em&gt;&quot;, p1: 1, p2: 10 },
    { Name: &quot;&lt;em&gt;obj2&lt;/em&gt;&quot;, Desc: &quot;&lt;strong&gt;Object two&lt;/strong&gt;&quot;, p1: 3.3, p2: 5 }
]</pre>
<p>Результат:</p>
<pre class="brush: xml;">&lt;ul class=&quot;output&quot;&gt;
    &lt;li&gt;obj1 (&lt;em&gt;Object one&lt;/em&gt;); вычисления: 21&lt;/li&gt;
    &lt;li&gt;&amp;lt;em&amp;gt;obj2&amp;lt;/em&amp;gt; (&lt;strong&gt;Object two&lt;/strong&gt;); вычисления: 18.3&lt;/li&gt;
&lt;/ul&gt;</pre>
<h2>Доступ к объектам и внутренние параметры шаблона</h2>
<p>Как я уже упоминал, внутри выражения можно обращаться к глобальным объектам и функциям JS, при этом шаблонизатор сам пытается определить, является указанное имя ссылкой на глобальный объект или на часть переданных данных. И конечно же, локальные данные имеют более высокий приоритет, чем глобальные. Давайте определим в документе глобальные объект testObj и функцию testFunc и попробуем их использовать:</p>
<pre class="brush: jscript;">var testObj = {
    Value: 1
};

function testFunc(i) {
    return i % 2 == 1;
}
</pre>
<h3>Пример 2. Использование глобальных объектов</h3>
<p>Шаблон:</p>
<pre class="brush: xml;">&lt;li&gt;${Name}; testObj.Value = ${testObj.Value}; testFunc(${p}) =&gt; ${testFunc(p)}&lt;/li&gt;</pre>
<p>Данные:</p>
<pre class="brush: jscript;">[
    { Name: &quot;obj1&quot;, p: 3, testObj: { Value: 20 } },
    { Name: &quot;obj2&quot;, p: 13, testFunc: function(i) { return i + 7; } }
]</pre>
<p>Результат:</p>
<pre class="brush: xml;">&lt;ul class=&quot;output&quot;&gt;
    &lt;li&gt;obj1; testObj.Value = 20; testFunc(3) =&amp;gt; true&lt;/li&gt;
    &lt;li&gt;obj2; testObj.Value = 1; testFunc(13) =&amp;gt; 20&lt;/li&gt;
&lt;/ul&gt;</pre>
<p>Внутри шаблона есть ещё доступ  к специальным объектам &#8211; внутренним параметрам шаблона: <strong>$item</strong> и <strong>$data</strong>.</p>
<p><strong>$item</strong> &#8211; представляет доступ к обрабатываемой в данный момент единице данных для вставки в шаблон, внутри этого объекта собраны и параметры, переданные пользователем, и дополнительные параметры из аргумента <em><strong>options</strong></em> функции <em><strong>.tmpl( )</strong></em>. Доступ к параметрам из данных осуществляется через вложенный объект <strong>.</strong><strong>data</strong>, а к параметрам аргумента <em><strong>options</strong></em> &#8211; напрямую, т.е. если вызвать <em><strong>$(&#8216;#myTmpl&#8217;).tmpl({ p1: 1 }, { p2: 2 })</strong></em>, то в шаблоне получить доступ к ним можно так: <em><strong>$item.data.p1</strong></em> и <em><strong>$item.p2</strong></em>.</p>
<p><strong>$data</strong> &#8211; это сокращённая версия доступа к данным, по сути это просто синоним для <em><strong>$item.data</strong></em>, в свете этого доступ в шаблоне к p1 и p2 из вызова в абзаце выше может быть таким: <em><strong>$data.p1</strong></em> и <em><strong>$item.p2</strong></em>.</p>
<h3>Пример 3. Параметр options</h3>
<p>Шаблон:</p>
<pre class="brush: xml;">&lt;li&gt;${Name}; p * 100 = ${$item.Method($data.p)}&lt;/li&gt;</pre>
<p>Данные:</p>
<pre class="brush: jscript;">[
    { Name: &quot;obj1&quot;, p: 3.3 },
    { Name: &quot;obj2&quot;, p: 0.13 }
]</pre>
<p>Опции:</p>
<pre class="brush: jscript;">{ Method: function(i) { return i * 100; } }</pre>
<p>Результат:</p>
<pre class="brush: xml;">&lt;ul class=&quot;output&quot;&gt;
    &lt;li&gt;obj1; p * 100 = 330&lt;/li&gt;
    &lt;li&gt;obj2; p * 100 = 13&lt;/li&gt;
&lt;/ul&gt;</pre>
<h2>Условная разметка в шаблоне {{if }} {{else}} {{/if}}</h2>
<p>Внутри шаблона можно отслеживать некие условия и в зависимости от них выводить тот или иной кусок. Для достижения этих целей применяются следующие комбинации инструкций:</p>
<p><strong>{{if <em>expression</em>}} tmplPart {{/if}}</strong> &#8211; простой вывод части шаблона, только если выражение истинно,<br />
<strong>{{if <em>expression</em>}} tmplPart1 {{else}} tmplPart2 {{/if}}</strong> &#8211; вывод части 1 или 2 в зависимости от истинности выражения,<br />
<strong>{{if <em>expr1</em>}} tmplPart1 {{else <em>expr2</em>}} tmplPart2 {{else}} tmplPart3</strong><strong> {{/if}}</strong> &#8211; это уже построение цепочки последовательных проверок (if .. else if .. else if .. else ..), понятное дело, что последний else без выражения необязателен. Думаю, тут всё понятно, давайте посмотрим простенький пример:</p>
<h3>Пример 4. Условный вывод</h3>
<p>Шаблон:</p>
<pre class="brush: xml;">&lt;li&gt;
{{if (
    (typeof(useFirstLastName) != &quot;undefined&quot; ? useFirstLastName : $item.defaultUseFirstLastName) &amp;&amp;
    $data.FirstName &amp;&amp; $data.LastName)}} ${FirstName + &quot; &quot; + LastName}
{{else $data.FullName}} ${FullName}
{{else $data.Name}} ${Name}
{{else}} ${$item.NoName}
{{/if}}
&lt;/li&gt;</pre>
<p>Данные:</p>
<pre class="brush: jscript;">[
    { Name: &quot;obj1&quot;, FullName: &quot;Object 1&quot;, FirstName: &quot;Object&quot;, LastName: &quot;One&quot; },
    { FirstName: &quot;Object&quot;, LastName: &quot;Two&quot;, Name: &quot;obj2&quot;, useFirstLastName: true },
    { Title: &quot;object number 3&quot; }
]</pre>
<p>Опции:</p>
<pre class="brush: jscript;">{ NoName: &quot;[noname]&quot;, defaultUseFirstLastName: false }</pre>
<p>Результат:</p>
<pre class="brush: xml;">&lt;ul class=&quot;output&quot;&gt;
    &lt;li&gt;  Object 1  &lt;/li&gt;
    &lt;li&gt;  Object Two  &lt;/li&gt;
    &lt;li&gt;  [noname]  &lt;/li&gt;
&lt;/ul&gt;</pre>
<p>Поясню, что происходит в шаблоне. Под первым условием мы проверяем, нужно ли выводить имя объекта в виде конкатенации FirstName и LastName &#8211; при этом проверяется условие внутри объекта, если оно не определено, то условие в опциях, и требуется наличие обоих свойств. Обращаясь в условии к этим свойствам через параметр <em><strong>$data</strong></em>, гарантируем их наличие именно в переданных данных, а глобальные объекты при этом игнорируются. Во втором и третьем условиях проверяем последовательно свойства FullName и Name &#8211; выводим первое попавшееся, если нет ни одного из них, то выводим &laquo;заглушку&raquo; из опций.</p>
<h2>Итеративный обход с помощью {{each }}</h2>
<p>Думаю всем знакома функция jQuery <em><strong>.each(func)</strong></em> (а есть ещё и <em><strong>$.map(array, callback)</strong></em> ) и надеюсь многим знакома конструкция JS <em><strong>for (var key in obj)</strong></em> &#8211; эти выражения совершают итеративный обход элементов коллекции. В шаблонах тоже возможен вывод коллекций поэлементно и описывается он следующей инструкцией: <strong>{{each( <em>index</em>, <em>value </em>) <em>data</em>}} <em>tmplText </em>{{/each}}</strong>. <strong>index</strong> и <strong>value</strong> &#8211; это имена параметров (указываются без кавычек) для доступа соответственно к текущему индексу и значению в коллекции. Есть и сокращённая форма этой инструкции: <strong>{{each <em>data</em>}} <em>tmplText</em> {{/each}}</strong> &#8211; при этом в тексте шаблона к текущим индексу и значению можно обратиться по именам по умолчанию: <strong>$index</strong> и <strong>$value</strong>. Выражение <strong>data</strong> должно возвращать в результате массив или объект, объект будет обработан как словарь (коллекция пар имя-значение свойств объекта). Довольно слов, посмотрим на примере:</p>
<h3>Пример 5. Вывод массива</h3>
<p>Шаблон:</p>
<pre class="brush: xml;">&lt;li&gt;
    &lt;table border=&quot;1&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot;&gt;
        &lt;tr&gt;&lt;th align=&quot;left&quot;&gt;n&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;${Expr}&lt;/th&gt;&lt;/tr&gt;
        {{each NumCollection}}
        &lt;tr&gt;&lt;td&gt;${$index}&lt;/td&gt;&lt;td&gt;${$value}&lt;/td&gt;&lt;/tr&gt;
        {{/each}}
        &lt;tr&gt;&lt;td&gt;${$item.EtcName}&lt;/td&gt;&lt;td&gt;${$item.EtcVal}&lt;/td&gt;&lt;/tr&gt;
    &lt;/table&gt;
&lt;/li&gt;</pre>
<p>Данные:</p>
<pre class="brush: jscript;">[
    { Expr: &quot;2^n&quot;, NumCollection: [ 1, 2, 4, 8, 16 ] },
    { Expr: &quot;2n-1&quot;, NumCollection: [ 1, 3, 5, 7, 9 ] },
]</pre>
<p>Опции:</p>
<pre class="brush: jscript;">{ EtcName: &quot;etc.&quot;, EtcVal: &quot;...&quot; }</pre>
<p>Результат:</p>
<pre class="brush: xml;">&lt;ul class=&quot;output&quot;&gt;
&lt;li&gt;
     &lt;table border=&quot;1&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot;&gt;
         &lt;tbody&gt;
             &lt;tr&gt;&lt;th align=&quot;left&quot;&gt;n&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;2^n&lt;/th&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;8&lt;/td&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;16&lt;/td&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;etc.&lt;/td&gt;&lt;td&gt;...&lt;/td&gt;&lt;/tr&gt;
         &lt;/tbody&gt;
    &lt;/table&gt;
&lt;/li&gt;&lt;li&gt;
     &lt;table border=&quot;1&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot;&gt;
         &lt;tbody&gt;
             &lt;tr&gt;&lt;th align=&quot;left&quot;&gt;n&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;2n-1&lt;/th&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;5&lt;/td&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;7&lt;/td&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;9&lt;/td&gt;&lt;/tr&gt;
             &lt;tr&gt;&lt;td&gt;etc.&lt;/td&gt;&lt;td&gt;...&lt;/td&gt;&lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
&lt;/li&gt;
&lt;/ul&gt;</pre>
<h3>Пример 6. Вывод объекта-словаря</h3>
<p>Шаблон:</p>
<pre class="brush: xml;">&lt;li&gt;
JSON = { {{each(key, val) $data}}{{if $item.f}},{{/if}} &quot;${key}&quot;: &quot;${val}&quot;{{if $item.f=true}}{{/if}}{{/each}} }
&lt;/li&gt;</pre>
<p>Данные:</p>
<pre class="brush: jscript;">[
    { Name: &quot;obj1&quot;, FullName: &quot;Object 1&quot;, FirstName: &quot;Object&quot;, LastName: &quot;One&quot; },
    { FirstName: &quot;Object&quot;, LastName: &quot;Two&quot;, Name: &quot;obj2&quot; },
    { Title: &quot;object number 3&quot; }
]</pre>
<p>Опции:</p>
<pre class="brush: jscript;">{ f: false }</pre>
<p>Результат:</p>
<pre class="brush: xml;">&lt;ul class=&quot;output&quot;&gt;
    &lt;li&gt; JSON = {  &quot;Name&quot;: &quot;obj1&quot;, &quot;FullName&quot;: &quot;Object 1&quot;, &quot;FirstName&quot;: &quot;Object&quot;, &quot;LastName&quot;: &quot;One&quot; } &lt;/li&gt;
    &lt;li&gt; JSON = {  &quot;FirstName&quot;: &quot;Object&quot;, &quot;LastName&quot;: &quot;Two&quot;, &quot;Name&quot;: &quot;obj2&quot; } &lt;/li&gt;
    &lt;li&gt; JSON = {  &quot;Title&quot;: &quot;object number 3&quot; } &lt;/li&gt;
&lt;/ul&gt;</pre>
<h2>Вывод шаблона в шаблоне {{tmpl }}</h2>
<p>Внутри шаблона можно использовать другие шаблоны, которые могут быть получены извне (селектором, функцией) или в виде разметки сгенерированной на месте (например, когда сами данные определяют в каком виде их надо вставить в шаблон).</p>
<p>Полный вид инструкции: <strong>{{tmpl(<em>data</em>, <em>options</em>) <em>template</em>}}</strong>.</p>
<p><em><span style="color: #ff0000">(На момент написания статьи в оф.документации показана сигнатура инструкции <span style="text-decoration: underline">{{tmpl( [data], [options] ) template}} content {{/tmpl}}</span> &#8211; это <strong>ОШИБКА</strong>, у этой инструкции нет закрывающего тега <span style="text-decoration: underline">{{/tmpl}}</span> и, соответственно, никакого содержания <span style="text-decoration: underline">content</span>)</span></em></p>
<p>Параметры <strong>data</strong> и <strong>options</strong> &#8211; являются необязательными и имеют то же назначение, что и в функции <em><strong>.tmpl(data, options)</strong></em>, если параметры опущены, то в качестве данных используется текущий объект данных <em><strong>$data</strong></em>, а <em><strong>options</strong></em> &#8211; пустой объект.<br />
Параметр <strong>template</strong> может принимать следующие значения: HTML-разметка, HTML- или jQuery-объект, строка, которая является именем скомпилированного шаблона или скомпилированный шаблон, также можно просто передать строку-селектор для jQuery (это недокументированная возможность, но она фигурирует в примерах).</p>
<h3>Пример 7. Использование сгенерированного шаблона</h3>
<p>Шаблон:</p>
<pre class="brush: xml;">&lt;li&gt; {{tmpl $item.lt+tag+$item.gt+$item.tp+&quot;{content}&quot;+$item.lt+&quot;/&quot;+tag+$item.gt}} &lt;/li&gt;</pre>
<p>Данные:</p>
<pre class="brush: jscript;">[
    { tag: &quot;strong&quot;, content: &quot;&lt;em&gt;Hello&lt;/em&gt;, &quot; },
    { tag: &quot;em&quot;, content: &quot;World!&quot; }
]</pre>
<p>Опции:</p>
<pre class="brush: jscript;">{ lt: &quot;&lt;&quot;, gt: &quot;&gt;&quot;, tp: &quot;$&quot; }</pre>
<p>Результат:</p>
<pre class="brush: xml;">&lt;ul class=&quot;output&quot;&gt;
    &lt;li&gt; &lt;strong&gt;&amp;lt;em&amp;gt;Hello&amp;lt;/em&amp;gt;, &lt;/strong&gt; &lt;/li&gt;
    &lt;li&gt; &lt;em&gt;World!&lt;/em&gt; &lt;/li&gt;
&lt;/ul&gt;</pre>
<p>В шаблоне этого примера при генерировании вложенного шаблона используются строковые значение &laquo;&lt;&raquo;, &laquo;&gt;&raquo;, &laquo;$&raquo; в виде переменных, это сделано для того, чтобы они не воспринимались как разметка и инструкции внешним шаблоном.</p>
<h3>Пример 8. Использование шаблона внутри шаблона</h3>
<p>Шаблон:</p>
<pre class="brush: xml;">&lt;li&gt;${Name} {{if Items}}&lt;ul&gt;{{tmpl(Items) '#tmplSelector'}}&lt;/ul&gt;{{/if}}&lt;/li&gt;</pre>
<p>Тут строку &#8216;#tmplSelector&#8217; &#8211; следует заменить на корректный селектор (или функцию) получения текущего шаблона. Для моих &laquo;живых&raquo; примеров можно использовать такой шаблон:</p>
<pre class="brush: xml;">&lt;li&gt;${Name} {{if Items}}&lt;ul&gt;{{tmpl(Items) $('#example8 script[type=&quot;text/x-jquery-tmpl&quot;]')}}&lt;/ul&gt;{{/if}}&lt;/li&gt;</pre>
<p>, в нём будет применен начальный шаблон, или</p>
<pre class="brush: xml;">&lt;li&gt;${Name} {{if Items}}&lt;ul&gt;{{tmpl(Items) $('#example8')[0].DemoData.Tmpl}}&lt;/ul&gt;{{/if}}&lt;/li&gt;</pre>
<p>, в нём будет применён отредактированный шаблон &#8211; полностью &laquo;живой&raquo; пример.</p>
<p>Данные:</p>
<pre class="brush: jscript;">[
    { Name: &quot;obj1&quot;, Items: [ { Name: &quot;obj11&quot;, Items: [ { Name: &quot;obj111&quot; }, { Name: &quot;obj112&quot; } ] }, { Name: &quot;obj12&quot; } ] },
    { Name: &quot;obj2&quot; }
]</pre>
<p>Опции:</p>
<pre class="brush: jscript;">{ }</pre>
<p>Результат:</p>
<pre class="brush: xml;">&lt;ul class=&quot;output&quot;&gt;
    &lt;li&gt;obj1 &lt;ul&gt;
        &lt;li&gt;obj11 &lt;ul&gt;
            &lt;li&gt;obj111 &lt;/li&gt;
            &lt;li&gt;obj112 &lt;/li&gt;
        &lt;/ul&gt;&lt;/li&gt;
        &lt;li&gt;obj12 &lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;
    &lt;li&gt;obj2 &lt;/li&gt;
&lt;/ul&gt;</pre>
<p>В этом примере определён рекурсивный шаблон.</p>
<h2>Шаблон в шаблоне с HTML-содержанием внутри {{wrap }}</h2>
<p><strong>{{wrap (<em>data</em>, <em>options</em>) <em>template</em>}} <em>HTMLcontent </em>{{/wrap}}</strong> &#8211; эта инструкция очень похожа на инструкцию <em><strong>{{tmpl }}</strong></em>, её параметры <em><strong>data</strong></em>, <em><strong>options</strong></em> и <em><strong>template</strong></em> имеют то же назначение. Отличие инструкции <em><strong>{{wrap }}</strong></em> от <em><strong>{{tmpl }}</strong></em> в том, что она может включать HTML-содержание и затем это содержание можно использовать в применяемом шаблоне.</p>
<p>В шаблоне, который передаётся параметром <em><strong>template</strong></em>, можно достать HTML-разметку, заключённую между <em><strong>{{wrap }}</strong></em> и <em><strong>{{/wrap}}</strong></em> с помощью метода <em><strong>$item.html(filter, onlyText)</strong></em>. Первым аргументом можно наложить фильтр в виде селектора jQuery на выбираемые из разметки элементы, а вторым аргументом можно указать, что нужно в результате получить только текст верхнего выбранного элемента.</p>
<h3>Пример 9. Использование {{wrap }}</h3>
<pre class="brush: xml;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;style&gt;
table { border-collapse:collapse; width:380px; background-color:#f8f8f8; border:2px solid blue; margin:5px; } table td { border:1px solid blue; padding:3px; }
&lt;/style&gt;
  &lt;script src=&quot;http://code.jquery.com/jquery-latest.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;http://nje.github.com/jquery-tmpl/jquery.tmpl.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;script id=&quot;myTmpl&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
    The following wraps and reorders some HTML content:
    {{wrap &quot;#tableWrapper&quot;}}
        &lt;h3&gt;One&lt;/h3&gt;
        &lt;div&gt;
            First &lt;b&gt;content&lt;/b&gt;
        &lt;/div&gt;
        &lt;h3&gt;Two&lt;/h3&gt;
        &lt;div&gt;
            And &lt;em&gt;more&lt;/em&gt; &lt;b&gt;content&lt;/b&gt;...
        &lt;/div&gt;
    {{/wrap}}

    And this wraps different HTML content:
    {{wrap &quot;#tableWrapper&quot;}}
        &lt;div&gt;
            First &lt;b&gt;div&lt;/b&gt;
        &lt;/div&gt;
        &lt;div&gt;
            Second &lt;b&gt;div&lt;/b&gt;
        &lt;/div&gt;
        &lt;div&gt;
            Third &lt;b&gt;div&lt;/b&gt;
        &lt;/div&gt;
        &lt;h3&gt;first h3&lt;/h3&gt;
        &lt;h3&gt;second h3&lt;/h3&gt;
        &lt;h3&gt;third h3&lt;/h3&gt;
    {{/wrap}}
&lt;/script&gt;

&lt;script id=&quot;tableWrapper&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
    &lt;table&gt;&lt;tbody&gt;
        &lt;tr&gt;
            {{each $item.html(&quot;h3&quot;, true)}}
                &lt;td&gt;
                    ${$value}
                &lt;/td&gt;
            {{/each}}
        &lt;/tr&gt;
        &lt;tr&gt;
            {{each $item.html(&quot;div&quot;)}}
                &lt;td&gt;
                    {{html $value}}
                &lt;/td&gt;
            {{/each}}
        &lt;/tr&gt;
    &lt;/tbody&gt;&lt;/table&gt;
&lt;/script&gt;

&lt;div id=&quot;myWrappedView&quot;&gt;&lt;/div&gt;

&lt;script&gt;
$( &quot;#myTmpl&quot; ).tmpl()
    .appendTo( &quot;#myWrappedView&quot; );
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Этот пример взят со страницы оф. документации по этой инструкции шаблона. В &laquo;живых&raquo; примерах приведена переработанная под их специфику версия.</p>
<h2>Комментарии в шаблонах {{! }}</h2>
<p>В шаблонах можно вставлять комментарии разработчика, которые не будут попадать в результат, делается это очень просто, а именно так:</p>
<pre class="brush: xml;">{{! это текст комментария}}</pre>
<h2><a name="demoLinks"></a>&laquo;Живые&raquo; примеры из статьи</h2>
<p>По этому адресу страница доступна online: <a href="http://zalab.net/projects/jquery/demo/tmpl/" target="_blank">http://zalab.net/projects/jquery/demo/tmpl/</a><br />
А по этой ссылке можно загрузить эту страничку в архиве: <a href="http://www.linkexchanger.su/wp-content/uploads/2010/11/jq.tmpl_.live_.examples.zip">jq.tmpl.live.examples.zip (33 KB)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2010/644.html/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Официальные плагины jQuery: Templates plugin</title>
		<link>http://www.linkexchanger.su/2010/619.html</link>
		<comments>http://www.linkexchanger.su/2010/619.html#comments</comments>
		<pubDate>Mon, 01 Nov 2010 13:13:03 +0000</pubDate>
		<dc:creator>Андрей</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery документация]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[jQuery Plugins]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/?p=619</guid>
		<description><![CDATA[4 октября 2010 года была опубликована запись в официальном блоге jQuery об анонсе трёх плагинов jQuery, созданных при поддержке команды Microsoft. Эти плагины &#8211; плагин шаблонов (the jQuery Templates plugin), плагин привязки данных (the jQuery Data Link plugin) и плагин глобализации (the jQuery Globalization plugin) &#8211; получили статус “Официальные плагины проекта jQuery” (officially supported plugins [...]]]></description>
			<content:encoded><![CDATA[<p>4 октября 2010 года была опубликована <a href="http://blog.jquery.com/2010/10/04/new-official-jquery-plugins-provide-templating-data-linking-and-globalization/">запись в официальном блоге jQuery</a> об анонсе трёх плагинов jQuery, созданных при поддержке команды Microsoft. Эти плагины &#8211; <strong>плагин шаблонов (the jQuery Templates plugin)</strong>, <strong>плагин привязки данных (the jQuery Data Link plugin)</strong> и <strong>плагин глобализации (the jQuery Globalization plugin)</strong> &#8211; получили статус “Официальные плагины проекта jQuery” (officially supported plugins of the jQuery project).</p>
<p>Плагин шаблонов используется при необходимости вывести объект данных или массив объектов в разметку страницы. Плагин привязки данных нужен для связи объектов с элементами страницы и синхронного изменения значений. Плагин глобализации позволяет выводить такие данные, как числа, дата и время, сумма денег и т.п., на страницу в соответствии с форматом текущего языка.</p>
<p>Следует отметить, что команда Microsoft использовала свои немалые наработки в этих направлениях, как и команда проекта jQuery, и при хорошо сложившемся взаимодействии получились, на мой взгляд, отличные инструменты для разработчиков. В подтверждение моего мнения могу добавить, что разработчики jQuery анонсировали включение плагинов шаблонов и привязки данных в ядро библиотеки jQuery уже версии 1.5, а плагина глобализации &#8211; в соответствующую версию jQuery UI. Плагины пока ещё не получили статус релиза, но уже активно ведется написание документации на сайте <a href="http://api.jquery.com/">http://api.jquery.com</a>. К слову, команда Microsoft последовала традициям разработки jQuery и разместила материалы по разработке плагинов на github.com, где доступны описание и исходники плагинов.</p>
<p>В этой статье я расскажу немного о плагине шаблонов.<br />
<span id="more-619"></span></p>
<h2>jQuery Templates plugin</h2>
<p>Начнём с простенького примера:</p>
<pre class="brush: xml;">&lt;script id=&quot;movieTemplate&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
  &lt;li&gt;&lt;b&gt;${Name}&lt;/b&gt; (${ReleaseYear})&lt;/li&gt;
&lt;/script&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
var movies = [
  { Name: &quot;The Red Violin&quot;, ReleaseYear: &quot;1998&quot; },
  { Name: &quot;Eyes Wide Shut&quot;, ReleaseYear: &quot;1999&quot; },
  { Name: &quot;The Inheritance&quot;, ReleaseYear: &quot;1976&quot; }
];

$( &quot;#movieTemplate&quot; ).tmpl( movies )
    .appendTo( &quot;#movieList&quot; );
&lt;/script&gt;

&lt;ul id=&quot;movieList&quot;&gt;&lt;/ul&gt;</pre>
<p>Итак, в примере разработчик страницы описал шаблон для вывода объектов в виде разметки (первый элемент <strong><em>script</em></strong>), потом получил откуда-то массив объектов <strong><em>movies </em></strong>и вызвал инструкцию сгенерировать нужную разметку по шаблону, взяв данные из предоставленного массива объектов, а результат добавить в конец списка <strong><em>#movieList</em></strong>.<br />
В результате работы плагина мы получим такую разметку:</p>
<pre class="brush: xml;">&lt;ul id=&quot;movieList&quot;&gt;
  &lt;li&gt;&lt;b&gt;The Red Violin&lt;/b&gt; (1998)&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Eyes Wide Shut&lt;/b&gt; (1999)&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;The Inheritance&lt;/b&gt; (1976)&lt;/li&gt;
&lt;/ul&gt;</pre>
<p>А теперь по сути вопроса.<br />
<strong> Что делает плагин?</strong><br />
Плагин получает на вход строку шаблона и множество объектов (или один объект), которые нужно вывести в строку (или разметку) с форматированием.<br />
<strong> Где это применяется?</strong><br />
В основном этот плагин полезен при динамическом выводе объектов JS на страницу, объекты могут быть получены самыми разными способами, например, при разчётах или по результатам каких-то действий пользователя и, конечно самый часто приводимый пример, в виде JSON в ответе сервера на AJAX запрос.</p>
<h3>Методы плагина</h3>
<p><strong><span style="text-decoration: underline">.tmpl( [ data ], [ options ] )</span></strong><br />
Получает содержимое первого выбранного элемента и использует его в качестве шаблона для форматированного вывода указанных данных.<br />
<strong><em> data </em></strong> &#8211; данные для вывода в шаблон (объект или массив объектов).<br />
<strong><em> options </em></strong> &#8211; опционально, определённое пользователем расширение в виде пар ключ-значение для объекта вывода в шаблон.<br />
<strong><span style="text-decoration: underline"> jQuery.tmpl(template, [ data ], [ options ])</span></strong><br />
Использует указанный шаблон для форматированного вывода указанных данных.<br />
<strong><em> template </em></strong> &#8211; шаблон для форматирования данных, может быть одного из следующих типов: строка с разметкой, HTML-элемент (в том числе и в jQuery-обёртке), строка, соответствующая имени ранее скомпилированного шаблона.<br />
<strong><em> data, options</em></strong> &#8211; имеют то же значение, что и выше<br />
<strong><span style="text-decoration: underline"> .tmplItem()</span></strong><br />
Возвращает для первого выбранного элемента структуру (объект) с результатами работы шаблонизатора. Возвращаемый методом объект обеспечивает доступ к:</p>
<ul>
<li> HTML-частям, из которых состоит шаблон</li>
<li> ассоциированной единице переданных данных</li>
<li> родительскому шаблону, если текущий шаблон является вложенным</li>
<li> текущему шаблону, использованному для вывода</li>
<li> определённому пользователем расширению (полям и методам), переданным в параметр options метода tmpl()</li>
</ul>
<p>Этот метод используется, напрмер, когда после проведенного форматирования данных требуется узнать, а какие же данные были использованы при формировании некоторого куска разметки, или для обновления куска разметки с использованием новых данных.<br />
<strong><span style="text-decoration: underline"> jQuery.tmplItem( element )</span></strong><br />
Аналогичен методу .tmplItem, только структура с результатами работы шаблонизатора ищется для элемента <strong><em>element </em></strong> (HTML-элемент, в том числе и в jQuery-обёртке).<br />
<strong><span style="text-decoration: underline"> .template( [ name ] )</span></strong><br />
Метод делает из содержимого первого выбранного элемента скомпилированную версию шаблона форматирования.<br />
<strong><em> name </em></strong> &#8211; необязательно имя шаблона, если имя указано, то потом можно использовать его для обращения к этому шаблону в методе <strong><em>jQuery.tmpl(name, data, options)</em></strong><br />
<strong><span style="text-decoration: underline"> jQuery.template( [ name, ] template )</span></strong><br />
Метод аналогичен описанному выше, только здесь шаблон передаётся в качестве параметра <strong><em>template </em></strong> &#8211; это может быть строка, строка с разметкой, HTML-элемент (в том числе и в jQuery-обёртке).</p>
<h3>Синтаксис шаблона</h3>
<p>Я вкратце приведу описание нескольких самых основных элементов шаблона, остальное надеюсь более подробно описать в следующей статье (если будет положительный отклик на эту статью)<br />
<strong><span style="text-decoration: underline"> ${fieldNameOrExpression} и {{= fieldNameOrExpression}}</span></strong><br />
Позволяет вставить в шаблон значение поля (свойства) объекта данных, может быть также использовано для вставки результата метода или js-выражения. Напрмер, <strong><em>&laquo;${Name}&raquo;</em></strong> &#8211; вставит в шаблон значение поля obj.Name, а при том, что Languages &#8211; это поле объекта, которому присвоен массив, <strong><em>&laquo;${Languages.length}&raquo;</em></strong> &#8211; вставит в шаблон длину этого массива, и наконец, если у объекта есть метод getLanguages с двумя параметрами, то <strong><em>&laquo;${getLanguages(Languages, &#8216; &#8211; &#8216;)}&raquo;</em></strong> &#8211; вставит в шаблон результат работы этого метода.<br />
<strong><span style="text-decoration: underline"> {{html fieldNameOrExpression}}</span></strong><br />
Элемент шаблона ${field} (или {{= field}}) вставляет в результат значение указанного поля в виде текста, т.е. если в строке будут HTML-теги, то они будут закодированы, а не преобразованы в разметку. Если вам требуется вставить данные в шаблон именно в виде HTML-разметки, то надо использовать синтаксис <strong><em>{{html &lt;что нужно вставить&gt;}}</em></strong>.<br />
Для начала работы с плагином уже достаточно рассказано, могу лишь добавить, что синтаксис шаблонов позволяет вставлять вложенные шаблоны, условные инструкции, обращаться к некоторым объектам JS и jQuery и ещё кое-что&#8230; Остальное &#8211; материал будущей статьи.</p>
<h3>Источники</h3>
<p>Статья написана по материалам, найденным во всемирной паутине. В основном это перевод официальной документации. Оригиналы можно посмотреть по следующим ссылкам:</p>
<ul>
<li> <a href="http://blog.jquery.com/2010/10/04/new-official-jquery-plugins-provide-templating-data-linking-and-globalization/"> Сообщение в блоге jQuery</a> и <a href="http://weblogs.asp.net/scottgu/archive/2010/10/04/jquery-templates-data-link-and-globalization-accepted-as-official-jquery-plugins.aspx"> в блогах MS</a></li>
<li> <a href="http://api.jquery.com/category/plugins/templates/"> Страница документации плагина</a> (примеры взяты оттуда)</li>
</ul>
<h3>Об авторе</h3>
<p>Зовут меня Зайцев Андрей, <a href="http://blog.zalab.net/">мой маленький блог</a>, профиль на форуме <a href="http://linkexchanger.su/forum/memberlist.php?mode=viewprofile&amp;u=106">zandroid</a></p>
<p>Это моя первая статья в этом блоге, надеюсь, и не последняя <img src='http://www.linkexchanger.su/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Большое спасибо Геннадию за возможность публикации и за полезные советы по написанию и оформлению материала.</p>
<h3>Примеры</h3>
<p><strong>Пример 1: Динамическое переключение применяемого шаблона</strong></p>
<pre class="brush: xml;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;style&gt;
    table { cursor:pointer; border-collapse:collapse; border:2px solid blue; width:300px; margin:8px; }
    table tr { border:1px solid blue; color:blue; background-color:#f8f8f8; } table td { padding:3px; } table tr:hover { color:red; }
    .movieDetail { background-color:yellow; } .movieDetail.row1 { border-bottom:none; } .movieDetail.row2 { border-top:none; }
  &lt;/style&gt;
  &lt;script src=&quot;http://code.jquery.com/jquery-latest.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;http://nje.github.com/jquery-tmpl/jquery.tmpl.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;script id=&quot;summaryTemplate&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
  &lt;tr class='movieSummary'&gt;&lt;td colspan='2'&gt;${Name}&lt;/td&gt;&lt;/tr&gt;
&lt;/script&gt;

&lt;script id=&quot;detailTemplate&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
  &lt;tr class='movieDetail row1'&gt;&lt;td colspan='2'&gt;${Name}&lt;/td&gt;&lt;/tr&gt;&lt;tr class='movieDetail row2'&gt;&lt;td&gt;${ReleaseYear}&lt;/td&gt;&lt;td&gt;Director: ${Director}&lt;/td&gt;&lt;/tr&gt;
&lt;/script&gt;

Click for details:
&lt;table&gt;&lt;tbody id=&quot;movieList&quot;&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
var movies = [
  { Name: &quot;The Red Violin&quot;, ReleaseYear: &quot;1998&quot;, Director: &quot;François Girard&quot; },
  { Name: &quot;Eyes Wide Shut&quot;, ReleaseYear: &quot;1999&quot;, Director: &quot;Stanley Kubrick&quot; },
  { Name: &quot;The Inheritance&quot;, ReleaseYear: &quot;1976&quot;, Director: &quot;Mauro Bolognini&quot; }
];
var selectedItem = null;

/* Render the summaryTemplate with the &quot;movies&quot; data */
$( &quot;#summaryTemplate&quot; ).tmpl( movies ).appendTo( &quot;#movieList&quot; );

/* Add onclick handlers for movie template items
using the summary or details template */
$(&quot;#movieList&quot;)
  .delegate( &quot;.movieSummary&quot;, &quot;click&quot;, function () {
    if (selectedItem) {
      // Set the template on the previously selected item
      // back to the summary template
      selectedItem.tmpl = $( &quot;#summaryTemplate&quot; ).template();
      selectedItem.update();
    }
    /* Get the data structure for the template item
       which this clicked element belongs to, and make
       it the selected item */
    selectedItem = $.tmplItem(this);

    /* Set the template on this item to the detail template */
    selectedItem.tmpl = $( &quot;#detailTemplate&quot; ).template();
    selectedItem.update();
  })
  .delegate( &quot;.movieDetail&quot;, &quot;click&quot;, function () {
    /* Set the template on this item to the summary template */
    selectedItem.tmpl = $( &quot;#summaryTemplate&quot; ).template();
    selectedItem.update();
    selectedItem = null;
  });
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Довольно сложный и объемный, в нём используются сразу несколько методов плагина, взят с <a href="http://api.jquery.com/jquery.tmplitem/"> этой страницы</a>.</p>
<p><strong>Пример 2: Вставка данных с разметкой в шаблон</strong></p>
<pre class="brush: xml;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;style&gt;
    .role {font-weight:bold;font-style: italic;} #movieContainer {padding-left: 8px;}
  &lt;/style&gt;
  &lt;script src=&quot;http://code.jquery.com/jquery-latest.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;http://nje.github.com/jquery-tmpl/jquery.tmpl.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;script id=&quot;movieTemplate&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
  &lt;h4&gt;${Name}&lt;/h4&gt;
  &lt;p&gt;{{html Synopsis}}&lt;/p&gt;
&lt;/script&gt;

&lt;div id=&quot;movieContainer&quot;&gt;&lt;/div&gt;

&lt;script&gt;
/* The Synopsis data field contains HTML markup. */
var movie = {
  Name: &quot;Meet Joe Black&quot;,
  Synopsis: &quot;The &lt;span class='role'&gt;grim reaper&lt;/span&gt; (&lt;a href='http://www.netflix.com/RoleDisplay/Brad_Pitt/73919'&gt;Brad Pitt&lt;/a&gt;) visits &lt;span class='role'&gt;Bill Parrish&lt;/span&gt; (&lt;a href='http://www.netflix.com/RoleDisplay/Anthony_Hopkins/43014'&gt;Anthony Hopkins&lt;/a&gt;)...&quot;
};

/* Render the template with the movie data.
   The template uses the {{html}} template tag
   to  insert the Synopsis HTML markup data. */
$( &quot;#movieTemplate&quot; ).tmpl( movie )
  .appendTo( &quot;#movieContainer&quot; );
&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p>В этом примере в шаблон добавляются как простые строковые значения полей, так и значения с разметкой, взято вот с <a href="http://api.jquery.com/template-tag-html/"> этой страницы</a>.</p>
<h3>P.S.</h3>
<p>Примеры не стал расписывать, если аудитория поддержит мои начинания, то можно пошагово расписать что, как и почему, и привести ещё несколько примерчиков.</p>
<p>Вопросы по плагину прошу задавать на <a href="/forum/">форуме</a>, если есть комменты именно по статье &#8211; то комментируйте ниже.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2010/619.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>jqGrid Часть III: Расширенные возможности</title>
		<link>http://www.linkexchanger.su/2010/523.html</link>
		<comments>http://www.linkexchanger.su/2010/523.html#comments</comments>
		<pubDate>Sun, 23 May 2010 15:26:04 +0000</pubDate>
		<dc:creator>TRAHOMOTO</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery UI]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/?p=523</guid>
		<description><![CDATA[Введение
Я рад приветствовать вас, дорогие читатели в третьей статье цикла, посвященного плагину jqGrid. Прошу прощения за столь долгое отсутствие, сейчас все свободное время отдаю изучению и освоению другого монстра &#8211; ExtJS.
Напомню, что в предыдущей статье (jqGrid Часть II: Базовые возможности) мы перешли от basic к advanced уровню использования этого замечательного плагина. Но прежде чем мы [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Введение</strong><br />
Я рад приветствовать вас, дорогие читатели в третьей статье цикла, посвященного плагину jqGrid. Прошу прощения за столь долгое отсутствие, сейчас все свободное время отдаю изучению и освоению другого монстра &#8211; ExtJS.<br />
Напомню, что в предыдущей статье (<a href="http://www.linkexchanger.su/2010/486.html">jqGrid Часть II: Базовые возможности</a>) мы перешли от basic к advanced уровню использования этого замечательного плагина. Но прежде чем мы начнем я хотел бы сообщить, что jqGrid обновилась до версии 3.6.5 и соответственно и мы будем использовать новую версию.</p>
<p>Итак план работ на эту статью:</p>
<ul>
<li><strong><a href="http://www.linkexchanger.su/2010/523.html#p1">jqGrid и &laquo;деревья&raquo;</a></strong>
<ul>
<li><a href="http://www.linkexchanger.su/2010/523.html#p1.1">Общие сведения о деревьях</a></li>
<li><a href="http://www.linkexchanger.su/2010/523.html#p1.2">jqGrid и SQL деревья</a></li>
<li><a href="http://www.linkexchanger.su/2010/523.html#p1.3">jqGrid и статические деревья</a></li>
</ul>
</li>
<li><strong><a href="http://www.linkexchanger.su/2010/523.html#p2">Связывание данных в jqGrid</a></strong>
<ul>
<li><a href="http://www.linkexchanger.su/2010/523.html#p2.1">Простая подтаблица (subgrid)</a></li>
<li><a href="http://www.linkexchanger.su/2010/523.html#p2.2">jqGrid как subgrid</a></li>
<li><a href="http://www.linkexchanger.su/2010/523.html#p2.3">Ведущая и ведомая jqGrid</a></li>
</ul>
</li>
</ul>
<p><span id="more-523"></span><br />
<a title="p1" name="p1"></a><strong>I.jqGrid и &laquo;деревья&raquo;</strong></p>
<p><a title="p1.1" name="p1.1"></a><strong>1) Краткие сведения о деревьях</strong><br />
Конечно здесь речь пойдет не о садово-огородных работах, а об представлении древовидных структур данных. В очередной раз обратимся за определением к Википедии:</p>
<p><strong>Древовидная структура</strong> является одним из способов представления иерархической структуры в графическом виде. <strong>Древовидной структурой</strong> называется благодаря тому, что граф выглядит как перевернутое дерево. По этой же причине говорят, что корневой узел (корень) находится на самом верху, а листья — внизу.</p>
<p>В принципе более или менее сносное определение, несмотря на то, что оно навивает академическую скуку я все же настоятельно рекомендую ознакомиться с материалом по древовидным структурам. Поверьте моему не большому опыту, абсолютно каждый программист рано или поздно станет перед необходимостью использовать дерево, и тут одним из помошников может стать jqGrid. Плагин может работать с двумя самыми распространенными в вычислительной технике типами деревьев: на основе &laquo;вложенных множеств&raquo; (Nested Sets) и &laquo;матрицы смежностей&raquo; (adjacency matrix). Вообще говоря тема деревьев очень серьезна, это один из разделов теории графов на изучение которых отводится не одна лекция в ВУЗах, но от себя посоветую те материалы которые мне в свое время очень помогли. Столкнувшись впервые с проблемой хранения деревьев я наткнулся на материал по подходу вложенных множеств (<a href="http://phpclub.ru/detail/article/db_tree">Хранение древовидных структур в Базах данных</a>) и сразу же остановился на нем, наверное потому что для работы с таким деревом существует готовый PHP класс. Но в процессе написания статьи я все же прочел статью <a href="http://phpclub.ru/detail/article/2002-06-03">Работа с &laquo;MySQL. Деревья&raquo;</a> в которой рассматривается подход матрицы смежностей.</p>
<p>Думаю здесь общие сведения следует закончить и перейти к практическому рассмотрению. </p>
<p><a title="p1.2" name="p1.2"></a><strong>2) jqGrid и SQL деревья</strong><br />
Для того, чтобы jqGrid могла работать с древовидными структурами, она должна быть загружена с модулем <strong>Tree Grid</strong>. Плагин может работать с обоими типами деревьев, упомянутых в предыдущем пункте. При этом jqGrid может работать с деревьями подгрузив все дерево за один раз или же подгружая ветви и листья по мере необходимости. Собственно загрузку дерева за один раз я рассматривать не буду, не интересно, а вот автоподгрузку мы разберем детально. И на этой ноте давайте перейдем к просмотру <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p3e1.html">ДЕМО3.1</a>, <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/files/demo3.1.zip">ссылка для скачивания</a> </p>
<pre class="brush: jscript;">
$(function(){
     $('#table_nested').jqGrid({
                     treeGrid: true,
                     treeGridModel: 'nested',
                     ExpandColumn: 'title',
                     ExpandColClick: true,
                     url: 'p3e1_n.php',
                     datatype: &quot;json&quot;,
                     mtype: &quot;POST&quot;,
                     colNames:[&quot;id&quot;,&quot;Раздел&quot;],
                     colModel:[
                                   {name:'cid',index:'cid', width:1, hidden:true, key:true},
                                   {name:'title',index:'title', width:180}
                                  ],
                     treeIcons: {plus:'ui-icon-folder-collapsed',minus:'ui-icon-folder-open',leaf:'ui-icon-document'},
                     height: 'auto',
                     caption: 'вложенныe множества',
                     hidegrid: false
     });

     $('#table_adjacency').jqGrid({
                     treeGrid: true,
                     treeGridModel: 'adjacency',
                     ExpandColumn: 'title',
                     ExpandColClick: true,
                     url: 'p3e1_a.php',
                     datatype: &quot;json&quot;,
                     mtype: &quot;POST&quot;,
                     colNames:[&quot;cid&quot;,&quot;Раздел&quot;],
                     colModel:[
                                   {name:'cid',index:'cid', width:1, hidden:true, key:true},
                                   {name:'title',index:'title', width:180}
                                   ],
                     treeIcons: {plus:'ui-icon-circle-plus',minus:'ui-icon-circle-minus',leaf:'ui-icon-person'},
                     height: 'auto',
                     caption:'матрица смежностей',
                     hidegrid: false
    });
});
</pre>
<p>Настройки обоих таблиц идентичны, но имеется ряд свойств, отличающих эти экземпляры от рассмотренных в предыдущих статьях.</p>
<ul>
<li><strong>treeGrid: true</strong> &#8211; самый главный параметр, указывает что jqGrig будет работать с древовидной структурой, а не с простыми табличными данными</li>
<li><strong>treeGridModel: &#8216;adjacency&#8217; / &#8216;nested&#8217;</strong> &#8211; это свойство определяет какой алгоритм дерева использовать</li>
<li><strong>ExpandColumn: &#8216;title&#8217;</strong> &#8211; определяет при клике по какому столбцу происходит открытие и(или) загрузка ветви</li>
<li><strong>ExpandColClick: true</strong> &#8211; необходимо, чтобы открытие ветви происходило при клике на колонку, а не на иконку</li>
<li><strong>colModel:[... key:true},...]</strong> &#8211; свойство <strong>key</strong> в массиве colModel позволяет указать данные какого столбца следует использовать как уникальный идентификатор записи при запросе данных с сервера. Т.е. благодаря этому свойству, можно переопределить идентификатор. Но только в одном столбце может быть указан <strong>key</strong>. Плагин будет использовать первый, найденный столбец как ключевой.</li>
<li><strong>treeIcons:</strong> &#8211; позволяет переопределить стандартные (<em>{plus:&#8217;ui-icon-triangle-1-e&#8217;,minus:&#8217;ui-icon-triangle-1-s&#8217;,leaf:&#8217;ui-icon-radio-off&#8217;}</em>) иконки листьев и ветвей.</li>
</ul>
<p>С не описанными свойства мы знакомы из предыдущих статей, а другие свойства и методы, характерные только для работы с jqGrid в качестве дерева можно посмотреть на странице <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:treegrid">TreeGrid</a>. </p>
<p>Прежде чем перейдем к рассмотрению серверных скриптов давайте немного разберемся как работает плагин. Сразу после инициализации, таблица отправляет запрос к серверу, при этом передает следующие данные и ждет ответа сервера:</p>
<blockquote><p><strong>В режиме &#8216;nested&#8217; (на примере метода POST)</strong></p>
<ul>
<li><strong>POST['nodeid']</strong> &#8211; идентификатор узла (ветви)</li>
<li><strong>POST['n_left']</strong> &#8211; позиция узла &laquo;слева&raquo;</li>
<li><strong>POST['n_right']</strong> &#8211; позиция узла &laquo;справа&raquo;</li>
<li><strong>POST['n_level']</strong> &#8211; уровень вложенности узла</li>
</ul>
</blockquote>
<p></p>
<blockquote><p><strong>В режиме &#8216;adjacency&#8217; (на примере метода POST)</strong></p>
<ul>
<li><strong>POST['nodeid']</strong> &#8211; идентификатор узла (ветви)</li>
<li><strong>POST['parentid']</strong> &#8211; идентификатор родительского узла</li>
<li><strong>POST['n_level']</strong> &#8211; уровень вложенности узла</li>
</ul>
</blockquote>
<p></p>
<blockquote><p><strong>кроме этого, на сервер также передаются стандартные для jqGrid параметры (на примере метода POST)</strong></p>
<li><strong>POST['page']</strong> &#8211; номер страницы, для &laquo;листалки&raquo;</li>
<li><strong>POST['rows']</strong> &#8211; количество записей, для ограничения при выборке данных</li>
<li><strong>POST['sidx']</strong> &#8211; значение <strong>index:</strong> в<strong> colModel</strong>, имя столбца по которому необходимо отсортировать результат</li>
<li><strong>POST['sord']</strong> &#8211; направление сортировки</li>
</blockquote>
<p>
После получения данных, серверный скрипт выполняет запрос данных из БД и сроит и  выводит результат в следующих форматах. </p>
<blockquote><p><strong>В режиме &#8216;nested&#8217; (на примере XML ответа)</strong></p>
<ul>
<li><strong>пользовательские столбцы</strong></li>
<li><strong>level</strong> &#8211; уровень узла в иерархии</li>
<li><strong>lft</strong> &#8211; позиция узла &laquo;слева&raquo;</li>
<li><strong>rgt</strong> &#8211; позиция узла &laquo;справа&raquo;</li>
<li><strong>isLeaf</strong> &#8211; логический признак (true/false), определяет этот узел является &laquo;веткой&raquo;(есть подузлы) или &laquo;листом&raquo;(нет подузлов)</li>
<li><strong>expanded</strong> &#8211; логический признак (true/false), нужно ли показывать подузлы если этот узел является веткой, т.е. загрузить &laquo;открытым&raquo; или &laquo;закрытым&raquo;</li>
</ul>
</blockquote>
<p></p>
<blockquote><p><strong>В режиме &#8216;adjacency&#8217; (на примере XML ответа)</strong></p>
<ul>
<li><strong>пользовательские столбцы</strong></li>
<li><strong>level</strong> &#8211; уровень узла в иерархии</li>
<li><strong>parent</strong> &#8211; идентификатор родительского узла</li>
<li><strong>isLeaf</strong> &#8211; логический признак (true/false), определяет этот узел является &laquo;веткой&raquo;(есть подузлы) или &laquo;листом&raquo;(нет подузлов)</li>
<li><strong>expanded</strong> &#8211; логический признак (true/false), нужно ли показывать подузлы если этот узел является веткой, т.е. загрузить &laquo;открытым&raquo; или &laquo;закрытым&raquo;</li>
</ul>
</blockquote>
<p>
Ядро (<a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data">ридеры</a>) jqGrid разбирают ответ и вставляют данные в таблицу. Вот теперь серверные скрипты будут более-менее понятны. </p>
<p><strong>Вложенные множества (<em>p3e1_n.php</em>)</strong>(опущены подключение к БД и вывод результата)</p>
<pre class="brush: php;">
// Получаем параметры от таблицы
    # ВНИМАНИЕ!!!
    # Данный код не имеет проверок запрашиваемых данных
    # что может стать причиной взлома! Обязательно проверяйте все данные
    # поступающие от клиента

    $node  = intval($_POST['nodeid']);
    $left  = intval($_POST['n_left']);
    $right = intval($_POST['n_right']);
    $level = intval($_POST['n_level']);

// Настраиваем условие для выбора ветки
    $WHERE = '';
    if($node &gt; 0) {
       $level = $level + 1;  // нужно выбрать следующий уровень
       $WHERE = &quot; AND cleft &gt; &quot;.$left.&quot; AND cright &lt; &quot;.$right.&quot; AND clevel = &quot;.$level;
    }else{
       $level = 0;
    }

// Выбираем подразделы
    $query = &quot;SELECT cid, title, clevel, cleft, cright FROM tree_nested_sets WHERE cleft BETWEEN cleft AND cright &quot;.$WHERE.&quot; GROUP BY title ORDER BY cleft;&quot;;
    $result = mysql_query($query);

// Формируем результат
    $response-&gt;page = 1;
    $response-&gt;total = 1;
    $response-&gt;records = 1;

    $i = 0;
    while($row = mysql_fetch_assoc($result)) {
        //-------------------------------------
        // Определяем является ли выбранный узел &quot;листом&quot;
        if($row['cright'] == $row['cleft']+1)
            $leaf = 'true';
        else
            $leaf='false';
        //-------------------------------------

        if($level == $row['clevel']){
            $response-&gt;rows[$i]['cell'] = array($row['cid'], $row['title'], $row['clevel'], $row['cleft'], $row['cright'], $leaf, 'false');
        }
        $i++;
    }
</pre>
<p><strong>Матрица смежностей(<em>p3e1_a.php</em>)</strong>(опущены подключение к БД и вывод результата)</p>
<pre class="brush: php;">
// Выбираем все разделы без подразделов (листья)
    $query_feafs = &quot;SELECT t1.cid FROM tree_adjacency_matrix AS t1 LEFT JOIN tree_adjacency_matrix AS t2 ON t1.cid = t2.id_parent WHERE t2.cid IS NULL&quot;;
    $sql_leafs = mysql_query($query_feafs);

    while($row = mysql_fetch_assoc($sql_leafs)) {
       $leafs[] = $row['cid']; // Массив для хранения &quot;листьев&quot;
    }
    unset($row);

// Получаем параметры от таблицы
    # ВНИМАНИЕ!!!
    # Данный код не имеет проверок запрашиваемых данных
    # что может стать причиной взлома! Обязательно проверяйте все данные
    # поступающие от клиента

    $level  = intval($_POST['n_level']);
    $node   = intval($_POST['nodeid']);

// Настраиваем условие для выбора ветки
    if($node &gt; 0) {
       $level = $level + 1;            // нужно выбрать следующий уровень
       $WHERE = 'id_parent ='.$node;
    } else {
       $WHERE = 'id_parent IS NULL';   // выбрать корень(ни)
    } 

// Выбираем подразделы
    $query  = &quot;SELECT cid, title, id_parent FROM tree_adjacency_matrix WHERE &quot;.$WHERE;
    $result = mysql_query($query);

// Формируем результат
    $response-&gt;page      = 1;
    $response-&gt;total     = 1;
    $response-&gt;records   = 1;

    $i = 0;
    while($row = mysql_fetch_assoc($result)) {
       //-------------------------------------
       // Определяем ID родителя этого узла
       if(!$row['id_parent'])
           $parent = 'NULL';
       else
          $parent = $row['id_parent'];
       //-------------------------------------
       // Определяем является ли выбранный узел &quot;листом&quot;
       if(in_array($row['cid'], $leafs))
           $is_leaf = 'true';
       else
           $is_leaf = 'false';
       //--------------------------------------

       $response-&gt;rows[$i]['cell'] = array($row['cid'], $row['title'], $level, $parent, $is_leaf, FALSE);

       $i++;
    }</pre>
<p>Я считаю комментировать в этих листингах особо нечего, кроме того что данные поступающие с сервера не ограничиваются по кол-ву записей и не сортируются. А практически все остальное является повторением примеров из предыдущих статей или специфическими вещами при работе с деревьями, описанными в статьях приложенных выше. Также обращу ваше внимание на то, что пример работы с <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:nested_set_model">Nested Set Model</a> описанный в документации разработчиком не хотел работать, пришлось его доводить, за что мне большое спасибо <img src='http://www.linkexchanger.su/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><a title="p1.3" name="p1.3"></a><strong>3)jqGrid и статические деревья</strong><br />
Название <em>статические деревья</em> оносительно, того что мы делали немного ранее. Безусловно данные &laquo;загруженные&raquo; таким способом могут быть построены и скриптом динамически, но все же бывают такие задачи, когда дерево уже есть необходимо лишь вывести его в дружественной для пользователя форме как в <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p3e2.html">ДЕМО3.2</a> . Не правда ли что-то напоминает? Да! это меню из демо jqGrid от разработчика. </p>
<p>Листинг клиентской части:</p>
<pre class="brush: jscript;">
  $('#table').jqGrid({
            url: &quot;tree.xml&quot;,
            datatype: &quot;xml&quot;,
            height: &quot;auto&quot;,
            pager: false,
            loadui: &quot;disable&quot;,
            colNames: [&quot;id&quot;,&quot;Items&quot;,&quot;url&quot;],
            colModel: [
                {name: &quot;id&quot;,width:1,hidden:true, key:true},
                {name: &quot;menu&quot;, width:150, resizable: false, sortable:false},
                {name: &quot;url&quot;,width:1,hidden:true}
            ],
            treeGrid: true,
                    caption: &quot;jqGrid Demos&quot;,
            ExpandColumn: &quot;menu&quot;,
            width: 200,
            rowNum: 200,
            ExpandColClick: true,
            treeIcons: {leaf:'ui-icon-document-b'}
 });
</pre>
<p>Полностью идентичные параметры плагина, за исключением того, что я отключил обработчик события <strong>onSelectRow</strong>.<br />
Из листига должно стать понятно, что таблица запрашивает статичный(оносительно) файл <em>tree.xml</em>, который выглядит так</p>
<pre class="brush: xml;">&lt;?xml version='1.0' encoding=&quot;utf-8&quot;?&gt;
&lt;rows&gt;
    &lt;page&gt;1&lt;/page&gt;
    &lt;total&gt;1&lt;/total&gt;
    &lt;records&gt;1&lt;/records&gt;
    &lt;row&gt;&lt;cell&gt;1&lt;/cell&gt;&lt;cell&gt;Loading Data&lt;/cell&gt;&lt;cell&gt;&lt;/cell&gt;&lt;cell&gt;0&lt;/cell&gt;&lt;cell&gt;1&lt;/cell&gt;&lt;cell&gt;10&lt;/cell&gt;&lt;cell&gt;false&lt;/cell&gt;&lt;cell&gt;false&lt;/cell&gt;&lt;/row&gt;
    &lt;row&gt;&lt;cell&gt;2&lt;/cell&gt;&lt;cell&gt;XML Data&lt;/cell&gt;&lt;cell&gt;xmlex.html&lt;/cell&gt;&lt;cell&gt;1&lt;/cell&gt;&lt;cell&gt;2&lt;/cell&gt;&lt;cell&gt;3&lt;/cell&gt;&lt;cell&gt;true&lt;/cell&gt;&lt;cell&gt;true&lt;/cell&gt;&lt;/row&gt;
    &lt;row&gt;&lt;cell&gt;3&lt;/cell&gt;&lt;cell&gt;JSON Data&lt;/cell&gt;&lt;cell&gt;jsonex.html&lt;/cell&gt;&lt;cell&gt;1&lt;/cell&gt;&lt;cell&gt;4&lt;/cell&gt;&lt;cell&gt;5&lt;/cell&gt;&lt;cell&gt;true&lt;/cell&gt;&lt;cell&gt;true&lt;/cell&gt;&lt;/row&gt;

...

&lt;/rows&gt;
</pre>
<p>Т.е. jqGrid просто разбирает данные из этого файла и строит TreeGrid.</p>
<p><a title="p2" name="p2"></a><strong>II. Связывание данных в jqGrid</strong></p>
<p>Иногда при построении какого либо приложения необходимо как то сгруппировать данные для экономии визуального пространства на странице и при этом иметь возможность как можно быстрее и комфортнее получить доступ к более детальной информации или связанной с текущей. Немного сумбурно получилось <img src='http://www.linkexchanger.su/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , но надеюсь вы меня поняли, а если не поняли то примеры разложат все по полочкам.</p>
<p><a title="p2.1" name="p2.1"></a><strong>1)Простая подтаблица (subgrid)</strong></p>
<p>Это весьма полезная опция у этого плагина. На <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p3e3.html">ДЕМО3.3</a> обратите внимание на крестик в крайнем правом столбце таблицы. При клике на нем под выбранной строкой распахивается &laquo;карман&raquo; в котором находится небольшая табличка с названиями городов и прочей &laquo;рыбой&raquo;.  Вот пример группировки. Теперь давайте перейдем к листингам.</p>
<pre class="brush: jscript;">
$('#table').jqGrid({
       url:'p3e3.php',
       datatype: 'json',
       mtype: 'POST',
       colNames:['Код страны','Cтрана',''],
       colModel :[
          {name:'country_code', index:'country_code', width:80, hidden: true},
          {name:'country_name', index:'country_name', width:60},
          {name:'description', width:200, sortable: false}
          ],
       pager: $('#tablePager'),
       rowNum: 100,
       scroll: true,
       viewrecords: true,
       sortname: 'country_name',
       sortorder: 'asc',
       width: 700,
       height: 400,
       subGrid: true,
         subGridUrl: 'p3e3.php?get=subgrid',
         subGridModel:[{
                     name :  ['&amp;nbsp;','Город', 'Широта', 'Долгота'],
                     width:  [40, 200, 150, 150],
                     align:  ['center','left','right','right'],
                     params: ['country_code','country_name']
                 }]
});
</pre>
<p>Как видите, абсолютно обыкновенный jqGrid, но в &laquo;настройках&raquo; есть несколько интересных моментов:</p>
<ul>
<li><strong>subGrid:</strong> &#8211; в строке 19. Эта опция позволяет использовать подтаблицу.</li>
<li><strong>subGridUrl:</strong> &#8211; указывает путь к скрипту, который должен вернуть данные для построения подтаблицы. В данном случае происходит запрос к тому же скрипту, который &laquo;обслуживает&raquo; и таблицу-родителя при этом передав ему параметр <em>get</em> со значением <em>subgrid</em></li>
<li><strong>subGridModel:</strong> &#8211; свойство которое задает параметры подтаблицы. Аналогично <strong>colModel</strong> таблицы-родителя</li>
</ul>
<p><strong>subGridModel:</strong> &#8211; представляет из себя массив с объектом, у которого есть свои параметры. <strong>name</strong>, <strong>width</strong> и <strong>align</strong> уверен их имена говорят сами за себя, это тексты заголовков столбцов, ширины соответствующих столбцов и выравнивание в них соответственно. Более интересным будет свойство <strong>params</strong>. Оно позволяет передать значения из каких то ячеек родительской таблицы на сервер при запросе подтаблицы. Иными словами, когда вы нажмете на крестик , открывающий подтаблицу, происходит запрос к серверу которому передается  клоч (id) записи (в нашем случае это <em>country_code</em>) и плос к этим данным можно передать дополнительные (в нашем случае серверу будет передан еще и <strong>country_name</strong>). А вот на сервере получив значения нужных параметров (в этом примере серверный скрипт просто игнорирует значение параметра <strong>country_name</strong>) вы выполняем запрос к БД и выводим JSON объект с данными.</p>
<pre class="brush: php;">
...
$get = $_REQUEST['get'];  // Параметр указывающий на то
                                    //  что мы запросили информацию для подтаблицы
...
switch ($get){
    case 'subgrid':
        // Выбрать города запрошенной страны
        $id =$_REQUEST['id'];

        // Запрос данных
        $query = &quot;SELECT id, country_code, region_code, city, latitude, longitude, nbip FROM cities  WHERE country_code LIKE '&quot;.$id.&quot;'&quot;;

        $result = mysql_query($query);
        if(mysql_num_rows($result) &gt;= 1){
            // Строки данных для таблицы
            $i = 0;
            while($row = mysql_fetch_assoc($result)) {
                $data-&gt;rows[$i]['cell'] = array($i+1,'&lt;strong&gt;&lt;em&gt;'.$row['city'].'&lt;/em&gt;&lt;/strong&gt;',$row['latitude'],$row['longitude']);
                $i++;
            }
        }
        break;

    default:
        // Выбрать названия стран и сосчетать города
        ...

}
// Вывести результат
...
</pre>
<p>Серверный скрипт особо ничем не отличается от рассмотренных в предыдущих примерах. При этом он разбит на две части оператором <strong>switch</strong>. Который по умолчанию выполняет &laquo;стандартную&raquo; обработку и вывод данных для главной таблицы. А вот если этот скрипт запустить передав ему  параметр <em>get</em> (я выбрал такое имя только ради наглядности) тогда будет выполнена выборка данных для подтаблицы. Ну и если у вас чешутся руки поковырять пример, вы можете <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/files/demo3.3.zip">скачать его</a>.</p>
<p>Подтаблицы это замечательный инструмент, который позволяет очень элегантно организавать данные, но при этом имеет один существенный недостаток &#8211; подтаблица &laquo;не живая&raquo;. Т.е. данные в подтаблице не могут сортироваться, нет возморжности реализовать поиск и т.д. А это очень критично если в подтаблице будет выводиться много записей. Однако это ограничение отпадает само собой при использовании jqGrid как подтаблицы.</p>
<p><a title="p2.2" name="p2.2"></a><strong>2)jqGrid как subgrid</strong><br />
Итак начнем с промотра <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p3e4.html">ДЕМО3.4</a>. Как видите все тот же &laquo;родной&raquo; jqGrid с названиями стран, и кол-вом городов в этой стране, но при этом подтаблица теперь представляет из себя самую настоящую jqGrid со всеми свойствами и методами. Согласитесь, что так работать намного приятнее и удобнее. </p>
<p>А вот здесь самое интересное &#8211; клиентский код (в листинге опущены все настройки родительской таблицы, кроме одного свойства):</p>
<pre class="brush: jscript;">
...
subGrid: true,
subGridRowExpanded: function(subgrid_id, row_id) {
    var subgrid_table_id;
    subgrid_table_id = subgrid_id+'_t';

    $('#'+subgrid_id).html('&lt;table id=&quot;'+subgrid_table_id+'&quot;&gt;&lt;/table&gt;&lt;div id=&quot;'+subgrid_table_id+'_pager&quot;&gt;&lt;/div&gt;');
    $('#'+subgrid_table_id).jqGrid({
        url: 'p3e4.php',
        datatype: 'json',
        mtype: 'POST',
        postData: {'get':'subgrid', 'id':row_id},
        colNames: ['Город', 'Широта', 'Долгота'],
        colModel: [
            {name: 'city', index: 'city', width:130},
            {name: 'latitude', index: 'latitude', width:80, align: 'right'},
            {name: 'longitude', index: 'longitude', width:80, align: 'right'}
            ],
        height: 'auto',
        autowidth: true,
        rownumbers: true,
        rownumWidth: 40,
        rowNum: 10,
        sortname: 'city',
        sortorder: 'asc',
        pager: $('#'+subgrid_table_id+'_pager'),
        rowNum:10,
        rowList:[10,20,50,100]
    });
}
...
</pre>
<p>Настройки таблицы-родителя идентичные предыдущему примеру, но при этом появилось новое свойство <strong>subGridRowExpanded</strong>. Думаю самые догадливые поняли, а самые любопытные прочли в документации в секции <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:subgrid">Subgrid</a>, что <strong>subGridRowExpanded</strong> не просто свойство, а событие. </p>
<blockquote><p>
<strong>subGridRowExpanded</strong> &#8211; это событие возникает когда пользователь кликает на крестик раскрытия подтаблицы и выполняет определенную функцию при распахивании &laquo;кармана&raquo; для подтаблицы. При этом в функцию обработчик будут переданы 2 параметра:</p>
<ul>
<li><strong>pID</strong> &#8211; уникальный идентификатор &laquo;кармана&raquo; (контейнера, если хотите) который открывается под выбранной строкой</li>
<li><strong>id</strong> &#8211; идентификатор записи под которой открылся &laquo;карман&raquo;</li>
</ul>
</blockquote>
<p>Безусловно существуют еще события, о которых вы можете узнать из документации. А мы пока пробежимся по листингу. Итак когда пользователь &laquo;тыцнул&raquo; на крестик, открывается контейнер и выполняется функция. Которая получает 2 параметра <em>subgrid_id</em> и <em>row_id</em>. Далее в строке 5 создаем строковое значение для атрибута id и в 6й строке используем метод jQuery, который вставляет в &laquo;карман&raquo; (кстати сказать что это обыкновенный DIV) html разметку таблицы и DIV&#8217;a. А далее идет бональная инициализация jqGrid для только что созданной разметки. Т.е. фактически мы просто напросто динамически создали разметку и создали jqGrid! В этот момент я воскликнул &laquo;Тааак!&raquo; и потер руки. Почему? Да потому, что зная id объекта (&lt;div id=&quot;someid&quot;&gt;&#8230;&lt;/div&gt;) с помощью jQuery можно сотворить с ним все что угодно. Но прежде чем мы перейдем к следующему примеру я приведу <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/files/demo3.4.zip">ссылку на раздаточный материал</a> по теме &#8211; это пример который только что расмотрели.<br />
А теперь зная id контейнера давайте, еще добавим наглядности нашему примеру со странами и городами, например как на <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p3e5.html">ДЕМО3.5</a>. Как видите все эта же, скучная таблица со странами, но теперь при клике на крестик открывается подробная информация и флаг выбранной строки. Под которой свернутая jqGrid таблица с перечнем городов. Этот пример вы можете скачать перейдя по <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/files/demo3.5.zip">этой ссылке</a>. Внутри архива все скрипты, но наибольший интерес представляет клиентский код. Я условно разделю его на 2 части, первая (нижняя) часть:</p>
<pre class="brush: jscript;">
$('#table').jqGrid({
          ...
          subGrid: true,
          subGridRowExpanded: function(subgrid_id, row_id) {
                       getCountryDetails(subgrid_id, row_id);
                   }

});
</pre>
<p>Это таблица из предыдущего примера, но теперь при возникновении события <strong>subGridRowExpanded</strong> будет выполнена пользовательская функция <strong>getCountryDetails()</strong>, которая и является 2 половиной клиентского скрипта:</p>
<pre class="brush: jscript;">
function getCountryDetails(container, countryCode){
    $.ajax({
            type: 'post',
            url: 'p3e5.php',
            data: ({'id': countryCode, 'get': 'details'}),
            dataType: 'json',
            success: function(server){
                $('#'+container).html('&lt;div class=&quot;c_detail&quot;&gt;&lt;img src=&quot;files/images/'+server.flag+'&quot;&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Столица:&lt;/strong&gt; '+server.capital+'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Дата независимости:&lt;/strong&gt; '+server.independence_date+'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Официальные языки:&lt;/strong&gt; '+server.off_lng+'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Форма правления:&lt;/strong&gt; '+server.government+'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Глава правительства:&lt;/strong&gt; '+server.president+'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Валюта:&lt;/strong&gt; '+server.currency+'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Интернет-домены:&lt;/strong&gt; '+server.domains+'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Телефонный код:&lt;/strong&gt; '+server.dialing_code+'&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Часовой пояс:&lt;/strong&gt; '+server.time_zone+'&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;');

                var subgrid_table_id = container+'_t';

                $('#'+container).append('&lt;table id=&quot;'+subgrid_table_id+'&quot;&gt;&lt;/table&gt;&lt;div id=&quot;'+subgrid_table_id+'_pager&quot;&gt;&lt;/div&gt;');
                $('#'+subgrid_table_id).jqGrid({
                          caption: 'Города',
                          hiddengrid: true,
                          url: 'p3e4.php',
                          datatype: 'json',
                          mtype: 'POST',
                          postData: {'get':'subgrid', 'id':countryCode},
                          colNames: ['Город', 'Широта', 'Долгота'],
                          colModel: [
                            {name: 'city', index: 'city', width:130},
                            {name: 'latitude', index: 'latitude', width:80, align: 'right'},
                            {name: 'longitude', index: 'longitude', width:80, align: 'right'}
                          ],
                          height: 'auto',
                          autowidth: true,
                          rownumbers: true,
                          rownumWidth: 40,
                          rowNum: 10,
                          sortname: 'city',
                          sortorder: 'asc',
                          pager: $('#'+subgrid_table_id+'_pager'),
                          rowNum:10,
                          rowList:[10,20,50,100]
                });
            }
    });
}
</pre>
<p>В теле этой функции выполняется AJAX запрос, передающий серверному скрипту 2 параметра методом POST:</p>
<ul>
<li><strong>id</strong> &#8211; идентификатор записи, в нашем случае это сокращенный код страны</li>
<li><strong>get</strong> &#8211; этот параметр указывает, что мы хотим получить с сервера детальную информацию по выбранной стране</li>
</ul>
<p>После того как запрос будет успешно выполнен (см. строку 8), в открывшийся под выбранной строкой контейнер будет помещена какая-то HTML разметка с полученными с сервера данными. В данном примере такая разметка представлена не нумированным списком в картинкой &#8211; флагом страны. После этого в этот же контейнер помещается разметка для дочерней таблицы и производится инициализация дочерней таблицы.</p>
<p>В принципе логика работы достаточно проста, главное не забывать что работать с полученными от сервера данными можно только после окончания AJAX запроса или производя синхронные запросы. </p>
<p>Как вы понимаете в контейнер для подтаблицы можно помещать не только какую-то примитивную разметку, но и формы, флеш, другие &laquo;вкусные&raquo; и полезные вещи.</p>
<p><a title="p2.3" name="p2.3"></a><strong>3)Ведущая и ведомая jqGrid</strong></p>
<p>Однако не всегда можно сгруппировать данные и засунуть их в подтаблицу. Иногда данные могут быть полностью самостоятельными и при этом иметь некую связь. Например однажды передо мной стала задача вывести пользователю перечень счетов и платежей по этим счетам, и при этом обеспечить возможность просмотра счетов, платежей и платежей по выбранному счету. И тут то мне очень помогла методика &laquo;ведущий-ведомый&raquo;. Работа которой проиллюстрирована в <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p3e6.html">ДЕМО5.6</a>.</p>
<p>Имеется две jqGrid, отображающие страны и города, которые можно менять местами благодаря плагину <em>sortable</em>. Также в верхней части документа есть checkbox который включает функцию фильтрации содержимого ведомой (нижней) таблицы, на основе выбранной записи в ведущей (верхней) таблице. При этом вся фильтровка осуществляется на стороне сервера, с этого и начнем разбор примера. Для удобства две таблицы запрашивают данные у двух отдельных серверных скриптов, один для городов, другой для стран.<br />
<strong>Скрипт для таблицы &laquo;Города&raquo;</strong> (т.к. основная структура скрипта &laquo;стандартна&raquo; я привожу лишь основные моменты):</p>
<pre class="brush: php;">
// Получение параметров page, rows и т.д.
...
if($_REQUEST['filterBy'] != 'null')  // Фильтр
    $WHERE = &quot; WHERE country_code = '&quot;.$_REQUEST['filterBy'].&quot;' &quot;;
else
    $WHERE = '';
...
// Запрос подсчета суммарного кол-ва записей
$result = mysql_query(&quot;SELECT COUNT(*)AS count FROM cities&quot;.$WHERE);
...
// Запрос выборки данных
$result = mysql_query(&quot;SELECT city, latitude, longitude FROM cities &quot;.$WHERE.&quot; ORDER BY &quot;.$sidx.&quot; &quot;.$sord.&quot; LIMIT &quot;.$start.&quot;, &quot;.$limit);
</pre>
<p>В данном случае клиентский код при запросе данных с сервера помимо &laquo;стандартных&raquo; параметров, отправляет еще и дополнительный параметр <strong>filterBy</strong>, который по сути и определяет критерий по которому нужно выбрать записи из БД и вернуть клиенту. Что и проиллюстрировано в последующих запросах.</p>
<p><strong>Скрипт для таблицы &laquo;Страны&raquo;:</strong></p>
<pre class="brush: php;">
// Получение параметров page, rows и т.д.
...
if($_REQUEST['filterBy'] != 'null'){
     $country = @mysql_fetch_array(mysql_query(&quot;SELECT country_code FROM cities WHERE id = &quot;.$_REQUEST['filterBy']));
     $WHERE = &quot; WHERE country_code = '&quot;.$country['country_code'].&quot;' &quot;;
}else{
     $WHERE = '';
}
...
// Запрос подсчета суммарного кол-ва записей
$result = mysql_query(&quot;SELECT COUNT(*)AS count FROM countries &quot;.$WHERE);
...
// Запрос выборки данных
$result = mysql_query(&quot;SELECT * FROM countries &quot;.$WHERE.&quot; ORDER BY &quot;.$sidx.&quot; &quot;.$sord.&quot; LIMIT &quot;.$start.&quot;, &quot;.$limit);
</pre>
<p>Как видите полная аналогия предыдущего листинга, но теперь если передано определенное значение фильтра, происходит дополнительный запрос для уточнения кода страны.<br />
На этом все премудрости серверной стороны заканчиваются и начинается клиентский код, но прежде чем перейти к его рассмотрению <strong>пара слов о разметке страницы</strong>:</p>
<pre class="brush: xml;">
&lt;input type=&quot;checkbox&quot; id=&quot;link&quot;&gt;
&lt;label for=&quot;link&quot;&gt;Связать таблицы&lt;/label&gt;

&lt;div id=&quot;interfaceBody&quot; style=&quot;margin: 10px 10px 10px 10px; padding: 0px 10px 10px 10px; border: 2px solid gray&quot;&gt;
&lt;div class=&quot;grid&quot; id=&quot;countries&quot; style=&quot;padding: 10px 10px 10px 10px; margin-top: 10px; border: 2px solid red&quot;&gt;
    &lt;table id=&quot;table_countries&quot;&gt;&lt;/table&gt;
    &lt;div id=&quot;table_countriesPager&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;grid&quot; id=&quot;cities&quot; style=&quot;padding: 10px 10px 10px 10px; margin-top: 10px; border: 2px solid green&quot;&gt;
    &lt;table id=&quot;table_cities&quot;&gt;&lt;/table&gt;
    &lt;div id=&quot;table_citiesPager&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>Если не обращать внимание на ужасно длинные inline-стили, то разметка достаточно проста. Сначала идет код checkbox&#8217;a с меткой, а следом контейнер всего интерфейса, внутри которого два дочерних контейнера, по одному для каждой таблицы. </p>
<p>И наконец <strong>клиентский скрипт:</strong></p>
<pre class="brush: jscript;">
//-------------------------------------------------------------------
// Функция-обработчик
function stickTogether(){
    if($('#link').is(':checked')){
        // Флаг &quot;Связать таблицы&quot; утановлен
        var masterId        = $('#interfaceBody &gt; DIV:first').attr('id');                //Определяем ID контейнера &quot;ведущей таблицы&quot;
        var masterPostData  = $('#table_'+masterId).jqGrid('getGridParam','postData');   //Получаем весь объект postData &quot;ведущей таблицы&quot;
        var selId    = $('#table_'+masterId).jqGrid('getGridParam','selrow');            //Получаем id записи в выделенной строке
                                                                                         //не путайте с rowIndex
        // Проверяем какое текущее значение фильтра ведущей таблицы, он должен быть сброшен (например null)
        if(masterPostData.filterBy){
            $('#table_'+masterId).jqGrid('setGridParam',{'postData':{'filterBy':null}}); //Сбрасываем значение фильтра
            $('#table_'+masterId).trigger('reloadGrid');                                 //Перезагружаем данные в таблицу
        }

        var slaveId  = $('#interfaceBody &gt; DIV:last').attr('id');                        //Определяем ID контейнера &quot;ведомой таблицы&quot;
        $('#table_'+slaveId).jqGrid('setGridParam',{'postData':{'filterBy':selId}});     //Применяем в качестве фильтра ведомой таблицы
                                                                                         //id выбранной записи в ведущей таблице
        $('#table_'+slaveId).trigger('reloadGrid');                                      //Перезагружаем данные в таблицу
    }else{
        // Флаг &quot;Связать таблицы&quot; не утановлен
        var coutriesT       = $('#table_countries');
        var countriesPost   = coutriesT.jqGrid('getGridParam','postData');

        if(countriesPost.filterBy){ //Сбрасываем фильтр т.к. ничего не нужно фильтровать
            coutriesT.jqGrid('setGridParam',{'postData':{'filterBy':null}})
            coutriesT.trigger('reloadGrid');
        }
        //-----------------------
        var citiesT       = $('#table_cities');
        var citiesPost    = citiesT.jqGrid('getGridParam','postData');

        if(citiesPost.filterBy){ //Сбрасываем фильтр т.к. ничего не нужно фильтровать
            citiesT.jqGrid('setGridParam',{'postData':{'filterBy':null}})
            citiesT.trigger('reloadGrid');
        }
    }
}
//-------------------------------------------------------------------
// Настройка плагинов
var tcountries = $('#table_countries').jqGrid({
                          caption: 'Страны',
                          hidegrid: false,
                          url:'p3e6_countries.php',
                          postData: {'filterBy':null},
                          datatype: 'json',
                          mtype: 'POST',
                          colNames:['Код страны','Cтрана','Столица','Домены'],
                          colModel :[
                                    {name:'country_code', index:'country_code', width:80, hidden: true},
                                    {name:'country_name', index:'country_name', width:60},
                                    {name:'capital', index:'capital', width:60},
                                    {name:'domains', index:'domains', width:60}
                                    ],
                          pager: $('#table_countriesPager'),
                          rowNum: 100,
                          scroll: true,
                          viewrecords: true,
                          sortname: 'country_name',
                          sortorder: 'asc',
                          height: 200,
                          autowidth: true,
                          onSelectRow: stickTogether
                });

var tcities = $('#table_cities').jqGrid({
                          caption: 'Города',
                          hidegrid: false,
                          url: 'p3e6_cities.php',
                          postData: {'filterBy':null},
                          datatype: 'json',
                          mtype: 'POST',
                          colNames: ['Город', 'Широта', 'Долгота'],
                          colModel: [
                            {name: 'city', index: 'city', width:130},
                            {name: 'latitude', index: 'latitude', width:80, align: 'right'},
                            {name: 'longitude', index: 'longitude', width:80, align: 'right'}
                          ],
                          height: 200,
                          autowidth: true,
                          rownumbers: true,
                          rownumWidth: 40,
                          rowNum: 100,
                          sortname: 'city',
                          sortorder: 'asc',
                          pager: $('#table_citiesPager'),
                          scroll: true,
                          viewrecords: true,
                          onSelectRow: stickTogether
                });

$(&quot;#interfaceBody&quot;).sortable({
        connectWith: '.grid',
        placeholder: 'ui-state-error',
        opacity: 0.7,
        stop: stickTogether
});

//-------------------------------------------------------------------
// Назначаем обработчик на событие
$('#link').change(stickTogether);
</pre>
<p>При всем своем объеме код достаточно груб и прост. Начнем пожалуй с назначения обработчика на изменение checkbox&#8217;a, самая последняя строка в листинге. Как видите при изменении checkbox&#8217;a будет вызвана функция <strong>stickTogether</strong>. В теле которой происходит проверка состояния флажка и если он не установлен, то произойдет сброс всех &laquo;фильтров&raquo; таблиц и перезагрузка данных в таблице.<br />
Но самое интересное это код в &laquo;положительной&raquo; ветке if&#8217;а, когда флажок установлен. Мы знаем, что ведущая таблица расположена вверху, значит для начала узнаем какая же таблица в данный момент находится там. Для этого получаем значение атрибута <em>id</em> первого контейнера (строка 6).  Теперь зная какая таблица ведущая &#8211; получаем объект <strong>postData</strong>, который, напомню, содержит все параметры и их значения для отправки серверу. В 7й строке получим Id записи в выделенной строке ведущей таблицы. Далее проверив значение фильтра ведущей таблицы, при необходимости сбросим его. Это необходимо если пользователь поменял таблицы местами.<br />
В строке 16 узнаем id контейнера ведомой таблицы. И применяем фильтр, записав id выделенной строки в ведущей таблице, и перезагружаем данные.<br />
У данного скрипта есть один недостаток &#8211; расплата за универсальность. Из-за того что на событие <strong>onSelectRow:</strong> в обоих таблицах определен один и тот же обработчик <strong>stickTogether</strong>, при выделении строки в ведомой таблице, происходит постоянное обновление ее записей. Но уверен что те кому потребуется такой функционал jqGrid без труда смогут это исправить. </p>
<p><strong>Заключение</strong><br />
Подведя итоги проделанной работы можно сказать, что в данной статье мы рассмотрели практически все варианты расширенного использования плагина. Научились работать с древовидными данными и подтаблицами, а также попробовали управлять содержимым ведомой таблицы посредством данных из ведущей. В следующей части я рассмотрю еще одну экзотическую интересную опцию jqGrid &#8211; &laquo;drag&#8217;n'drop записей между jqGrid&#8217;ами&raquo;.<br />
Ну и как всегда если у вас возникли вопросы задавайте их на <a href="http://www.linkexchanger.su/forum/">форуме</a> ну а комментарии используйте для предложений и пожеланий.</p>
<p>Итак приблизительный план работ на следующий выпуск:</p>
<ul>
<li><strong>Расширенные возможности jqGrid</strong>
<ul>
<li>drag&#8217;n'drop записей между jqGrid&#8217;ами</li>
</ul>
</li>
<li><strong>Поиск данных в jqGrid</strong>
<ul>
<li>&laquo;inline&raquo; поиск</li>
<li>поиск с использованием встроенной формы</li>
<li>расширенный поиск с использованием встроенной формы</li>
<li>поиск с использованием внешней формы</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2010/523.html/feed</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>jqGrid Часть II: Базовые возможности</title>
		<link>http://www.linkexchanger.su/2010/486.html</link>
		<comments>http://www.linkexchanger.su/2010/486.html#comments</comments>
		<pubDate>Sat, 27 Feb 2010 07:37:35 +0000</pubDate>
		<dc:creator>TRAHOMOTO</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[jqGrig]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/?p=486</guid>
		<description><![CDATA[Итак в предыдущей статье (jqGrid Часть I:Знакомство) мы с вами подготовили платформу для опытов и выполнили &#171;пробный запуск&#187; плагина, с самыми &#171;базовейшими&#187; параметрами. Согласно которым таблица запрашивает данные с сервера в XML разметке, при этом у нас есть возможность сортировать данные в столбцах.
В данной статье мы продолжим эксперименты и прощупаем еще ряд замечательных возможностей jqGrid, [...]]]></description>
			<content:encoded><![CDATA[<p>Итак в предыдущей статье (<a href="http://www.linkexchanger.su/2010/118.html">jqGrid Часть I:Знакомство</a>) мы с вами подготовили платформу для опытов и выполнили &laquo;пробный запуск&raquo; плагина, с самыми &laquo;базовейшими&raquo; параметрами. Согласно которым таблица запрашивает данные с сервера в XML разметке, при этом у нас есть возможность сортировать данные в столбцах.</p>
<p>В данной статье мы продолжим эксперименты и прощупаем еще ряд замечательных возможностей jqGrid, вот план действий:</p>
<ul>
<li><strong><a href="http://www.linkexchanger.su/2010/486.html#p1">Другие способы загрузки данных</a></strong>
<ul>
<li><a href="http://www.linkexchanger.su/2010/486.html#p1.1">В виде JSON объекта</a></li>
<li><a href="http://www.linkexchanger.su/2010/486.html#p1.2">В виде массива</a></li>
<li><a href="http://www.linkexchanger.su/2010/486.html#p1.3">Конвертирование простой таблицы в jqGrid</a></li>
</ul>
</li>
<li><strong><a href="http://www.linkexchanger.su/2010/486.html#p2">Форматирование данных</a></strong>
<ul>
<li><a href="http://www.linkexchanger.su/2010/486.html#p2.1">Форматирование ячеек</a></li>
<li><a href="http://www.linkexchanger.su/2010/486.html#p2.2">Изменение представления данных</a></li>
</ul>
</li>
<li><strong><a href="http://www.linkexchanger.su/2010/486.html#p3">Панели инструментов и дополнительные панели</a></strong>
<ul>
<li><a href="http://www.linkexchanger.su/2010/486.html#p3.1">Панель-листалка</a></li>
<li><a href="http://www.linkexchanger.su/2010/486.html#p3.2">Панель инструментов</a></li>
<li><a href="http://www.linkexchanger.su/2010/486.html#p3.3">Пользовательские панели</a></li>
</ul>
</li>
<li><strong><a href="http://www.linkexchanger.su/2010/486.html#p4">Управление столбцами данных</a></strong>
<ul>
<li><a href="http://www.linkexchanger.su/2010/486.html#p4.1">Изменение размера и положения столбцов</a></li>
<li><a href="http://www.linkexchanger.su/2010/486.html#p4.2">Скрываем не нужные или отображаем нужные столбцы данных</a></li>
</ul>
</li>
</ul>
<p><span id="more-486"></span></p>
<p><a title="p1" name="p1"></a><strong>I. Другие способы загрузки данных</strong><br />
<a title="p1.1" name="p1.1"></a><strong>1) Загрузка данных в виде JSON объекта</strong></p>
<p>JSON &#8211; как и XML является текстовым форматом обмена данными, при этом намного моложе последнего. Является более прогрессивным методом, благодаря большей гибкости своей архитектуры по сравнению с XML. На тему сравнения XML и JSON есть очень хорошая статья (<a href="http://habrahabr.ru/blogs/webdev/31225/">JSON и XML. Что лучше?</a>). Но при генерировании ответа в JSON методами PHP, есть ряд особенностей при работе с кириллицей. Повествование о которых выходит за рамки данной статьи, поэтому я ограничиваюсь лишь упоминанием.</p>
<p>Итак на практике загрузка таких данных требует следующей конфигурации плагина:</p>
<pre class="brush: jscript;">$(function(){
                $('#table').jqGrid({
                              url:'p2e1.php',
                  datatype: 'json',
                             mtype: 'GET',
                             colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
                             colModel :[
                                    {name:'country_code', index:'country_code', width:80},
                                    {name:'region_code', index:'region_code', width:80},
                                    {name:'city', index:'city', width:90},
                                    {name:'latitude', index:'latitude', width:60},
                                    {name:'longitude', index:'longitude', width:60},
                                    {name:'nbip', index:'nbip', width:30}],
                            pager: $('#tablePager'),
                            rowNum:10,
                            rowList:[10,20,30,100],
                            sortname: 'city',
                            sortorder: 'asc',
                  caption: 'Загрузка JSON данных',
                  rownumbers: true,
                            rownumWidth: 40
                });
    });
</pre>
<p>Все изменения я выделил отступами (строки 4, 19-21). Как вы можете видеть в листинге параметру <strong>datatype:</strong> присвоено значение <em><strong>&#8216;json&#8217;</strong></em>, что говорит плагину о том что от сервера ожидается ответ в виде JSON объекта. Далее я ввел в конфиг таблицы еще три свойства <strong>caption</strong>, <strong>rownumbers</strong>, <strong>rownumWidth</strong>. Что они определяют?</p>
<ul>
<li><strong>caption</strong> &#8211; если это свойство не пустое, то у таблицы появляется заголовок с текстом, присвоенным этому свойству.</li>
<li><strong>rownumbers</strong> &#8211; если это свойство &laquo;истина&raquo;, то первым столбцом таблицы будет столбец с номерами записей по порядку.
<ul>
<li><strong>rownumWidth</strong> &#8211; это свойство зависимо от rownumbers. И определяет ширину столбца с нумерацией.</li>
</ul>
</li>
</ul>
<p>С данного момента, я ввожу еще одно правило в этот цикл статей. Все свойства-параметры инициализации jqGrid вы будете самостоятельно изучать на <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:jqgriddocs">странице документации</a> плагина в разделе <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options">Options</a> и <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:colmodel_options">colModel Options</a>. Но при этом я буду комментировать, то на что следует обратить внимание.</p>
<p>C параметрами клиентской части разобрались, теперь перейдем к серверной. Здесь я привожу листинг только последних строк кода, собственно это момент формирования и вывод ответа сервера.</p>
<p>Пример 1 &#8211; используя массив</p>
<pre class="brush: php;">
...
// Начало формирование массива
// для последующего преобразоования
// в JSON объект
$data['page']       = $page;
$data['total']      = $total_pages;
$data['records']    = $count;
// Строки данных для таблицы
$i = 0;
while($row = mysql_fetch_assoc($result)) {
    $data['rows'][$i]['id'] = $row['id'];
    $data['rows'][$i]['cell'][] = $row['country_code'];
    $data['rows'][$i]['cell'][] = $row['region_code'];
    $data['rows'][$i]['cell'][] = $row['city'];
    $data['rows'][$i]['cell'][] = $row['latitude'];
    $data['rows'][$i]['cell'][] = $row['longitude'];
    $data['rows'][$i]['cell'][] = $row['nbip'];
    $i++;
}
// Перед выводом не забывайте выставить header
// с типом контента и кодировкой
header(&quot;Content-type: application/json;charset=utf-8&quot;);
echo json_encode($data);
</pre>
<p>Пример 2 &#8211; используя объект</p>
<pre class="brush: php;">
...
// Начало формирование объекта
// для последующего преобразоования
// в JSON объект
$data-&gt;page       = $page;
$data-&gt;total       = $total_pages;
$data-&gt;records   = $count;
// Строки данных для таблицы
$i = 0;
while($row = mysql_fetch_assoc($result)) {
    $data-&gt;rows[$i]['id'] = $row[id];
    $data-&gt;rows[$i]['cell'] = array($row[country_code],$row[region_code],$row[city],$row[latitude],$row[longitude],$row[nbip]);
    $i++;
}
// Перед выводом не забывайте выставить header
// с типом контента и кодировкой
header(&quot;Content-type: text/script;charset=utf-8&quot;);
echo json_encode($data);
</pre>
<p>Оба подхода выполняют одни и те же действия, но при этом выбор подхода зависит от ваших предпочтений и уровня мастерства.</p>
<p>Вот ссылка на <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p2e1.html">ДЕМО2.1</a> и <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/files/demo2.1.zip">ссылка на архив</a> с примером.<br />
Подытожив, скажу, что как видите в данном способе загрузки данных нет ничего сложного и принцип работы идентичен с загрузкой данных в виде XML, но при этом немного облегчается код серверного скрипта. Также повторюсь, что при кодировании данных в JSON методом PHP следует учитывать особенности работы с кириллицей!</p>
<p><a title="p1.2" name="p1.2"></a><strong>2) Загрузка данных в виде массива</strong></p>
<p>Теперь рассмотрим пример, как можно создать jqGrid используя в качестве источника данных массив. Как вы понимаете для данного примера не понадобится серверный скрипт, а клиентский скрипт будет выглядеть приблизительно так.</p>
<pre class="brush: jscript;">
$(function(){
$('#table').jqGrid({
  datatype: 'local',
          colNames:['ID','Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
          colModel :[
                        {name:'id', index:'id', width:20},
                        {name:'country_code', index:'country_code', width:80},
                        {name:'region_code', index:'region_code', width:80},
                        {name:'city', index:'city', width:90},
                        {name:'latitude', index:'latitude', width:60},
                        {name:'longitude', index:'longitude', width:60},
                        {name:'nbip', index:'nbip', width:30}
                     ],
          caption: 'Загрузка массива данных'
});
var data = [
            {id: '1', country_code:'AD',  region_code:'02', city:'Canillo', latitude:'42.5667', longitude: '1.6', nbip:'0'},
            {id: '2', country_code:'AD',  region_code:'02', city:'El Tarter', latitude:'42.5833', longitude: '1.65', nbip:'0'},
            {id: '3', country_code:'AD',  region_code:'03', city:'Encamp', latitude:'42.5333', longitude: '1.5833', nbip:'0'},
            {id: '4', country_code:'AD',  region_code:'04', city:'Arinsal', latitude:'42.5667', longitude: '1.4833', nbip:'1'},
            {id: '5', country_code:'AD',  region_code:'04', city:'La Massana', latitude:'42.55', longitude: '1.5167', nbip:'0'},
            {id: '6', country_code:'AD',  region_code:'04', city:'Llorts', latitude:'42.6', longitude: '1.5333', nbip:'0'},
            {id: '7', country_code:'AD',  region_code:'05', city:'Ordino', latitude:'42.55', longitude: '1.5333', nbip:'2'},
            {id: '8', country_code:'AD',  region_code:'06', city:'Sant JuliГ  De LГІria', latitude:'42.4667', longitude: '1.5', nbip:'0'},
            {id: '9', country_code:'AD',  region_code:'07', city:'Andorra La Vella', latitude:'42.5', longitude: '1.5167', nbip:'56'},
            {id: '10', country_code:'AD',  region_code:'08', city:'Engordany', latitude:'42.5167', longitude: '1.55', nbip:'1'},
            {id: '11', country_code:'AD',  region_code:'08', city:'Les Escaldes', latitude:'42.5', longitude: '1.5333', nbip:'0'},
            {id: '12', country_code:'AE',  region_code:'01', city:'Abu Dhabi', latitude:'24.4667', longitude: '54.3667', nbip:'824'},
            {id: '13', country_code:'AE',  region_code:'01', city:'Al Ain', latitude:'24.1917', longitude: '55.7606', nbip:'19'},
            {id: '14', country_code:'AE',  region_code:'03', city:'Deira', latitude:'25.2722', longitude: '55.3111', nbip:'0'},
            {id: '15', country_code:'AE',  region_code:'03', city:'Dubai', latitude:'25.2521', longitude: '55.28', nbip:'7082'},
            {id: '16', country_code:'AE',  region_code:'03', city:'Jumairah', latitude:'25.2097', longitude: '55.2478', nbip:'0'},
            {id: '17', country_code:'AE',  region_code:'04', city:'Fujairah', latitude:'25.1231', longitude: '56.3375', nbip:'1'},
            {id: '18', country_code:'AE',  region_code:'05', city:'Ras Al Khaima', latitude:'25.7911', longitude: '55.9428', nbip:'0'},
            {id: '19', country_code:'AE',  region_code:'05', city:'Ras Al Khaimah', latitude:'25.7911', longitude: '55.9428', nbip:'2'},
            {id: '20', country_code:'AE',  region_code:'06', city:'Dibba', latitude:'25.6167', longitude: '56.2667', nbip:'1'},
            {id: '21', country_code:'AE',  region_code:'06', city:'Sharjah', latitude:'25.3622', longitude: '55.3911', nbip:'297'},
            {id: '22', country_code:'AF',  region_code:'11', city:'Herat', latitude:'34.3469', longitude: '62.1983', nbip:'0'},
            {id: '23', country_code:'AF',  region_code:'13', city:'Kabul', latitude:'34.5167', longitude: '69.1833', nbip:'161'},
            {id: '24', country_code:'AF',  region_code:'23', city:'Iran', latitude:'31.8314', longitude: '65.0689', nbip:'0'},
            {id: '25', country_code:'AF',  region_code:'23', city:'Kandahar', latitude:'31.6125', longitude: '65.7094', nbip:'0'}
           ]
for(var i = 0;i &lt;= data.length; i++){
    $('#table').jqGrid('addRowData',i+1,data[i]);
}
});
</pre>
<p>Как видите и в этом примере нет ничего &laquo;военного&raquo;, все предельно просто.  В качестве <strong>datatype:</strong> указываем <em><strong>&#8216;local&#8217;</strong></em>. Далее каким-либо образом(в данном примере простым присвоением) создаем массив объектов (каждая строка данных является объектом) и производим добавление данных методом <strong>addRowData</strong> в цикле (<em>for(var i = 0;i &lt;= data.length; i++)</em>).<br />
На данном этапе мне следует дать небольшой комментарий. Почему я написал &laquo;&#8230; добавление данных методом &#8230;&raquo; а при этом вся конструкция выглядит как передача параметра. Т.е. фактически происходит передача названия метода addRowData методу jqGrid() в качестве параметра. Дело все в том, что с версии 3.6 разработчики реализовали новый API для работы с jqGrid, согласно которому запись вида <strong>$(&#8216;#table&#8217;).jqGrid(&#8216;addRowData&#8217;,i+1,data[i]);</strong> равноценна <strong>$(&#8216;#table&#8217;).addRowData(i+1,data[i]);</strong> Но будьте внимательны, не все методы могут быть использованы в аннотации нового API, перед использованием методов обязательно ознакомьтесь с документацией по данному методу на странице <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:methods">Methods</a>.</p>
<ul>
<li><strong>addRowData</strong> &#8211; добавляет в таблицу новую строку данных. При этом строка данных должна выглядеть следующим образом {имя1: значение1, имя2: значение2&#8230;}. В качестве первого параметра методу, addRowData передается id вставляемой строки, а вторым объект данных (<strong>addRowData(row_id, row_data)</strong>).</li>
</ul>
<p>Также в свойствах инициализации jqGrid вы не найдете параметров панели-листалки, потому что данные уже загружены и нет необходимости запрашивать их порциями.<br />
Если присмотреться, то можно заметить что данный способ загрузки данных напоминает работу с JSON, но только на стороне клиента. Такой способ может пригодиться если вы по каким-либо причинам не можете сформировать XML или JSON ответ с данными от сервера.<br />
<a title="p1.3" name="p1.3"></a><strong>3) Конвертирование простой таблицы в jqGrid</strong><br />
Данный способ создания jqGrid будет полезен во время &laquo;страховки&raquo; на странице. Т.е. у нас есть страница, на которой есть таблица jqGrid в &laquo;нормальном браузере&raquo;, но как же пользователи у которых браузер не поддерживает JavaScript (Простите но тут обязан быть смайл <img src='http://www.linkexchanger.su/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> )? Они не увидят таблицу? И вот тут то и пригодится данное свойство плагина.<br />
План действий таков:</p>
<ul>
<li>На сервере выполняется скрипт, который выводит в браузер страницу с таблицей и данными.</li>
<li>После загрузки всех элементов страницы выполняется функция преобразования статической таблицы в jqGrid</li>
<li>Ну, а если браузер посетителя-бедолаги не поддерживает JS, то он просто увидит таблицу. Которую кстати можно оформить используя стили jQueryUI CSS Framework.</li>
</ul>
<p>Вот и листинг</p>
<pre class="brush: xml;">
&lt;!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'&gt;
&lt;html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'&gt;
&lt;head&gt;
&lt;meta http-equiv='Content-Type' content='text/html; charset=utf-8' /&gt;
&lt;title&gt;Осваиваем jqGrid с Linkexchanger&lt;/title&gt;&lt;/p&gt;
&lt;link rel='stylesheet' type='text/css' media='screen' href='css/flick/jquery-ui-1.7.2.custom.css' /&gt;
&lt;link rel='stylesheet' type='text/css' media='screen' href='css/ui.jqgrid.css' /&gt;
&lt;p&gt;&lt;style&gt;
html, body {
margin: 0;
padding: 0;
font-size: 80%;
}
&lt;/style&gt;
&lt;script type='text/javascript' src='js/jquery-1.4.min.js'&gt;&lt;/script&gt;
&lt;script src='js/i18n/grid.locale-ru.js' type='text/javascript'&gt;&lt;/script&gt;
&lt;script src='js/jquery.jqgrid.min.js' type='text/javascript'&gt;&lt;/script&gt;
&lt;script type='text/javascript'&gt;
$(function(){
    $('#table').click(function(){
        tableToGrid('#table');
    });
});
&lt;/script&gt;&lt;/head&gt;
&lt;body&gt;
&lt;?php
// Подключение и выбор БД
//$db = mysql_connect('database_host', 'database_user', 'database_password');
//mysql_select_db('database_name');
// Подключение и выбор БД
$db = mysql_connect('database_host', 'database_user', 'database_password');
mysql_select_db('database_name');&lt;/p&gt;
// Запрос выборки данных
$query = 'SELECT id, country_code, region_code, city, latitude, longitude, nbip FROM cities LIMIT 30';
$result = mysql_query($query);
// Строим таблицу с данными
echo &quot;&lt;table id='table' border='1'&gt;&quot;;
echo &quot;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;ID&lt;/th&gt;&lt;th&gt;Код страны&lt;/th&gt;&lt;th&gt;Код региона&lt;/th&gt;&lt;th&gt;Город&lt;/th&gt;&lt;th&gt;Долгота&lt;/th&gt;&lt;th&gt;Широта&lt;/th&gt;&lt;th&gt;nbip&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&quot;;
while($row = mysql_fetch_assoc($result)) {
    echo &quot;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;'.$row['id'].'&lt;/td&gt;&lt;td&gt;'.$row['country_code'].'&lt;/td&gt;&lt;td&gt;'.$row['region_code'].'&lt;/td&gt;&lt;td&gt;'.$row['city'].'&lt;/td&gt;td&gt;'.$row['latitude'].'&lt;/td&gt;&lt;td&gt;'.$row['longitude'].'&lt;/td&gt;&lt;td&gt;'.$row['nbip'].'&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&quot;;
}
echo &quot;&lt;/table&gt;&quot;;
?&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>И ссылка на <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p2e2.php">ДЕМО2.2</a> (просто кликните на таблицу)<br />
Как видите простейший код, при клике на объект <em><strong>#table</strong></em> собственно таблицу, выполняется функция <strong>tableToGrid()</strong> которой в качестве параметра передается селектор таблицы которую следует преобразовать в jqGrid.</p>
<p><strong>Использование свойств при конвертировании таблицы в jqGrid</strong><br />
И раз уж мы начали разговор про этот метод инициализации jqGrid, то давайте рассмотрим на примере <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p2e2_1.php">ДЕМО2.2_1</a> его работу. А следом и код</p>
<pre class="brush: jscript;">
var options = {
                    caption: 'Конвертирование таблицы',
                    width: 800,
                    height: 600,
                    colModel :[
                                {name:'ID', width:20},
                                {name:'Код страны', width:80},
                                {name:'Страна', width:100, formatter:'select', editoptions:{value:&quot;AD:Andorra; AE:United Arab Emirates; AF:Afghanistan; AG:Antigua and Barbuda; AI:Anguilla; AL:Albania; AM:Armenia; AN:Netherland Antilles; AO:Angola; AR:Argentina&quot;}},
                                {name:'Код региона', width:80},
                                {name:'Город', width:90},
                                {name:'Долгота', width:60},
                                {name:'Широта', width:60},
                                {name:'nbip', index:'nbip', width:30}
                   ]};
                   tableToGrid(&quot;#table&quot;,options);
</pre>
<p>Как видите при использовании этой функции, в качестве второго параметра можно передать объект с параметрами таблицы. Но при этом следует обратить внимание на то, что заголовки столбцов должны иметь такое же имя как и текст в заголовке конвертируемой таблицы. Я думаю вы обратили внимание на дополнительные параметры в строке 8, мы рассмотрим их далее в этой статье.<br />
<a title="p2" name="p2"></a><strong>II. Форматирование данных</strong><br />
<a title="p2.1" name="p2.1"></a><strong>1) Форматирование ячеек</strong><br />
Википедия определяет Форматирование как &laquo;приведение чего-либо к какому-либо формату&raquo;. Соответственно в нашем случае это будет преобразование полученных от сервера данных, к другому виду. jqGrid позволяет производить как  простое так и сложное форматирование. &laquo;Простым форматированием&raquo; я условно назвал &laquo;Выравнивание&raquo; и &laquo;Изменением цвета&raquo; данных при этом мы &laquo;форматируем ячейку&raquo;.<br />
Давайте посмотрим как это делается на примере <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p2e3.html">ДЕМО2.3</a></p>
<pre class="brush: jscript;">
$(function(){
    $('#table').jqGrid({
              datatype: 'local',
              colNames:['ID','Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
              colModel :[
                            {name:'id', index:'id', width:20, align: 'center'},
                            {name:'country_code', index:'country_code', width:80, align: 'right'},
                            {name:'region_code', index:'region_code', width:80, align: 'left'},
                            {name:'city', index:'city', width:90},
                            {name:'latitude', index:'latitude', width:60},
                            {name:'longitude', index:'longitude', width:60},
                            {name:'nbip', index:'nbip', width:30}
                         ],
              caption: 'Простое форматирование',
              width: 600,
              afterInsertRow: function(row_id, row_data){
                                if (row_data.country_code == 'AD') {
                                    $('#table').jqGrid('setCell',row_id,'city','',{'color':'#FF00FF'});
                                }else if(row_data.country_code == 'AE'){
                                    $('#table').jqGrid('setCell',row_id,'city','',{'color':'red'});
                                }else{
                                    $('#table').jqGrid('setCell',row_id,'city','',{'background-color': '#999999'});
                              if(row_data.country_code == 'CZ'){
                                        $('#table').jqGrid('setCell',row_id,'city','',{'color':'#FF00FF', 'font-weight':'bold'},{'title': 'Чехия Ура!'});
                                    }
                                }
                            }
    });
var data = [
            {id: '1', country_code:'AD',  region_code:'02', city:'Canillo', latitude:'42.5667', longitude: '1.6', nbip:'0'},
            {id: '2', country_code:'AD',  region_code:'02', city:'El Tarter', latitude:'42.5833', longitude: '1.65', nbip:'0'},
            {id: '3', country_code:'AD',  region_code:'03', city:'Encamp', latitude:'42.5333', longitude: '1.5833', nbip:'0'},
            {id: '4', country_code:'AD',  region_code:'04', city:'Arinsal', latitude:'42.5667', longitude: '1.4833', nbip:'1'},
            {id: '5', country_code:'AD',  region_code:'04', city:'La Massana', latitude:'42.55', longitude: '1.5167', nbip:'0'},
            {id: '6', country_code:'AD',  region_code:'04', city:'Llorts', latitude:'42.6', longitude: '1.5333', nbip:'0'},
            {id: '7', country_code:'AD',  region_code:'05', city:'Ordino', latitude:'42.55', longitude: '1.5333', nbip:'2'},
            {id: '8', country_code:'AD',  region_code:'06', city:'Sant JuliГ  De LГІria', latitude:'42.4667', longitude: '1.5', nbip:'0'},
            {id: '9', country_code:'AD',  region_code:'07', city:'Andorra La Vella', latitude:'42.5', longitude: '1.5167', nbip:'56'},
            {id: '10', country_code:'AD',  region_code:'08', city:'Engordany', latitude:'42.5167', longitude: '1.55', nbip:'1'},
            {id: '11', country_code:'AD',  region_code:'08', city:'Les Escaldes', latitude:'42.5', longitude: '1.5333', nbip:'0'},
            {id: '12', country_code:'AE',  region_code:'01', city:'Abu Dhabi', latitude:'24.4667', longitude: '54.3667', nbip:'824'},
            {id: '13', country_code:'AE',  region_code:'01', city:'Al Ain', latitude:'24.1917', longitude: '55.7606', nbip:'19'},
            {id: '14', country_code:'AE',  region_code:'03', city:'Deira', latitude:'25.2722', longitude: '55.3111', nbip:'0'},
            {id: '15', country_code:'AE',  region_code:'03', city:'Dubai', latitude:'25.2521', longitude: '55.28', nbip:'7082'},
            {id: '16', country_code:'AE',  region_code:'03', city:'Jumairah', latitude:'25.2097', longitude: '55.2478', nbip:'0'},
            {id: '17', country_code:'AE',  region_code:'04', city:'Fujairah', latitude:'25.1231', longitude: '56.3375', nbip:'1'},
            {id: '18', country_code:'AE',  region_code:'05', city:'Ras Al Khaima', latitude:'25.7911', longitude: '55.9428', nbip:'0'},
            {id: '19', country_code:'AE',  region_code:'05', city:'Ras Al Khaimah', latitude:'25.7911', longitude: '55.9428', nbip:'2'},
            {id: '20', country_code:'AE',  region_code:'06', city:'Dibba', latitude:'25.6167', longitude: '56.2667', nbip:'1'},
            {id: '21', country_code:'AE',  region_code:'06', city:'Sharjah', latitude:'25.3622', longitude: '55.3911', nbip:'297'},
            {id: '22', country_code:'AF',  region_code:'11', city:'Herat', latitude:'34.3469', longitude: '62.1983', nbip:'0'},
            {id: '23', country_code:'AF',  region_code:'13', city:'Kabul', latitude:'34.5167', longitude: '69.1833', nbip:'161'},
            {id: '24', country_code:'AF',  region_code:'23', city:'Iran', latitude:'31.8314', longitude: '65.0689', nbip:'0'},
            {id: '25', country_code:'AF',  region_code:'23', city:'Kandahar', latitude:'31.6125', longitude: '65.7094', nbip:'0'},
            {id: '26', country_code:'CZ',  region_code:'23', city:'Stav', latitude:'50.4667', longitude: '15.4667', nbip:'0'}
           ]
for(var i = 0;i &lt;= data.length; i++){
     $('#table').jqGrid('addRowData',i+1,data[i]);
}
});
</pre>
<p>Для этого примера я взял код &laquo;Загрузки данных из массива&raquo;. Давайте разберем, то что изменилось. Во-первых для удобства это таблица имеет ширину 600px (width: 600), во-вторых появился обработчик на событие <strong><em>afterInsertRow</em></strong> и в-третьих &#8211; в набор данных добавилась строка id 26.<br />
Итак выравнивание текста в ячейке осуществляется простым определением свойства align в модели столбца (<em>colModel</em>).<br />
А вот чтобы раскрасить, а также изменить другие стилевые свойства ячейки, нужно писать пользовательскую функцию, например как та что написал я. Давайте разберемся что же происходит.<br />
Сразу после добавления строки в таблицу возникает событие  <strong>afterInsertRow</strong> (все события вы можете изучить на странице <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events">Events</a>), при котором выполняется функция. Функции принимает в качестве параметров (см. описание события) Id строки (row_id) и объект с данными (row_data) текущей строки, вставка которой вызвала событие. Далее смотрим чему равен <strong>country_code</strong> текущей строки.</p>
<ul>
<li>Если <strong>AD</strong> то установить ячейке (setCell) в строке <strong>row_id</strong> с именем  <strong>city</strong> данные <strong>&raquo;</strong> (пусто &#8211; не менять текущие данные) и стиль <strong>color:#FF00FF</strong>. Последнее действие аналогично записи для &laquo;обыкновенной&raquo;  таблицы.</li>
<li>Если <strong>AE</strong> &#8211; аналогично, но цвет текста в ячейке сделать <strong>red</strong>.</li>
<li>Иначе всем остальным ячейкам сделать фон <strong>#999999</strong> и если попадутся строки с <strong>CZ</strong> то выделить такие ячейки жирным шрифтом и присвоить атрибуту <strong>title</strong> текст <strong>&#8216;Чехия Ура!&#8217;</strong>. Атрибуты ячейки можно выставить передав в качестве 5го параметра функции <strong>setCell</strong> объект с именами и значениями этих атрибутов.</li>
</ul>
<p>Как вы понимаете благодаря такому подходу, можно раскрасить таблицу как угодно.<br />
<a title="p2.2" name="p2.2"></a><strong>2) Изменение представления данных</strong><br />
Другим мощным инструментом форматирования данных в jqGrid является набор &laquo;предопределенных форматтеров&raquo; (<a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:predefined_formatter">Predefined Formatter</a>). Это функции, которые выполняются над данными в столбце.<br />
Существует 9 стандартных форматтеров</p>
<ul>
<li><strong>integer</strong> &#8211; форматирование целых чисел</li>
<li><strong>number</strong> &#8211; форматирование любых чисел</li>
<li><strong>currency</strong> &#8211; форматирование денежных величин</li>
<li><strong>date</strong> &#8211; форматирование даты/времени</li>
<li><strong>email</strong> &#8211; форматирование адресов эл. почты</li>
<li><strong>link</strong> &#8211; форматирование ссылок</li>
<li><strong>showlink</strong> &#8211; генератор ссылок</li>
<li><strong>checkbox</strong> &#8211; форматирование данных имеющих два состояния</li>
<li><strong>select </strong>- форматирование данных имеющих множество состояний</li>
</ul>
<pre class="brush: jscript;">
$(function(){
    $('#table').jqGrid({
      url:'p2e4.php',
      datatype: 'json',
      mtype: 'GET',
      colNames:['id', 'integer', 'number', 'currency','date','email','link','showlink','checkbox','select','ip'],
      colModel :[
        {name:'id', index:'id', width:15},
        {name:'integer', index:'integer', width:50},
        {name:'number', index:'number', width:50},
        {name:'currency', index:'currency', width:60},
        {name:'date', index:'date', width:65},
        {name:'email', index:'email', width:70},
        {name:'link', index:'link', width:300},
        {name:'showlink', index:'showlink', width:130},
        {name:'checkbox', index:'checkbox', width:35},
        {name:'select', index:'select', width:30},
        {name:'ip', index:'ip', width:50}],
      caption: 'Данные в чистом виде',
      autowidth: true
    });
$('#tableFormated').jqGrid({
      url:'p2e4.php',
      datatype: 'json',
      mtype: 'GET',
      colNames:['id', 'integer', 'number', 'currency','date','email','link','showlink','checkbox','select','ip'],
      colModel :[
        {name:'id', index:'id', width:15},
        {name:'integer', index:'integer', width:50, formatter:'integer', formatoptions:{defaultValue: 'n.a.'}},
        {name:'number', index:'number', width:50, formatter:'number',formatoptions:{decimalPlaces: 3}},
        {name:'currency', index:'currency', width:60, formatter:'currency',formatoptions:{prefix: '$', suffix:'p.'}},
        {name:'date', index:'date', width:65, formatter: 'date',formatoptions:{srcformat:'Y-m-d H:i:s',newformat:'F d'}},
        {name:'email', index:'email', width:70, formatter: 'email'},
        {name:'link', index:'link', width:300, formatter:'link',formatoptions:{target: '_blank'}},
        {name:'title', index:'title', width:130, formatter:'showlink',formatoptions:{baseLinkUrl: 'http://www.linkexchanger.su/forum/',showAction: 'viewtopic.php', addParam: '&amp;amp;f=4', idName:'t',target: '_blank'}},
        {name:'checkbox', index:'checkbox', width:35, formatter:'checkbox',formatoptions:{disabled: true}},
        {name:'select', index:'select', width:30, formatter:'select', editoptions:{value:&amp;quot;:Все; black:Черный; white:Белый; yellow:Желтый; red:Красный&amp;quot;}},
        {name:'ip', index:'ip', width:50, formatter:long2ip}],
      caption: 'Встроенное форматирование',
      autowidth: true
    });
function long2ip (proper_address) {
        var output = false;
if ( !isNaN( proper_address ) &amp;&amp; ( proper_address &gt;= 0 || proper_address &lt;= 4294967295 ) ) {
            output = Math.floor(proper_address / Math.pow( 256, 3 ) ) + '.' +
                Math.floor( ( proper_address % Math.pow( 256, 3 ) ) / Math.pow( 256, 2 ) ) + '.' +
                Math.floor( ( ( proper_address % Math.pow( 256, 3 ) )  % Math.pow( 256, 2 ) ) / Math.pow( 256, 1 ) ) + '.' +
                Math.floor( ( ( ( proper_address % Math.pow( 256, 3 ) ) % Math.pow( 256, 2 ) ) % Math.pow( 256, 1 ) ) / Math.pow( 256, 0 ) );
        }
return output;
    }
});
</pre>
<p>Работающий код данного примера можно увидеть на <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p2e4.html">ДЕМО2.4</a>. Или если вы хотите скачать его, то вот <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/files/demo2.4.zip">ссылка на архив</a>, внутри клиентский и серверный скрипты, а также дамп БД.<br />
Давайте разберемся как все это работает. Сам пример выглядит как две таблицы и как написано в заголовках, верхняя &#8211; отображает данные с сервера как они есть, а нижняя &#8211; применяет собственные методы форматирования. Как вы уже наверное догадались, в этом примере важен только клиентский код, поэтому серверный скрипт я упростил до минимума, поэтому таблица не сортирует данные в столбцах. Все столбцы кроме последнего названы в соответствии с используемым &laquo;форматтером&raquo;. Все &laquo;форматтеры&raquo; используются одинаково, указывая имя и параметры в colModel таблицы, описания всех параметров доступны на странице <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:predefined_formatter">Predefined Formatter</a> документации плагина.<br />
Теперь подробнее по применению в данном примере.</p>
<ul>
<li><strong>formatter:&#8217;integer&#8217;, formatoptions:{defaultValue: &#8216;n.a.&#8217;}</strong> &#8211; я переназначил значение по-умолчанию, которое будет отображаться в таблице если сервер не вернул никакого значения (пусто).</li>
<li><strong>formatter:&#8217;number&#8217;,formatoptions:{decimalPlaces: 3}</strong> &#8211; для данного типа данных я хочу чтобы после запятой было 3 знака.</li>
<li><strong>formatter:&#8217;currency&#8217;,formatoptions:{prefix: &#8216;$&#8217;, suffix:&#8217;p.&#8217;}</strong> &#8211; для валют нужно ставить вначале $, а в конце р.</li>
<li><strong>formatoptions:{srcformat:&#8217;Y-m-d H:i:s&#8217;,newformat:&#8217;F d&#8217;}</strong> &#8211; для  использования этого &laquo;форматтера&raquo; сначала нужно указать параметру srcformat: маску формата даты в <a href="http://www.php.su/functions/?date">принятом в PHP виде</a>, а затем новый формат newformat:</li>
<li><strong>formatter: &#8216;email&#8217;</strong> &#8211; этот &laquo;форматтер&raquo; не имеет параметров, он всего лишь добавляет mailto: к адресам эл.почты</li>
<li><strong>formatter:&#8217;link&#8217;,formatoptions:{target: &#8216;_blank&#8217;}</strong> &#8211; с помощью &#8216;link&#8217; можно указать target открытия ссылки</li>
<li><strong>formatter:&#8217;showlink&#8217;,formatoptions:{baseLinkUrl: &#8216;http://www.linkexchanger.su/forum/&#8217;, showAction: &#8216;viewtopic.php&#8217;, addParam: &#8216;&amp;f=4&#8242;, idName:&#8217;t', target: &#8216;_blank&#8217;} </strong>- а вот с помощью этого &laquo;форматтера&raquo; можно генерировать ссылки. В нашем примере сервер возвращает название раздела форума linkexchanger в поле <em>showlink</em> в верхней таблице, при этом в нижней таблице вы видите уже готовую ссылку на тему. Это делается указанием следующих параметров:
<ul>
<li><strong>baseLinkUrl:</strong> &#8211; базовая (не изменяющаяся) часть адреса.</li>
<li><strong>showAction:</strong> &#8211; имя скрипта или метода сервера, в нашем примере это скрипт, который показывает тему.</li>
<li><strong>addParam:</strong> &#8211; дополнительные параметры адреса, в нашем случае это идентификатор ветки форума.</li>
<li><strong>idName:</strong> &#8211; какой параметр использовать в качестве имени идентификатора записи, в нашем случае темы форума. А вот сам идентификатор записи (темы на форуме) равен id строки в таблице.</li>
</ul>
</li>
<li><strong>formatter:&#8217;checkbox&#8217;,formatoptions:{disabled: true}</strong> &#8211; удобно использовать при отображении булевых данных (данных которые имеют только два значения), намного нагляднее видеть &laquo;флажок&raquo; вместо 0 или 1 например. При этом &laquo;флажок&raquo; можно сделать активным (formatoptions:{disabled: false}) и использовать при быстром редактировании (об этом в последующих статьях).</li>
<li><strong>formatter:&#8217;select&#8217;, editoptions:{value:&raquo;:Все; black:Черный; white:Белый; yellow:Желтый; red:Красный&raquo;}</strong> &#8211; этот &laquo;форматтер&raquo; очень пригодится при отображении данных, имеющих много значений, но при этом все значения известны. В нашем примере замена названий цветов.</li>
</ul>
<p>На этом Стандартные &laquo;форматтеры&raquo; закончились, а в последнем столбце используется пользовательский. Он представляет из себя функцию <strong>function long2ip (proper_address)</strong> полный <a href="http://www.php.su/functions/?long2ip">аналог PHP&#8217;шной функции</a>, но написанной <a href="http://phpjs.org/functions/index">на и для JS</a>, которая переводит IP из <em>unsignet int</em> в &laquo;человеко-понятный&raquo; вид октетов с точками.<br />
Если возникла необходимость создать сложный пользовательский &laquo;форматтер&raquo; со множеством параметров, то на странице <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:predefined_formatter">Predefined Formatter</a> можно посмотреть пример расширения jqGrid своим &laquo;форматтером&raquo;.<br />
<a title="p3" name="p3"></a><strong>III. Панели инструментов и дополнительные панели</strong><br />
<a title="p3.1" name="p3.1"></a><strong>1) Панель-листалка (Pager)</strong><br />
C этой панелью мы уже знакомы, именно ее мы инициализировали устанавливая свойства <strong>pager:</strong>, <strong>rowNum:</strong>, <strong>rowList:</strong> в предыдущих примерах. В принципе об этой панели рассказывать более нечего, я лишь приведу ссылку на прочие свойства панели <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:pager">Pager</a>, которые возможно понадобятся вам для решения какой-то специфической задачи.<br />
<a title="p3.2" name="p3.2"></a><strong>2) Панель инструментов (Navigator) </strong><br />
Данная панель совсем не является панелью это функция, которая позволяет добавлять элементы управления (кнопки) на панель-листалку. Т.е. если вы хотите использовать pager, то вы обязательно должны его объявить  при инициализации jqGrid хотя бы со стандартными параметрами, без использования <strong>rowNum:</strong>, <strong>rowList:</strong>. После этого уже можно добавлять кнопки, давайте взглянем на <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p2e5.html">ДЕМО2.5</a>. Добавление кнопок стандартных функций.</p>
<pre class="brush: jscript;">
$(function(){
        var pager = $('#tablePager');
$('#table').jqGrid({
                  url:'p2e1.php',
                  datatype: 'json',
                  mtype: 'GET',
                  colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
                  colModel :[
                    {name:'country_code', index:'country_code', width:80},
                    {name:'region_code', index:'region_code', width:80},
                    {name:'city', index:'city', width:90},
                    {name:'latitude', index:'latitude', width:60},
                    {name:'longitude', index:'longitude', width:60},
                    {name:'nbip', index:'nbip', width:30}],
                  pager: pager,
                  sortname: 'city',
                  sortorder: 'asc',
                  caption: 'Pager в качестве панели инструментов',
                  autowidth: true
         }).jqGrid('navGrid', pager);
});
</pre>
<p>Итак друзья мы с вами переступили порог начального уровня использования плагина, с этого момента я буду рассказывать о продвинутых функциях jqGrid.<br />
Как вы уже заметили на листалке появились 6 кнопок, при этом 4 &laquo;практически не работают&raquo;, 1 &#8211; &laquo;практически работает&raquo; и 1 работает, давайте разберемся. Листинг выглядит вполне &laquo;стандартно&raquo;, разве что строка <strong>var pager = $(&#8216;#tablePager&#8217;);</strong> может вызвать легкое недоумение у новичков, но это обычная практика программирования JS, а именно кэширование, об этом написан <a href="http://vl.vg/07.02.2010/cache/">цикл хороших статей</a>, возьмите эту методику на вооружение! Далее вы можете видеть что после инициализации jqGrid я инициализирую панель Navigator используя метод <strong>navGrid</strong>.  Данному методу в качестве первого параметра передается селектор панели листалки, вторым параметром (не указан в листинге) &#8211; объект в котором указывается функции (<em>редактировать, добавить и т.п.</em>) которые необходимо задействовать на панели (например <strong>{view:true, del:false}</strong>), а далее идут объекты с параметрами по каждой из функций в определенном порядке. Давайте я приведу иллюстрацию в виде списка:</p>
<ul>
<li><strong>pagerSelector</strong></li>
<li><strong>{refresh: true(false), add: true(false), del: true(false), edit: true(false), search: true(false), view: true(false)}</strong></li>
<li><strong>{&#8230; параметры редактирования &#8230;}</strong></li>
<li><strong>{&#8230; параметры добавления &#8230;}</strong></li>
<li><strong>{&#8230; параметры удаления &#8230;}</strong></li>
<li><strong>{&#8230; параметры поиска &#8230;}</strong></li>
<li><strong>{&#8230; параметры просмотра &#8230;}</strong></li>
</ul>
<p>Я уверен, что теперь вам стало ясно почему не работают или не совсем работают задействованные функции, потому что они просто не настроены. Т.к. использование этих функций будет рассмотрена в последующих статьях, я не буду продолжать рассмотрение настроек, а перейду к следующему подпункту <em><strong>Добавление пользовательских кнопок</strong></em>.<br />
jqGrid позволяет добавлять на панель pager пользовательские кнопки и назначать на них функции, ниже приведен листинг <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p2e6.html">ДЕМО2.6</a></p>
<pre class="brush: jscript;">
$(function(){
var pager = $('#tablePager');
$('#table').jqGrid({
              url:'p2e1.php',
              datatype: 'json',
              mtype: 'GET',
              colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
              colModel :[
                {name:'country_code', index:'country_code', width:80},
                {name:'region_code', index:'region_code', width:80},
                {name:'city', index:'city', width:90},
                {name:'latitude', index:'latitude', width:60},
                {name:'longitude', index:'longitude', width:60},
                {name:'nbip', index:'nbip', width:30}],
              pager: pager,
              sortname: 'city',
              sortorder: 'asc',
              caption: 'Pager в качестве панели инструментов',
              autowidth: true
     }).jqGrid('navGrid', pager,{add: false, del: false, edit: false, search: false});
$('#table').jqGrid('navSeparatorAdd','#tablePager');
     $('#table').jqGrid('navButtonAdd','#tablePager',{
                                              caption: 'Закрутить ',
                                              title: 'Ключ рожковый, обыкновенный',
                                              buttonicon: 'ui-icon-wrench',
                                              onClickButton: function(){
                                                                 alert('Скрип, скрип, скрип!..');
                                                             },
                                              position:'last'
               }).jqGrid('navButtonAdd','#tablePager',{
                                              caption: 'Замкнуть ',
                                              title: 'Открытый замок',
                                              buttonicon: 'ui-icon-unlocked',
                                              onClickButton: lock,
                                              position:'last'
});
function lock(){
                  alert('Взяли и замкнули что-то...');
              }
});
</pre>
<p>В данном примере после стандартных кнопок, из которых я оставил только &laquo;Обновить&raquo;, вставлен разделитель (separator) и две кнопки &laquo;Закрутить&raquo; и &laquo;Замкнуть&raquo;, простите но оригинальнее я не смог ничего придумать. По нажанию на эту кнопку вызываются функции, которые показывают стандартный alert.<br />
Разделитель добавляется методом <strong>navSeparatorAdd</strong>, первым параметром которого является строка-селектор панели-листалки (pager), а в качестве второго (не указан в листинге) объект с параметрами разделителя.</p>
<blockquote><p>Вот тут следует немного отвлечся и обратить ваше внимание на небольшой ньюанс, возможно разработчики что-то не доделали или не захотели доделать, но при использовании методов <strong>navSeparatorAdd</strong> и <strong>navButtonAdd</strong> в качестве первого параметра должна быть передана именно строка-селектор, но никак не переменная содержащая последний.</p></blockquote>
<p>Параметры разделителя по-умолчанию:<br />
<strong>{sepclass: &#8216;ui-separator&#8217;, sepcontent: &raquo;}</strong><br />
Где</p>
<ul>
<li><strong>sepclass:</strong> &#8211; класс в CSS ui.jqgrid.css, который определяет стиль разделителя. Можно использовать если захотите изменить внешний вид разделителя.</li>
<li><strong>sepcontent:</strong> &#8211; контент, который может быть помещен в разделитель.</li>
</ul>
<p>Кнопка вставляется с помощью метода <strong>navButtonAdd</strong><br />
<strong>{ caption:&#8217;NewButton&#8217;, buttonicon:&#8217;ui-icon-newwin&#8217;, onClickButton:null, position: &#8216;last&#8217;, title:&#8217; &#8216;, cursor: &#8216;pointer&#8217;} </strong><br />
Где</p>
<ul>
<li><strong>caption:</strong> &#8211; надпись на кнопке</li>
<li><strong>title:</strong> &#8211; атрибут кнопки, используется как подсказка</li>
<li><strong>buttonicon:</strong> &#8211; название класса иконки из <a href="http://jqueryui.com/themeroller/">jQuery UI CSS Framework</a></li>
<li><strong>onClickButton:</strong> &#8211; функция, которая будет выполнена при клике на кнопке</li>
<li><strong>position:</strong> (<strong>&#8216;first&#8217;</strong> или <strong>&#8216;last&#8217;</strong>) &#8211; добавить кнопку до или после стандартных кнопок</li>
<li><strong>cursor:</strong> &#8211; CSS свойство, определяющее вид курсора при наведении на элемент</li>
<li><strong>id:</strong> &#8211; с помощью этого свойства можно задать значение атрибуту id контейнеру(TD &#8211; обыкновенная ячейка таблицы) в котором находится кнопка.</li>
</ul>
<p>Однако при всем своем удобстве, у данного подхода к созданию панели инструментов есть ряд недостатков, таких как то что панель находится в нижней части таблицы, мало места для каких-то дополнительных элементов, большого размера и т.п. Для этих целей разработчики добавили еще и возможность создания пользовательских панелей.<br />
<a title="p3.3" name="p3.3"></a><strong>3) Пользовательские панели</strong><br />
Вот <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p2e7.html">ДЕМО2.7</a> листинги которого приведены ниже.<br />
Клиентская часть</p>
<pre class="brush: jscript;">
$(function(){
       $('#table').jqGrid({
           sortable: true,
                  url:'p2e1.php?userdata=true',
                  datatype: 'json',
                  mtype: 'GET',
                  colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
                  colModel :[
                    {name:'country_code', index:'country_code', width:80},
                    {name:'region_code', index:'region_code', width:80},
                    {name:'city', index:'city', width:90},
                    {name:'latitude', index:'latitude', width:60},
                    {name:'longitude', index:'longitude', width:60, resizable: false},
                    {name:'nbip', index:'nbip', width:30}],
                  pager: $('#tablePager'),
          toolbar: [true,'both'],
                  sortname: 'city',
                  sortorder: 'asc',
                  caption: 'Пользовательские панели инструментов',
                  autowidth: true,
                  loadComplete: function() {
                                    var udata = $('#table').jqGrid('getUserData');
                                    $('#tb_table').css('text-align','right').html(udata.msg+' '+udata.sum_regions_numbers+' '+udata.button);
                                }
    });
$(&quot;#t_table&quot;).height(60); //Set height of toolbar
    $(&quot;#t_table&quot;).append('&lt;input id=&quot;say_hello&quot; type=&quot;button&quot; value=&quot;Привет&quot; style=&quot;height:60px; width:80px&quot;&gt;');
    $(&quot;#say_hello&quot;).click(function(){
            alert(&quot;Привет! Спасибо что читаете linkexchanger.su!&quot;);
    });
    $('#show_sum').live('click',function(){
        var val = $(this).val();
        alert('Обратите внимание, с сервера мы получили кнопку с сууммой '+val+', а обработчик назначили уже на странице');
    });
   });
</pre>
<p>И серверная, практически полностью повторяющая пример 2.1</p>
<pre class="brush: php;">
// Начало формирование массива
// для последующего преобразоования
// в JSON объект
$data['page']       = $page;
$data['total']      = $total_pages;
$data['records']    = $count;
// Дополнительная информация с сервера
if($_GET['userdata']){
  $data['userdata']['msg'] = '&lt;span style=&quot;font-weight: normal; color: red;&quot;&gt;Сумма всех чисел в столбце &lt;em&gt;&quot;region_code&quot;&lt;em&gt; равна&lt;/span&gt; ';
  $data['userdata']['sum_regions_numbers'] = '&lt;em&gt;'. $row['sum'].'&lt;em&gt;';
  $data['userdata']['button'] = '&lt;input id=&quot;show_sum&quot; type=&quot;button&quot; value=&quot;'.$row['sum'].'&quot;&gt;';
}
// Строки данных для таблицы
$i = 0;
while($row = mysql_fetch_assoc($result)) {
    $data['rows'][$i]['id'] = $row['id'];
    $data['rows'][$i]['cell'][] = $row['country_code'];
    $data['rows'][$i]['cell'][] = $row['region_code'];
    $data['rows'][$i]['cell'][] = $row['city'];
    $data['rows'][$i]['cell'][] = $row['latitude'];
    $data['rows'][$i]['cell'][] = $row['longitude'];
    $data['rows'][$i]['cell'][] = $row['nbip'];
    $i++;
}
// Перед выводом не забывайте выставить header
// с типом контента и кодировкой
header(&quot;Content-type: text/script;charset=utf-8&quot;);
echo json_encode($data);
</pre>
<p>Ну а теперь по традиции давайте разберем пример подробнее<br />
jqGrig позволяет создавать две независимые панели инструментов. Для этого стоит свойству <strong>toolbar:</strong> присвоить массив <strong>[true,'both']</strong>, элементы которго в данном случае означают, что нужно создать обе(верхнюю и нижнюю) панели инструментов. Вместо <strong>&#8216;both&#8217;</strong> также можно указать <strong>&#8216;top&#8217;</strong> или <strong>&#8216;bottom&#8217;</strong> для верхней и нижней панелей соответственно.<br />
Теперь давайте рассмотрим первый вариант манипуляции с элементами на панелях, начнем с верхней панели. При инициализации плагина с определенным свойством <strong>toolbar:</strong> jqGrid автоматически выставит атрибут  <strong>id</strong> верхней панели как <strong>id=&raquo;t_&raquo;</strong>(<em><strong>&laquo;t_table&raquo;</strong></em> в нашем случае), а нижнюю  <strong>id=&raquo;tb_&raquo;</strong> (<em><strong>&laquo;tb_table&raquo;</strong></em> в нашем случае). С помощью этих идентификаторов можно отыскать &laquo;тулбары&raquo; в DOM и выполнить например такие манипуляции</p>
<pre class="brush: jscript;">
$(&quot;#t_table&quot;).height(60);
$(&quot;#t_table&quot;).append('&lt;input id=&quot;say_hello&quot; type=&quot;button&quot; value=&quot;Привет&quot; style=&quot;height:60px; width:80px&quot;&gt;');
...
$(&quot;#say_hello&quot;).click(function(){
            alert(&quot;Привет! Спасибо что читаете linkexchanger.su!&quot;);
});
</pre>
<p>Первая строка сделает высоту верхней панели равной 60px, а вторая поместит на нее кнопку, код которой вы видите. После этого определяется функция-обработчик которая выполнится при щелчке по добавленной кнопке. Думаю такая методика использования не вызовет затруднений.<br />
А вот второй, альтернативный вариант манипуляций с элементами на панелях, иллюстрируется на примере  нижней панели. Это следующие строки кода</p>
<pre class="brush: jscript;">
...
loadComplete: function() {
                                    var udata = $('#table').jqGrid('getUserData');
                                    $('#tb_table').css('text-align','right').html(udata.msg+' '+udata.sum_regions_numbers+' '+udata.button);
                                }
...
 $('#show_sum').live('click',function(){
        var val = $(this).val();
        alert('Обратите внимание, с сервера мы получили кнопку с суммой '+val+', а обработчик назначили уже на странице');
    });
...
</pre>
<p>Работает это следующим образом. После окончания загрузки данных возникает событие <strong><em>loadComplete:</em></strong> и вызывается функция. Эта функция  (<strong>var udata = $(&#8216;#table&#8217;).jqGrid(&#8216;getUserData&#8217;); </strong>) получает пользовательские данные из ответа сервера, об этом немного ниже, в виде JSON объекта в данном случае и выводит эти данные на нижнюю панель (<strong>$(&#8216;#tb_table&#8217;)</strong>) в виде HTML выравнивая по правому краю (<strong>css(&#8216;text-align&#8217;,'right&#8217;)</strong>). После чего выполняется объявление обработчика используя метод <strong>live</strong>.<br />
Ну откуда же берутся эти пользовательские данные? С сервера как и все остальные! Вот например как сделал я</p>
<pre class="brush: php;">
$userdata = $_GET['userdata'];
// Выполним запрос, который вернет суммарное кол-во записей в таблице
$result = mysql_query(&quot;SELECT COUNT(*)AS count, SUM(region_code) AS sum FROM cities&quot;);
if($userdata){
            $data['userdata']['msg'] = '&lt;span style=&quot;font-weight: normal; color: red;&quot;&gt;Сумма всех чисел в столбце &lt;em&gt;&quot;region_code&quot;&lt;em&gt; равна&lt;/span&gt; ';
            $data['userdata']['sum_regions_numbers'] = '&lt;em&gt;'. $row['sum'].'&lt;em&gt;';
            $data['userdata']['button'] = '&lt;input id=&quot;show_sum&quot; type=&quot;button&quot; value=&quot;'.$row['sum'].'&quot;&gt;';
        }
// Строки данных для таблицы
        $i = 0;
        while($row = mysql_fetch_assoc($result)) {
            $data['rows'][$i]['id'] = $row[id];
            $data['rows'][$i]['cell'][] = $row[country_code];
            }
            echo json_encode($data);
</pre>
<p>Итак я запрашиваю серверный скрипт (<strong>url:&#8217;p2e1.php?userdata=true&#8217;</strong>), который выполняет запрос. После выполнения запроса, вместе с суммарным кол-вом записей получаем сумму всех значений полей  <em><strong>region_code</strong></em>. Далее полученные данные помещаем в массив  <strong>$data</strong> и кодируем в формат JSON.<br />
<a title="p4" name="p4"></a><strong>IV. Управление столбцами данных</strong><br />
<a title="p4.1" name="p4.1"></a><strong>1) Изменение размера и положения столбцов</strong><br />
На самом деле никаких манипуляций для реализации этих возможностей таблицы делать не придется. Возможно вы заметили что в листинге предыдущего примера есть не рассмотренное свойство <strong>sortable: true</strong> и если схватить за заголовок любого из столбцов, то можно drag&#8217;n'drop&#8217;ом переместить его на место другого столбца.  Определение этого свойства как <strong>true</strong> как раз и включает возможность перетаскивать столбцы. Но перед использованием этой опции плагина убедитесь:</p>
<ul>
<li>Что вы послушали мой совет в первой части и при скачивании архива с прагином в <a href="http://www.trirand.com/blog/?page_id=6">Download Builder</a> вы выставили все галки в том числе <strong>jQuiery UI addons</strong>.</li>
<li>Что вы подключили к странице <a href="http://jqueryui.com/demos/">jQueryUI</a>,а именно виджет <a href="http://jqueryui.com/demos/sortable/">sortable</a>.</li>
</ul>
<p>При этом можно изменять ширину любых столбцов, в <em><strong>colModel</strong></em>-опциях которых не определено свойство <strong>resizable: false</strong> как столбец &laquo;Широта&raquo; в <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p2e7.html">ДЕМО2.7</a>, при условии что вы скачали jqGrid с опцией <strong>jQuiery UI addons</strong>.<br />
<a title="p4.2" name="p4.2"></a><strong>2) Скрываем не нужные или отображаем нужные столбцы данных</strong><br />
Начнем обсуждение с <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p2e8.html">ДЕМО2.8</a>.</p>
<pre class="brush: jscript;">
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;../../../_library/css/ui.multiselect.css&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../../../_library/js/ui.multiselect.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
      var table = $('#table');
      table.jqGrid({
                  url:'p2e1.php',
                  datatype: 'json',
                  mtype: 'GET',
                  colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
                  colModel :[
                    {name:'country_code', index:'country_code', width:80, hidden: true},
                    {name:'region_code', index:'region_code', width:80, hidden: true},
                    {name:'city', index:'city', width:90},
                    {name:'latitude', index:'latitude', width:60},
                    {name:'longitude', index:'longitude', width:60},
                    {name:'nbip', index:'nbip', width:30, hidden: true}],
                  pager: $('#tablePager'),
                  toolbar: [true,&quot;top&quot;],
                  sortname: 'city',
                  sortorder: 'asc',
                  caption: 'Управление видимостью столбцов',
                  width: 400
        });

    var tBar = $(&quot;#t_table&quot;);
    tBar.append('&lt;input id=&quot;c_chooser1&quot; type=&quot;button&quot; value=&quot;Базовый мастер&quot;&gt;');
    tBar.append('&lt;input id=&quot;c_chooser2&quot; type=&quot;button&quot; value=&quot;Сторонний мастер&quot;&gt;');

    $(&quot;#c_chooser1&quot;).click(function(){
        table.jqGrid('setColumns',{
                                   colnameview:false,
                                   updateAfterCheck: true
                                  });
    });

    $(&quot;#c_chooser2&quot;).click(function(){
        table.jqGrid('columnChooser');
    });

});
&lt;/script&gt;
</pre>
<p>Первое что бросается в глаза так это то, что не все столбцы показаны, хотя все объявлены. Эта опция будет полезна если у вас имеется очень много колонок, при этом обычно не все они нужны, но могут понадобится при более детальном рассмотрении каких-то строк. Сделать столбец не видимым при инициализации таблицы можно указав в <strong>colModel</strong> колонки свойство  <strong>hidden: true</strong>. Но спрятанные колонки нужно как-то показывать при необходимости. Для таких целей можно воспользоваться 2 способами.</p>
<ul>
<li>Использовать метод  <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:show_hide_columns">setColumns</a>, я предпочитаю этот метод ввиду его простоты, не часто нужно управлять столбцами, но если нужно то этот метод самое оно.</li>
<li>Использовать метод-плагин <a href="http://www.trirand.com/jqgridwiki/doku.php?id=wiki:jquery_ui_methods">columnChooser</a> &#8211; этот подходя для истинных гурманов эстетов, очень эффектен если подключить соответствующие файлы. Для начала скачиваем плагин <a href="http://michael.github.com/multiselect/index.html">UI.MultiSelect</a> и подключаем файлы <strong>ui.multiselect.css</strong> и <strong>ui.multiselect.js</strong> как в демо. И снова напомню что для этого метода jqGrid должна быть с модулями  <strong>jQuiery UI addons</strong>.</li>
</ul>
<p><strong>Послесловие</strong><br />
В данной статье мы рассмотрели очень много вспомогательных возможностей плагина-таблицы jqGrid, при этом мы пересекли черту &laquo;начального использования&raquo; таблицы, от всей души поздравляю! Мы хорошо потрудились и дальше нас ждет еще больше интересного, а именно:</p>
<ul>
<li><strong>jqGrid и &laquo;деревья&raquo;</strong>
<ul>
<li>jqGrid и MySQL деревья</li>
<li>jqGrid и статические деревья</li>
</ul>
</li>
<li><strong>Связывание данных в jqGrid</strong>
<ul>
<li>Простая подтаблица (subgrid)</li>
<li>jqGrid как subgrid</li>
<li>Ведущая и ведомая jqGrid</li>
<li>Перемещение строк данных между таблицами</li>
</ul>
</li>
<li><strong>&#8230;</strong></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2010/486.html/feed</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>jqGrid Часть I: Знакомство</title>
		<link>http://www.linkexchanger.su/2010/118.html</link>
		<comments>http://www.linkexchanger.su/2010/118.html#comments</comments>
		<pubDate>Mon, 25 Jan 2010 18:54:10 +0000</pubDate>
		<dc:creator>TRAHOMOTO</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[jqGrid]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/2010/118.html</guid>
		<description><![CDATA[- Не робейте -, сказала Черная Королева, &#8211; это всего-навсего баранья нога, ни больше ни меньше.
Она вам понравится, уверяю вас.
Познакомьтесь. Алиса, это Баранья Нога.
Баранья Нога, это Алиса.
Предисловие
Весь цикл статей направлен в первую очередь на начинающих разработчиков, которые постигают все прелести jQuery. Которые имеют базовые знания и понимания работы с этой библиотекой. Для разработчиков, которые впервые [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-family: Georgia,'Times New Roman',Times,serif">- Не робейте -, сказала Черная Королева, &#8211; это всего-навсего баранья нога, ни больше ни меньше.<br />
Она вам понравится, уверяю вас.<br />
Познакомьтесь. Алиса, это Баранья Нога.<br />
Баранья Нога, это Алиса.</span></p>
<p><strong>Предисловие</strong></p>
<p>Весь цикл статей направлен в первую очередь на начинающих разработчиков, которые постигают все прелести jQuery. Которые имеют базовые знания и понимания работы с этой библиотекой. Для разработчиков, которые впервые слышат слово jQuery я бы посоветовал цикл видео уроков Евгений Попова (<a href="http://www.evgeniypopov.com/magazine.php?mag=45">Уроки 1-4</a> и <a href="http://www.evgeniypopov.com/magazine.php?mag=46">Уроки 5-6</a>) или книгу Геннадия Самкова<a href="http://www.linkexchanger.su/2010/115.html"> jQuery. Сборник рецептов</a>.</p>
<p>Во всех статьях, я постараюсь максимально подробно охватить материал, чтобы исключить появление примитивных вопросов.<span id="more-118"></span> Также хочется сразу предупредить, я не буду учить вас программированию на PHP, этот материал как и весь ресурс посвящен в первую очередь jQuery и технологиям AJAX. Поэтому пожалйста не задавайте вопросы &laquo;как мне защититься от хакеров?&raquo;, &laquo;как мне сделать авторизацию?&raquo; и т.п., на эту тему вы всегда сможете найти массу материала на дружественных сайтах.</p>
<p><strong>Введение</strong></p>
<p>Любой набор данных можно представить в виде двумерного массива &#8211; таблицы. Я считаю таблицу одним из фундаментальных элементов представления информации. Благодаря такой структуре организации человек может увидеть, оценить и легко манипулировать данными в такой форме.</p>
<p>В данном цикле статей я постараюсь познакомить вас и вместе с вами сам постигнуть все прелести замечательнейшего плагина для jQuery &#8211; jqGrid. Чтобы дать вам почувствовать этого &laquo;монстра&raquo;, да-да именно &laquo;монстра&raquo;, я приведу ссылку на <a href="http://trirand.com/blog/jqgrid/jqgrid.html">демо-галерею</a> сайта разработчика. Рекомендую посмотреть все примеры работы с таблицей.</p>
<p>Лично я, когда увидел &laquo;это&raquo; был шокирован и решил разобрать этот плагин. Но сразу же был разочарован, он не заработал! А перепроверив все еще раз я понял, что проблема не в плагине, а во мне. Вот еще одна причина, по которой я сел за этот цикл. Далее меня настигло еще одно разочарование, скрипт вызывал ошибку в IE и отказывался работать. Это было связанно с багом в коде плагина, которую устранили к версии 3.6.1 (На момент написания статьи, последняя версия была 3.6.2). Таким образом я &laquo;вляпался&raquo; в этот плагин. Уверен вы устали от моей пустой болтовни и следует перейти к делу.</p>
<p><strong>I. Подготовка к установке</strong></p>
<p>Перед началом любых работ нам необходимо заготовить &laquo;инструменты&raquo; и &laquo;материалы&raquo;.<br />
<strong>Инструменты (которые использую я)</strong></p>
<ul>
<li>Apache/2.2.9</li>
<li>PHP/5.2.6</li>
<li>MySQL-server/5.0.51a-24</li>
</ul>
<p>Вобщем все стандартные пакеты в репозитории Debian. Если вы предпочитаете Windows, то я могу посоветовать вам <a href="http://www.denwer.ru/">Denwer</a><br />
<strong>Материалы</strong></p>
<ul>
<li>jQuery &#8211; скачать с <a href="http://jquery.com/">официального сайта</a> или подключить по ссылке Google http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js</li>
<li>jQueryUI CSS Framework (проще говоря тема для jQueryUI) &#8211; выбирайте и скачивате на <a href="http://jqueryui.com/themeroller/">официальном сайте</a></li>
<li>jqGrid Plugin &#8211; скачивайте с <a href="http://www.trirand.com/blog/?page_id=6">официального сайта</a>. <strong><em>ВАЖНО!</em></strong> Выберите все модули, т.к. мы пока разбираемся и будем тестировать все возможности jqGrid! В дальнейшей работе, вы можете выбирать только те модули которые вам необходимы.</li>
</ul>
<p><strong>II. Документ, в котором будет использоваться jqGrid</strong><br />
<em>Аннотация:</em></p>
<ul>
<li>Весь материал, который начинается с этого момента я буду осваивать заново, поэтому все ответы на вопросы я буду искать вмести с вами.</li>
<li>Мы будем работать с кириллицей в кодировке UTF-8. Но я дам некоторые рекомендации при использовании плагина с кодировкой Windows-1251(CP1251) .</li>
</ul>
<p><strong>1) Html &#8211; разметка</strong><br />
Итак создадим документ с разметкой следующего вида:</p>
<pre class="brush: xml;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;title&gt;Осваиваем jqGrid с Linkexchanger&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;table id=&quot;le_table&quot;&gt;&lt;/table&gt;
&lt;div id=&quot;le_tablePager&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Как видите самый незаурядный код чистой страницы, где <em>&lt;table id=&raquo;le_table&raquo;&gt;&lt;/table&gt;</em> это и есть таблица которую вы видели на демо, а <em>&lt;div id=&raquo;le_tablePager&raquo;&gt;&lt;/div&gt;</em> &#8211; это элемент таблицы, &laquo;статус бар&raquo; (status bar), о нем поговорим позже. Здесь следует сказать, что в качестве селектора таблицы лучше использовать именно атрибут ID, почему? Ответ на этот вопрос будет дан по мере изучения плагина.</p>
<p><strong>2) Html + CSS + JS</strong><br />
Далее переходим к подключаем необходимые стили и скрипты. Для начала создадим на сервере, в рабочем каталоге следующую структуру.</p>
<ul>
<li><strong>css/</strong> &#8211; в этом каталоге будут все *.css файлы и прочие файлы относящиеся к визуальному оформлению страницы.</li>
<li><strong>js/</strong> &#8211; в этом каталоге будут все *.js файлы</li>
</ul>
<p>Теперь по каждому каталогу подробнее:</p>
<ul>
<li> <strong>css</strong> &#8211; в него следует положить
<ol> <em><strong> &laquo;jqueryUI Theme&raquo;</strong></em> &#8211; каталог с темой оформления jQueryUI (например flick)</ol>
<ol> <strong><em> ui.jqgrid.css</em></strong> &#8211; дополнительные стили jqGrid (находятся в скачанном в п.I архиве css/ui.jqgrid.css)</ol>
</li>
<li> <strong>js</strong> &#8211; в него следует положить
<ol><strong><em>jQuery</em> </strong>- библиотеку</ol>
<ol><strong><em>Каталог i18n</em></strong> &#8211; это каталог с локализациями плагина, проще говоря с &laquo;языками&raquo; (находятся в скачанном в п.I архиве js/i18n) . На этом этапе я остановлюсь подробнее, потому что тут дам обещанный совет по использованию плагина с кирилице кодировки CP1251. Если вы планируете использовать плагин в таких условиях, то вам необходимо в каталоге i18n найти и переконвертировать кодировку файла grid.locale-ru.js из UTF-8 в CP1251. Рассказ о том как это сделать выходит за рамки данной статьи. Также вы можете не загружать все языки, а выбрать только тот, который вам необходим.</ol>
<ol><em><strong>jquery.jqGrid.min.js</strong></em> &#8211; собственно сам плагин.</ol>
</li>
</ul>
<p>Теперь следует перепроверить всю структуру каталога еще раз. Именно на этом этапе я допустил первую ошибку, упоминавшуюся во введении.</p>
<ul>
<li><strong>/css/</strong>
<ul>
<li>flick/
<ul>
<li>images/</li>
<li>&#8230;</li>
<li>jquery-ui-1.7.2.custom.css</li>
</ul>
</li>
<li>ui.jqgrid.css</li>
</ul>
</li>
<li><strong>/js/</strong>
<ul>
<li>i18n/
<ul>
<li>grid.locale-ru.js</li>
<li>&#8230;</li>
</ul>
</li>
<li>jquery-1.4.min.js</li>
<li>jquery.jqGrid.min.js</li>
</ul>
</li>
</ul>
<p>Далее необходимо подключить всю эту кухню</p>
<pre class="brush: xml;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;
&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html;
charset=utf-8&quot; /&gt;
&lt;title&gt;Осваиваем jqGrid с Linkexchanger&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;css/flick/jquery-ui-1.7.2.custom.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;css/ui.jqgrid.css&quot; mce_href=&quot;css/ui.jqgrid.css&quot; /&gt;
&lt;style&gt;html, body {
    margin: 0;
    padding: 0;
    font-size: 80%;
}
&lt;/style&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery-1.4.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/i18n/grid.locale-ru.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery.jqgrid.min.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table id=&quot;le_table&quot;&gt;&lt;/table&gt;
&lt;div id=&quot;le_tablePager&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Как видите в разметке есть еще дополнительный стиль. Этот стиль задает базовые параметры для отступов и самое главное размер шрифта! Если этого не сделать, то при использовании jQueryUI CSS Framework размер шрифта будет &laquo;не маленьким&raquo; и при этом различным в различных браузерах.</p>
<p><strong>3) MySQL</strong><br />
Как бы мы не хотели, но в данной статье мы никак не сможем обойтись без базы данных. Поэтому я подготовил для вас дамп. Вы можете скачать его по <a title="Дамп MySQL (jqGrid)" href="http://www.linkexchanger.su/wp-content/uploads/2010/01/mysqldump.zip">этой ссылке</a> или <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/files/mysqldump.zip">с моего домашнего сервера</a> и экспортировать в любую БД (MySQL) например используя phpMyAdmin, у данного дампа есть один ньюанс. Аименно у некоторых названий городов &laquo;искаверкана&raquo; кодировка, т.е. проблема в дампе, но никак не в плагине!<br />
В дампе сохранены 10тыс городов с кодами страны, региона, названием на англ., долготой, широтой, и nbit. Фактически это кусок одной таблицы БД распределения IP адресов в интернете. В принципе нам абсолютно не важно, что это будет за БД и для опытов подойдет и такая.</p>
<p><strong>4) PHP</strong><br />
На данном этапе следует создать PHP скрипт, который будет возвращать таблице, запрашиваемую ею информацию. Вот пример такого скрипта для наших нужд</p>
<pre class="brush: php;">&lt;?php
// Подключение и выбор БД
$db = mysql_connect('database_host', 'database_user',
'database_password');
mysql_select_db('database_name');
# ВНИМАНИЕ!!!
# Данный код не имеет проверок запрашиваемых данных
# что может стать причиной взлома!
# Обязательно проверяйте все данные
# поступающие от клиента

// Номер запрашиваемой страницы
$page = $_GET['page'];

// Количество запрашиваемых записей
$limit = $_GET['rows'];

// Номер элемента массива по которому
// следует производить сортировку
// Проще говоря поле, по которому
// следует производить сортировку 
$sidx = $_GET['sidx'];                 

// Направление сортировки
$sord = $_GET['sord'];                         

// Если не указано поле сортировки,
// то производить сортировку по первому полю
if(!$sidx) $sidx =1;                 

// Выполним запрос, который
// вернет суммарное кол-во записей в таблице
$result = mysql_query(&quot;SELECT COUNT(*) AS count FROM cities&quot;);
$row = mysql_fetch_array($result,MYSQL_ASSOC);
 // Теперь эта переменная хранит кол-во записей в таблице
$count = $row['count'];                   

// Рассчитаем сколько всего страниц займут данные в БД
if( $count &gt; 0 &amp;&amp; $limit &gt; 0) {
    $total_pages = ceil($count/$limit);
} else {
    $total_pages = 0;
}                   

// Если по каким-то причинам клиент запросил
if ($page &gt; $total_pages) $page=$total_pages;                   

// Рассчитываем стартовое значение для LIMIT запроса
$start = $limit*$page - $limit;                   

// Зашита от отрицательного значения
if($start &lt; 0) $start = 0;                   

// Запрос выборки данных
$query = &quot;SELECT id, country_code, region_code, city, latitude,
longitude, nbip FROM cities
ORDER BY &quot;.$sidx.&quot; &quot;.$sord.&quot; LIMIT &quot;.$start.&quot;, &quot;.$limit;
$result = mysql_query($query);                   

// Начало xml разметки
$s = &quot;&lt;?xml version='1.0' encoding='utf-8'?&gt;&quot;;
$s .=  &quot;&lt;rows&gt;&quot;;
$s .= &quot;&lt;page&gt;&quot;.$page.&quot;&lt;/page&gt;&quot;;
$s .= &quot;&lt;total&gt;&quot;.$total_pages.&quot;&lt;/total&gt;&quot;;
$s .= &quot;&lt;records&gt;&quot;.$count.&quot;&lt;/records&gt;&quot;;                   

// Строки данных для таблицы
// Не забудьте обернуть
//текстовые данные в &lt;![CDATA[]]&gt;                   

while($row = mysql_fetch_assoc($result)) {
  $s .= &quot;&lt;row id='&quot;. $row[id].&quot;'&gt;&quot;;
  $s .= &quot;&lt;cell&gt;&lt;![CDATA[&quot;. $row[country_code].&quot;]]&gt;&lt;/cell&gt;&quot;;
  $s .= &quot;&lt;cell&gt;&quot;. $row[region_code].&quot;&lt;/cell&gt;&quot;;
  $s .= &quot;&lt;cell&gt;&lt;![CDATA[&quot;. $row[city].&quot;]]&gt;&lt;/cell&gt;&quot;;
  $s .= &quot;&lt;cell&gt;&quot;. $row[latitude].&quot;&lt;/cell&gt;&quot;;
  $s .= &quot;&lt;cell&gt;&quot;. $row[longitude].&quot;&lt;/cell&gt;&quot;;
  $s .= &quot;&lt;cell&gt;&quot;. $row[nbip].&quot;&lt;/cell&gt;&quot;;
  $s .= &quot;&lt;/row&gt;&quot;;
}
$s .= &quot;&lt;/rows&gt;&quot;;                   

// Перед выводом не забывайте выставить header
// с типом контента и кодировкой
header(&quot;Content-type: text/xml;charset=utf-8&quot;);                 

echo $s;
?&gt;</pre>
<p><strong>5) Инициализация плагина</strong><br />
Последний этап подготовительных работ. Здесь мы должны инициализировать плагин JqGrid. Делается это вызовом метода jqGrid(), который в качестве параметра, принимает объект со свойствами таблицы.<br />
Теперь давайте посмотрим на примере разметки, приведенной выше.</p>
<pre class="brush: xml;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;title&gt;Осваиваем jqGrid с Linkexchanger&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;css/flick/jquery-ui-1.7.2.custom.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;css/ui.jqgrid.css&quot; mce_href=&quot;css/ui.jqgrid.css&quot; /&gt;
&lt;style&gt;html, body {
    margin: 0;
    padding: 0;
    font-size: 80%;
}
&lt;/style&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery-1.4.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/i18n/grid.locale-ru.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery.jqgrid.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){           

$('#le_table').jqGrid({
   url:'p1e1.php',
   datatype: 'xml',
   mtype: 'GET',
   colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
   colModel :[
     {name:'country_code', index:'country_code', width:80},
     {name:'region_code', index:'region_code', width:80},
     {name:'city', index:'city', width:90},
     {name:'latitude', index:'latitude', width:60},
     {name:'longitude', index:'longitude', width:60},
     {name:'nbip', index:'nbip', width:30}],
  pager: $('#le_tablePager'),
  rowNum:10,
  rowList:[10,20,30,100],
  sortname: 'city',
  sortorder: 'asc'
});           

});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table id=&quot;le_table&gt;&lt;/table&gt;
&lt;div id=&quot;le_tablePager&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Cейчас можно взглянуть результаты наших трудов. Вот ссылка на просмотр <a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/p1e1.html">ДЕМО1</a> и на архив с <a title="ДЕМО1 jqGrid" href="http://www.linkexchanger.su/wp-content/uploads/2010/01/demo1.zip">ДЕМО1</a> (<a href="http://trahomoto.dlinkddns.com/works/linkexchanger/articles/jqgrid/files/demo1.zip">тот же архив на зеркале</a>)</p>
<p><strong>III. Разбор параметров</strong><br />
Остался последний пункт сегодняшней статьи в котором я дам пояснения по каждому из используемых в данном примере свойств плагина.</p>
<ul>
<li><strong>url</strong> &#8211; этот параметр указывает URL на скрипт</li>
<li><strong>datatype</strong> &#8211; тип возвращаемых сервером данных. В данном примере, плагин ожидает данные с сервера в виде XML. Забегая наперед скажу что в следующей статье мы рассмотрим ответ сервера в виде JSON и Offline варианты использования плагина.</li>
<li><strong>mtype</strong> &#8211; определяет каким методом будут переданы данные серверу</li>
<li><strong>colNames</strong> &#8211; массив с заголовками столбцов таблицы</li>
<li><strong>colModel</strong> &#8211; параметр-массив, каждый элемент которого является объектом свойств столбца с данными
<ul>
<li><strong>name</strong> &#8211; &laquo;имя колонки&raquo;, используется внутренними механизмами jqGrid</li>
<li><strong>index</strong> &#8211; &laquo;имя колонки&raquo;, передается серверу при запросах данных</li>
<li><strong>width</strong> &#8211; ширина столбца в пикселах</li>
</ul>
</li>
<li><strong>pager</strong> &#8211; определяет элемент, который будет преобразован в &laquo;панель-листалку&raquo;. Может быть как строкой (<em>&#8216;#le_tablePager&#8217;</em>) так и объектом jQuery (<em>$(&#8216;#le_tablePager&#8217;)</em>). При этом сами разработчики рекомендуют присваивать этому параметру как раз объект jQuery.</li>
<li><strong>rowNum</strong> &#8211; определяет количество записей запрашиваемых у сервера и отображаемых за &laquo;один раз&raquo; (я написал именно так, потому что jqGrid может динамически подгружать строки с данными, что будет рассмотрено в последующих статьях) по умолчанию.</li>
<li><strong>rowList </strong>- параметр-массив. На основе этого параметра строится выпадающий список, позволяющий изменять кол-во записей выводимых за &laquo;один раз&raquo;</li>
<li><strong>sortname</strong> &#8211; определяет index(столбец) по которому будут отсортированы записи</li>
<li><strong>sortorder</strong> &#8211; определяет направление сортировки. asc &#8211; по возрастанию, desc &#8211; по убыванию.</li>
</ul>
<p>Говоря о параметрах (options) следует сказать, что это лишь крохотная их часть. Эти параметры обеспечивают только базовую функциональность таблице. Множество других параметров мы с вами рассмотрим в последующих статьях, а пока поэкспериментируйте с теми что использованы в этом примере.</p>
<p><strong>IV. Содержание следующей статьи</strong></p>
<ul>
<li>Другие способы загрузки данных
<ul>
<li>В виде JSON объекта</li>
<li>В виде массива</li>
<li>Конвертирование простой таблицы в jqGrid</li>
</ul>
</li>
<li>Форматирование данных
<ul>
<li>Встроенные функции форматирования</li>
<li>Пользовательские функции форматирования</li>
</ul>
</li>
<li>Дополнительные панели и панели инструментов
<ul>
<li>Панель-листалка</li>
<li>Панели инструментов</li>
<li>Пользовательская панель</li>
<li>Управление столбцами данных</li>
</ul>
</li>
</ul>
<p><strong>Выводы</strong><br />
В данной статье мы познакомились с плагином jqGrid, запустили его в базовой функциональности и создали полигон для будущих примеров.</p>
<p>В ходе работы мы поняли принцип работы плагина. Фактически сам плагин это интерфейс пользователя, который отправляет AJAX запросы серверу и получает от него ответ. Таблица отправляет все необходимые параметры, для выборки данных на стороне сервера,  в виде GET запроса, а сервер возвращает в виде набора строк в XML-разметке.</p>
<p>Пожалуйста оставляйте только конструктивные комментария и пожелания, а все вопросы задавайте на форуме!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2010/118.html/feed</wfw:commentRss>
		<slash:comments>50</slash:comments>
		</item>
		<item>
		<title>JavaScript мастер-классы</title>
		<link>http://www.linkexchanger.su/2010/117.html</link>
		<comments>http://www.linkexchanger.su/2010/117.html#comments</comments>
		<pubDate>Mon, 25 Jan 2010 06:34:55 +0000</pubDate>
		<dc:creator>Gennady</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[comet]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/2010/117.html</guid>
		<description><![CDATA[Недавно узнал, что 20-21 февраля в Москве и 27-28 февраля в Санкт-Петербурге пройдут мастер-классы по Javascript, которые будет вести Илья Кантор &#8211; создатель  сайтов algolist.manual.ru и javascript.ru.
Это  мой уважаемый коллега, человек с большим опытом разработки сложных  приложений, в прошлом один из разработчиков javascript-фреймворка Dojo Toolkit.
» Профессиональное javascript-программирование
»  Сложный AJAX и COMET: [...]]]></description>
			<content:encoded><![CDATA[<p>Недавно узнал, что 20-21 февраля в Москве и 27-28 февраля в Санкт-Петербурге пройдут мастер-классы по Javascript, которые будет вести Илья Кантор &#8211; создатель  сайтов <a href="http://algolist.manual.ru">algolist.manual.ru</a> и <a href="http://javascript.ru">javascript.ru</a>.</p>
<p>Это  мой уважаемый коллега, человек с большим опытом разработки сложных  приложений, в прошлом один из разработчиков javascript-фреймворка <a href="http://dojotoolkit.org/">Dojo Toolkit</a>.</p>
<p>» Профессиональное javascript-программирование<br />
»  Сложный AJAX и COMET: тонкости Web 2.0<br />
» Мастер-класс по клиентской оптимизации<br />
» Секреты jQuery</p>
<p>Такие мастер-классы помогут узнать много нового, понять уровень своих знаний, получить новые идеи.</p>
<p>И еще, очень интересно! Принять участие в мастер-классе &laquo;<strong>Секреты jQuery</strong>&raquo; можно будет в режиме on-line.</p>
<p><strong><a href="http://javascript.ru/mk">Исходное объявление на javascript.ru »</a></strong><br />
<span id="more-117"></span></p>
<p>Для понимания материала необходимо знать javascript на минимальном уровне, писать простые скрипты. Содержание мастер-классов построено так, чтобы максимально глубоко раскрыть темы за короткий срок.</p>
<p>Теперь подробнее о содержании мастер-классов.</p>
<h3>&laquo;Профессиональное javascript-программирование&raquo;</h3>
<blockquote><p>- Javascript, browser tips &amp; tricks.<br />
- Фишки DOM, функции/замыкания, ООП &#8211; понятно и в деталях.<br />
- Малоизвестные возможности javascript и браузеров.<br />
- Javascript-фреймворки. Сравнение современных возможностей. jQuery в деталях.<br />
- Полезный инструментарий, который сделает вашу разработку быстрее и качественнее. Гораздо больше, чем Firebug.<br />
- Обмен информацией между окнами с разных доменов<br />
- HTML5: что уже есть, а что нас ждет уже скоро.</p></blockquote>
<p>Этот мастер класс &#8211; отнюдь не об основах javascript, здесь присутствует много информации для профессионалов.<br />
Москва: суббота, 20 февраля, 11.00<br />
Санкт-Петербург: суббота, 27 февраля, 11.00<br />
<em>Продолжительность &#8211; 4 часа.</em></p>
<h3>&laquo;Клиентская оптимизация&raquo;</h3>
<blockquote><p>- Способы и принципы сжатия javascript, что делать, чтобы код сжимался эффективнее.<br />
- Идеальное кеширование. Скрипты и серверная часть.<br />
- Эффективная оптимизация javascript. Подходы, цифры, рецепты.<br />
- Основные приемы оптимизации jQuery.<br />
- Ускорение загрузки страницы через HTTP pipelining.<br />
- Оптимизация с Google Gears и HTML5.<br />
- Google Closure Compiler в деталях<br />
- Удобные инструменты для оптимизации и профайлинга.</p></blockquote>
<p>Про то, как ускорить страницу, почти ничего не делая, и как серьезно ускорить страницу и сайт, если что-то сделать.<br />
Москва: воскресенье, 21 февраля, 11.00<br />
Санкт-Петербург: воскресенье, 28 февраля, 11.00<br />
<em>Продолжительность &#8211; 4 часа.</em></p>
<h3>&laquo;Сложный AJAX и COMET: тонкости Web 2.0&#8243;</h3>
<blockquote><p>- Асинхронная подгрузка событий с сервера (COMET) &#8211; различные варианты, сравнение и примеры реализации.<br />
- Кнопки back-forward, закладки и история с AJAX.<br />
- Cпособы написания чата/оповещающего демона, аспекты производительности и решения.<br />
- Кросс-доменные ограничения, способы их преодоления.<br />
- Асинхронный try..catch. Удобная работа с асинхронностью.<br />
- Инструменты для разработки и отладки сложных AJAX-приложений.<br />
- Специализированный COMET-сервер, установка, расширение, интеграция. Поднимем COMET прямо на мастер-классе.</p></blockquote>
<p>Мастер-класс сделает современные подходы простыми и понятными для вас, позволит улучшить те приложения, которые есть сейчас, и перейти к качественно новой разработке в будущем.<br />
Москва: суббота, 20 февраля, 16.00<br />
Санкт-Петербург: суббота, 27 февраля, 16.00<br />
<em>Продолжительность &#8211; 4 часа.</em></p>
<h3>&laquo;Секреты jQuery&raquo;</h3>
<blockquote><p>1. Как работает поисковой движок jQuery $(&#8216;&#8230;&#8217;).<br />
- Внутреннее устройство. Алгоритм поиска. No magic.<br />
- Почему некоторые очевидные запросы тормозят, и как их ускорять.<br />
- Расширение поискового движка, добавление своих фильтров.<br />
2. Система событий в jQuery.<br />
- Внутреннее устройство.<br />
- Слабо- и недокументированные фичи, отсутствующие в обычных javascript-событиях.<br />
- Влияние системы событий на быстродействие и DOM-манипуляции. Что тормозит и почему.<br />
- Обход утечек памяти.<br />
3. Фишки AJAX.<br />
- Особенные фичи AJAX в jQuery, которых нет в других библиотеках и полезные приемы работы с ними.<br />
4. $.изнутри.<br />
- Внутреннее устройство функции $. Что она делает быстро, а что &#8211; нет.<br />
- Создание плагинов. Внутренний механизм работы $.fn.plugin.<br />
5. jQuery UI.<br />
- Обзор и устройство jQuery UI.<br />
- Написание собственных виджетов. Объявление, вызов методов и т.п. Примеры.<br />
- Приемы для более удобной работы с виджетами.<br />
6. Профайлинг jQuery-приложения<br />
- Как из каши $(вызовов) получить читаемый профиль.<br />
7. Дополнительно.<br />
- Общий обзор библиотеки jQuery, ее сильных и слабых мест. Сравнение с другими фреймворками. Новое в jQuery 1.4.</p></blockquote>
<p>Мастер-класс посвящен слабо документированным особенностям и устройству фреймворка jQuery. Это не вводный курс. Знакомство и опыт работы с фреймворком jQuery &#8211; обязательны.<br />
Москва: воскресенье, 21 февраля, 16.00<br />
Санкт-Петербург: воскресенье, 28 февраля, 16.00<br />
<em>Продолжительность &#8211; 3 часа.</em><br />
<strong>On-line</strong>: суббота, 27 февраля, 20.00-21.50 и воскресенье, 28 февраля, 20.00-21.50</p>
<p><strong><a href="http://javascript.ru/mk">Дополнительная информация, запись на мастер-классы »</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2010/117.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>jQuery. Сборник рецептов</title>
		<link>http://www.linkexchanger.su/2010/115.html</link>
		<comments>http://www.linkexchanger.su/2010/115.html#comments</comments>
		<pubDate>Fri, 22 Jan 2010 09:51:08 +0000</pubDate>
		<dc:creator>Gennady</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery документация]]></category>
		<category><![CDATA[документация jQuery]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/2010/115.html</guid>
		<description><![CDATA[Несколько дней назад в интернет-магазинах появилась в продаже книга &#171;jQuery. Сборник рецептов&#187;. Книга вышла в издательстве &#171;БХВ-Петербург&#187;. Написана она мной &#8211; автором этого блога. См. второе издание >>

Геннадий Самков
jQuery. Сборник рецептов (+ CD-ROM)
Издательство: БХВ-Петербург, 2010 г.
Мягкая обложка, 410 стр.
ISBN 978-5-9775-0495-9
Тираж: 1500 экз.
Формат: 70&#215;100/16


Аннотация:
Книга является сборником решений наиболее часто встречающихся задач при веб-программировании пользовательских интерфейсов с [...]]]></description>
			<content:encoded><![CDATA[<p>Несколько дней назад в интернет-магазинах появилась в продаже книга <strong>&laquo;jQuery. Сборник рецептов&raquo;</strong>. Книга вышла в издательстве &laquo;БХВ-Петербург&raquo;. Написана она мной &#8211; автором этого блога. <a style="color:#f00; font-weight:bold;" href="http://www.linkexchanger.su/2011/842.html">См. второе издание >></a></p>
<ul style="float: right; width: 200px">
<li>Геннадий Самков</li>
<li>jQuery. Сборник рецептов (+ CD-ROM)</li>
<li>Издательство: БХВ-Петербург, 2010 г.</li>
<li>Мягкая обложка, 410 стр.</li>
<li>ISBN 978-5-9775-0495-9</li>
<li>Тираж: 1500 экз.</li>
<li>Формат: 70&#215;100/16</li>
</ul>
<p><a href="http://www.ozon.ru/context/detail/id/4934639/?partner=lexsu&#038;from=bar" title="jQuery. Сборник рецептов" target="_blank"><img style="border:1px solid #333;" src="http://www.linkexchanger.su/wp-content/uploads/2010/01/book2.jpg" alt="jQuery. Сборник рецептов" /></a><span id="more-115"></span></p>
<p><strong>Аннотация:</strong><br />
Книга является сборником решений наиболее часто встречающихся задач при веб-программировании пользовательских интерфейсов с использованием библиотеки jQuery. Рассмотрены практически все методы и вспомогательные функции jQuery, в том числе обеспечивающие взаимодействие jQuery и AJAX. Подробно рассказано о надстройке UI jQuery и приведены описания всех настроек для виджетов, входящих в ее состав, что позволяет использовать книгу в качестве справочника. Приведено большое количество примеров использования наиболее популярных плагинов для jQuery &#8211; создание графиков и диаграмм, фотогалерей, навигационных меню, всплывающих подсказок, работа с веб-формами, таймерами и cookies, обработка табличных данных. Компакт-диск содержит примеры, разобранные в книге, файлы библиотеки jQuery версий 1.2.6 и 1.3.2, файлы надстройки UI jQuery, а также файлы рассмотренных в книге расширений сторонних разработчиков.</p>
<p>От себя могу добавить, что книга написана в таком же духе, как и предыдущая: &laquo;<a href="http://www.linkexchanger.su/2009/87.html">AJAX. Программирование для Интернета</a>&laquo;, т.е. примеры, примеры и еще раз примеры плюс подробные разъяснения&#8230;.</p>
<p><strong>Полное содержание:</strong></p>
<table border="0" width="100%">
<tr>
<td>Введение</td>
<td>1</td>
</tr>
<tr>
<td>Структура книги</td>
<td>1</td>
</tr>
<tr>
<td>Как работать с книгой</td>
<td>2</td>
</tr>
<tr>
<td>Источники информации</td>
<td>3</td>
</tr>
<tr>
<td>Благодарности</td>
<td>4</td>
</tr>
<tr>
<td>
<h3>ЧАСТЬ I. МЕТОДЫ БИБЛИОТЕКИ JQUERY</h3>
</td>
<td>5</td>
</tr>
<tr>
<td>
<h3>Глава 1. Выбор элементов</h3>
</td>
<td>7</td>
</tr>
<tr>
<td>1.1. Базовые правила</td>
<td>7</td>
</tr>
<tr>
<td>1.2. Выбор элементов с учетом иерархии</td>
<td>14</td>
</tr>
<tr>
<td>1.3. Основные фильтры</td>
<td>18</td>
</tr>
<tr>
<td>1.4. Фильтрация по содержимому</td>
<td>24</td>
</tr>
<tr>
<td>1.5. Фильтры видимых и невидимых элементов</td>
<td>28</td>
</tr>
<tr>
<td>1.6. Фильтры атрибутов</td>
<td>29</td>
</tr>
<tr>
<td>1.7. Фильтры элементов форм</td>
<td>35</td>
</tr>
<tr>
<td>1.8. Фильтры состояния элементов форм</td>
<td>37</td>
</tr>
<tr>
<td>1.9. Фильтры элементов-потомков</td>
<td>42</td>
</tr>
<tr>
<td>
<h3>Глава 2. Атрибуты элементов</h3>
</td>
<td>48</td>
</tr>
<tr>
<td>2.1. Управление атрибутами элементов</td>
<td>48</td>
</tr>
<tr>
<td>2.2. Работа с атрибутом class</td>
<td>53</td>
</tr>
<tr>
<td>2.3. Работа с HTML и текстом</td>
<td>54</td>
</tr>
<tr>
<td>2.4. Работа с атрибутом value</td>
<td>57</td>
</tr>
<tr>
<td>
<h3>Глава 3. Визуальные эффекты</h3>
</td>
<td>64</td>
</tr>
<tr>
<td>3.1. Как показывать и скрывать элементы</td>
<td>64</td>
</tr>
<tr>
<td>3.2. Эффекты &laquo;скольжения&raquo; и &laquo;затухания&raquo;</td>
<td>67</td>
</tr>
<tr>
<td>3.3. Создание анимации</td>
<td>71</td>
</tr>
<tr>
<td>3.4. Эффекты UI jQuery</td>
<td>76</td>
</tr>
<tr>
<td>
<h3>Глава 4. Работа с CSS-свойствами</h3>
</td>
<td>81</td>
</tr>
<tr>
<td>4.1. Как получать и устанавливать значения CSS-свойств элементов</td>
<td>81</td>
</tr>
<tr>
<td>4.2. Ширина и высота элементов</td>
<td>85</td>
</tr>
<tr>
<td>4.3. Позиционирование элементов</td>
<td>88</td>
</tr>
<tr>
<td>
<h3>Глава 5. Некоторые методы ядра библиотеки jQuery</h3>
</td>
<td>92</td>
</tr>
<tr>
<td>5.1. Примеры работы с объектом jQuery</td>
<td>92</td>
</tr>
<tr>
<td>5.2. Сохранение и извлечение данных</td>
<td>97</td>
</tr>
<tr>
<td>
<h3>Глава 6. Манипуляции над элементами</h3>
</td>
<td>101</td>
</tr>
<tr>
<td>6.1. Изменение содержимого элементов</td>
<td>101</td>
</tr>
<tr>
<td>6.2. Как вставлять элементы в DOM</td>
<td>103</td>
</tr>
<tr>
<td>6.3. Замена, удаление и копирование элементов</td>
<td>113</td>
</tr>
<tr>
<td>
<h3>Глава 7. Перемещение по элементам</h3>
</td>
<td>120</td>
</tr>
<tr>
<td>7.1. Поиск нужных элементов в DOM</td>
<td>120</td>
</tr>
<tr>
<td>7.2. Фильтрация элементов набора</td>
<td>131</td>
</tr>
<tr>
<td>7.3. Перемещение по цепочке вызовов</td>
<td>138</td>
</tr>
<tr>
<td>
<h3>Глава 8. События и их обработка</h3>
</td>
<td>142</td>
</tr>
<tr>
<td>8.1. Готовность документа</td>
<td>142</td>
</tr>
<tr>
<td>8.2. Назначение, удаление и вызов событий</td>
<td>144</td>
</tr>
<tr>
<td>8.3. Взаимодействие с элементами</td>
<td>152</td>
</tr>
<tr>
<td>8.4. События</td>
<td>155</td>
</tr>
<tr>
<td>
<h3>Глава 9. Взаимодействие jQuery и AJAX</h3>
</td>
<td>161</td>
</tr>
<tr>
<td>9.1. Самое простое</td>
<td>161</td>
</tr>
<tr>
<td>9.2. GET- и POST-запросы</td>
<td>166</td>
</tr>
<tr>
<td>9.3. Вспомогательная функция $.ajax(options)</td>
<td>174</td>
</tr>
<tr>
<td>9.4. Для чего нужна функция $.ajaxSetup(options)</td>
<td>180</td>
</tr>
<tr>
<td>9.5. События AJAX</td>
<td>183</td>
</tr>
<tr>
<td>
<h3>Глава 10. Утилиты jQuery</h3>
</td>
<td>190</td>
</tr>
<tr>
<td>10.1. Некоторые операции с массивами и объектами в jQuery</td>
<td>190</td>
</tr>
<tr>
<td>
<h3>ЧАСТЬ II. РАСШИРЕНИЯ ДЛЯ БИБЛИОТЕКИ JQUERY</h3>
</td>
<td>201</td>
</tr>
<tr>
<td>
<h3>Глава 11. Меню для веб-сайта</h3>
</td>
<td>203</td>
</tr>
<tr>
<td>11.1. Плагин jQuery Multi Level Menu</td>
<td>203</td>
</tr>
<tr>
<td>11.2. Плагин jQuery Drop Line Menu</td>
<td>207</td>
</tr>
<tr>
<td>11.3. Плагин jQuery TreeView</td>
<td>210</td>
</tr>
<tr>
<td>11.4. Делаем меню похожее на Accordion</td>
<td>216</td>
</tr>
<tr>
<td>
<h3>Глава 12. Работа с таблицами</h3>
</td>
<td>219</td>
</tr>
<tr>
<td>12.1. Плагин jQuery DataTables</td>
<td>219</td>
</tr>
<tr>
<td>
<h3>Глава 13. Графики и диаграммы</h3>
</td>
<td>229</td>
</tr>
<tr>
<td>13.1. Плагин jqPlot</td>
<td>229</td>
</tr>
<tr>
<td>
<h3>Глава 14. AJAX-формы</h3>
</td>
<td>242</td>
</tr>
<tr>
<td>14.1. Плагин jQuery Autocomplete</td>
<td>242</td>
</tr>
<tr>
<td>14.2. Плагин jQuery Form</td>
<td>252</td>
</tr>
<tr>
<td>14.3. Плагин jQuery Validate</td>
<td>257</td>
</tr>
<tr>
<td>14.4. Плагин jQuery Uploadify</td>
<td>264</td>
</tr>
<tr>
<td>
<h3>Глава 15. Фотогалереи для сайта</h3>
</td>
<td>274</td>
</tr>
<tr>
<td>15.1. Фотогалерея FancyBox</td>
<td>274</td>
</tr>
<tr>
<td>15.2. Простая фотогалерея</td>
<td>282</td>
</tr>
<tr>
<td>
<h3>Глава 16. Несколько полезных плагинов</h3>
</td>
<td>286</td>
</tr>
<tr>
<td>16.1. jQuery Cookie</td>
<td>286</td>
</tr>
<tr>
<td>16.2. jQuery Corner</td>
<td>288</td>
</tr>
<tr>
<td>16.3. jQuery Timers</td>
<td>293</td>
</tr>
<tr>
<td>16.4. jQuery Cluetip</td>
<td>297</td>
</tr>
<tr>
<td>
<h3>Глава 17. UI jQuery — виджеты</h3>
</td>
<td>303</td>
</tr>
<tr>
<td>17.1. Виджет Accordion</td>
<td>303</td>
</tr>
<tr>
<td>17.2. Виджет Datepicker</td>
<td>314</td>
</tr>
<tr>
<td>17.3. Виджет Dialog</td>
<td>326</td>
</tr>
<tr>
<td>17.4. Виджет Progressbar</td>
<td>334</td>
</tr>
<tr>
<td>17.5. Виджет Slider</td>
<td>337</td>
</tr>
<tr>
<td>17.6. Виджет Tabs</td>
<td>343</td>
</tr>
<tr>
<td>
<h3>Глава 18. UI jQuery — взаимодействие с элементами страницы</h3>
</td>
<td>354</td>
</tr>
<tr>
<td>18.1. Draggable — перемещение элементов</td>
<td>354</td>
</tr>
<tr>
<td>18.2. Droppable — &laquo;сброс&raquo; элементов</td>
<td>364</td>
</tr>
<tr>
<td>18.3. Resizable — изменение размеров элементов</td>
<td>371</td>
</tr>
<tr>
<td>18.4. Selectable — выбор элементов</td>
<td>377</td>
</tr>
<tr>
<td>18.5. Sortable — сортировка элементов</td>
<td>385</td>
</tr>
<tr>
<td>Литература</td>
<td>397</td>
</tr>
<tr>
<td>Приложение. Описание компакт-диска</td>
<td>398</td>
</tr>
<tr>
<td>Предметный указатель</td>
<td>400</td>
</tr>
<tr>
<td>Оглавление</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2010/115.html/feed</wfw:commentRss>
		<slash:comments>74</slash:comments>
		</item>
	</channel>
</rss>

