<?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; php</title>
	<atom:link href="http://www.linkexchanger.su/category/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.linkexchanger.su</link>
	<description>css, html, php, javascript, jQuery, ajax ... - решения, примеры, рецепты</description>
	<lastBuildDate>Tue, 25 May 2010 08:13:42 +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>Yii framework. Часть 1 : Введение</title>
		<link>http://www.linkexchanger.su/2010/418.html</link>
		<comments>http://www.linkexchanger.su/2010/418.html#comments</comments>
		<pubDate>Sat, 06 Mar 2010 04:44:29 +0000</pubDate>
		<dc:creator>M4V23</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/?p=418</guid>
		<description><![CDATA[Предисловие
В этом цикле статей я хочу рассказать о таком замечательном фреймворке, как yii. Предполагается, что у читателя есть некоторый навык работы с php5, особенно с его объектно-ориентированной частью. Я буду стараться охватить как можно больше разных аспектов создания веб-приложений на базе yii, добавляя от себя разные тонкости и хитрости; но не ждите от меня копипаста [...]]]></description>
			<content:encoded><![CDATA[<h2><strong>Предисловие</strong></h2>
<p>В этом цикле статей я хочу рассказать о таком замечательном фреймворке, как yii. Предполагается, что у читателя есть некоторый навык работы с <a href="http://php.net">php5</a>, особенно с его объектно-ориентированной частью. Я буду стараться охватить как можно больше разных аспектов создания веб-приложений на базе yii, добавляя от себя разные тонкости и хитрости; но не ждите от меня копипаста документации или api. И то и другое Вы можете найти на официальном сайте.</p>
<h2><strong>Введение</strong></h2>
<p>Что такое Yii?</p>
<p>Yii это свободный(распространяется под <a href="http://yiiframework.com/license/">new BSD licence</a>) высокопроизводительный объектно-ориентированный расширяемый php-фрэймворк для разработки веб-приложений.<br />
<span id="more-418"></span><br />
Зачем он нужен?</p>
<p>Для удобной разработки веб-приложений и чтобы не изобретать сто раз изобретенный велосипед.</p>
<h3>Основные особенности :</h3>
<ul>
<li>MVC-архитектура</li>
<li>Работа с базами данных</li>
<li>Поддержка кэширования на разных уровнях</li>
<li>Большое количество встроенных компонентов</li>
<li>Возможность простого подключения сторонних библиотек</li>
<li>Интеграция с jQuery</li>
</ul>
<h2><strong>Подготовка:</strong></h2>
<p>Системные требования:</p>
<ul>
<li>Веб-сервер(рекомендуется Apache)</li>
<li>PHP версии не ниже 5.1.0</li>
<li>PDO-совместимая СУБД (MySql, PostgreSQL, SqLite, Microsoft SQL, Oracle8) и соответствующее php-расширение для её поддержки.</li>
</ul>
<p>Рекомендуемые расширения для php:</p>
<ul>
<li>gd – для работы с графикой.</li>
<li>mcrypt – для функций кодирования.</li>
<li>MemCache  или APC – для кэширования, ускорения работы.</li>
</ul>
<p>Такой нехитрый набор в наше время можно найти почти на любом хостинге.</p>
<p>Для домашнего тестирования на linux можно установить пакеты из стандартных репозитариев.Если же Вы предпочитаете на windows, могу порекомендовать в качестве готового решения <a href="http://denwer.ru">denwer</a>.</p>
<p>Для пользователей денвера:</p>
<p>(В данном случае, Z: это диск, монтируемый денвером)<br />
1. Для начала прописываем в переменные окружения путь  Z:\usr\local\php5\<br />
2. Открываем /usr/local/php5/php.ini, ищем строчку extension_dir = &laquo;/usr/local/php5/ext&raquo;, заменяем на extension_dir = &laquo;Z:\usr\local\php5\ext&raquo;<br />
3. session.save_path = &laquo;/tmp&raquo; на session.save_path = &laquo;Z:\tmp&raquo;</p>
<h2><strong>Установка:</strong></h2>
<p>На момент написания статьи, последняя стабильная версия была 1.1.0. Скачать её можно в виде архива по адресу  <a title="http://yiiframework.com/download" href="http://yiiframework.com/download" target="_blank">http://yiiframework.com/download</a><br />
Вся установка сводится к распаковке содержимого архива.Для начала рекомендую распаковать всё в директорию доступную из веб и открыть папку requirments в браузере, чтобы убедиться в наличии всех необходимых компонентов.</p>
<p>Для создания приложения необходимо использовать коммандную строку(ssh при удалённом доступе). Нужно запустить файл yiic.bat(для windows) или yiic(для linux и других unix-based систем) с параметрами webapp /full/path/to/new/wbebapp/.<br />
Например :</p>
<blockquote><p><em>$ /var/www/framework/yiic webapp /var/www/testing</em></p></blockquote>
<p>Убедитесь, что у вас есть права записи в  директорию, где Вы хотите создать веб-приложение и она доступна из web. Можно зайти в нее через браузер и увидеть возможности, предоставлямые yii «из коробки».</p>
<p>Практикой мы займемся в следующей статье, а теперь немного теории.</p>
<p><strong>Модель – Представление – Контроллер(MVC)</strong> – это модульная архитектура, применяющийся в веб-программировании(в частности и в yii). Она направлена на разделение логики(контроллер), управления данными(модель) и пользовательского интерфейса(представление) с целью возможности изменять одни части не внося изменения в другие.</p>
<h3>Основные части, из которых состоит yii:</h3>
<blockquote><p><span style="color: #000000;">В yii имена всех системных классов начинается с перфикса C , с целью недопущения коллизии имён. По этому, пожалуйста, воздержитесь от использования этого префикса в своих классах.</span></p></blockquote>
<p><strong>Входной файл</strong><br />
Входной файл(обычно index.php) это единственный скрипт, с которым контактирует пользователю. Вобщем-то, всё что он делает, это читает конфигурацию и создаёт экземпляр класса CWebApplication.<br />
<strong>Приложение(application)</strong><br />
Приложение(экземпляр класса CWebApplication) обрабатывает запрос пользователя, выполняет роутинг и передаёт его на исполнение соответствующему контроллеру.<br />
<strong>Контроллер(controller)</strong><br />
Контроллер(экзэмпляр класса CController или производного от него) определяет основную логику приложения, взаимодействует с моделями и отображениями. Контроллеры обычно находятся в папке /protected/controllers. По соглашению, класс контроллера и имя файла с ним : NameController.php<br />
<strong>Действие(action)</strong><br />
Действие это тип действия, выполняемого пользователем, например просмотр статьи в блоге или отправка комментария. Обычно является методом контроллера(вида actionName), но может быть вынесенно в отдельный класс.<br />
<strong>Модель (model)</strong><br />
Модель представляет собой сущность данных. Например таблица в базе данных(CActiveRecord) или форма на веб-странице(CForm). Она занимается непосредственной обработкой данных: созданием, получением, изменением. Также представляет интерфейс доступа к валидаторам(validator), проверяющим корректность введённых пользователем данных. Модели находятся в папке /protected/models. Модель обычно имеет имя, соответствующее таблице в бд, которую она представляет.<br />
<strong>Представление(view)</strong><br />
Представление генерирует готовые части страницы, отдаваемой пользователю.Оно не использует логики, кроме как условий и циклов. Представления для каждого контроллера обычно раздельны и хранятся в /protected/views/controllername/.<br />
<strong>Макет (layout)</strong><br />
Макет это специальное представление для вставки других представлений. Обычно он содержит части пользовательского интерфейса, используемого другими представлениями. Например, основной макет может содержать в себе шапку и подвал страницы, места для подключения других представлений и виджетов. Макеты храняться в /protected/views/layouts. По умолчанию используется макет main.php.<br />
<strong>Виджет(widget)</strong><br />
Виджет это компонент для генерации самодостаточного элемента пользовательского интерфейса(например, верхнее меню в тестовом приложении). В zii (библиотеке расширений, поставляемых вместе с yii) имеется большое количество готовых виджетов.<br />
<strong>Компонент(component)</strong><br />
Представляет сущность какого-либо аспекта веб-приложения. Например, авторизация пользователей. В yii много готовых компонентов, которые могут использоваться как в готовом виде, так и расширяться веб-разработчиками.<br />
<strong>Модуль(module)</strong><br />
Модуль, это самодостаточная единица, состоящая из контроллеров, моделей, отображений, и.т.д. Модули используются для разделения сайта на логические части, например форум и блог.</p>
<h2><strong>Заключение</strong></h2>
<p>В первой статье мы узнали, что такое yii, познакомились с базовыми понятиями и подготовили полигон для дальнейшего изучения.</p>
<p>И на последок хочу дать несколько полезных ссылок:</p>
<p><a href="http://yiiframework.com" target="_blank">Оффициальный сайт (en)</a></p>
<p><a href="http://yiiframework.ru" target="_blank">Русскоязычное сообщество (ru)</a></p>
<p><a href="http://dbhelp.ru/" target="_blank">Блог, посвящённый yii (ru) </a></p>
<h2><strong>В следующей статье:</strong></h2>
<p>В следующей статье мы познокомимся со внутренним устройством фреймворка, научимся делать собственные контроллеры, модели и отображения, изучим основы ActiveRecord.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2010/418.html/feed</wfw:commentRss>
		<slash:comments>18</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>11</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>31</slash:comments>
		</item>
		<item>
		<title>AJAX. Программирование для Интернета</title>
		<link>http://www.linkexchanger.su/2009/87.html</link>
		<comments>http://www.linkexchanger.su/2009/87.html#comments</comments>
		<pubDate>Thu, 23 Apr 2009 05:03:33 +0000</pubDate>
		<dc:creator>Gennady</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[DOM]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/2009/87.html</guid>
		<description><![CDATA[Перед кем еще похвастаться, как не перед читателями своего блога? Тем более, что хвастаться я собираюсь по теме. Несколько дней назад в интернет-магазинах появилась в продаже книга &#171;AJAX. Программирование для Интернета&#187;. Книга вышла в издательстве &#171;БХВ-Петербург&#187;. Написана она преподавателем компьютерных дисциплин СПбГПУ &#8211; Санкт-Петербургского государственного политехнического университета Е. С. Бенкен и мной &#8211; автором этого [...]]]></description>
			<content:encoded><![CDATA[<p>Перед кем еще похвастаться, как не перед читателями своего блога? Тем более, что хвастаться я собираюсь по теме. Несколько дней назад в интернет-магазинах появилась в продаже книга <strong>&laquo;AJAX. Программирование для Интернета&raquo;</strong>. Книга вышла в издательстве &laquo;БХВ-Петербург&raquo;. Написана она преподавателем компьютерных дисциплин СПбГПУ &#8211; Санкт-Петербургского государственного политехнического университета Е. С. Бенкен и мной &#8211; автором этого блога.<span id="more-87"></span></p>
<ul style="float: right; width: 200px">
<li>Елена Бенкен, Геннадий Самков</li>
<li>AJAX. Программирование для Интернета (+ CD-ROM)</li>
<li>Издательство: БХВ-Петербург, 2009 г.</li>
<li>Твердый переплет, 464 стр.</li>
<li>ISBN 978-5-9775-0428-7</li>
<li>Тираж: 2000 экз.</li>
<li>Формат: 70&#215;100/16</li>
</ul>
<p><a href="http://www.ozon.ru/context/detail/id/4385582/" target="_blank"><img src="http://www.linkexchanger.su/wp-content/uploads/2009/04/ajax.jpg" alt="Ajax - программирование для Интернета" style="border: medium none " /></a><br />
<strong>От издателя:</strong><br />
Описана технология AJAX и показаны возможности, которые открываются перед разработчиком с ее применением. Рассмотрена объектная модель документа: DOM в JavaSript и DOM-функции в PHP. Изложены основы языка XML и формат JSON. Показан принцип генерации асинхронных запросов к серверу средствами JavaScript. Сделан обзор основных JavaScript-библиотек: Prototype, Scriptaculous, ExtJS и jQuery. Подробно рассмотрены популярные и перспективные библиотеки ExtJS и jQuery: описана объектная модель языка JavaScript, на которой базируются эти библиотеки; применение AJAX-запросов; обработка событий и др. Приведено большое количество практических примеров.</p>
<p>Компакт-диск содержит дистрибутивы Web-сервера, модуля РНР и сервера MySQL, исходные коды описываемых библиотек, распространяемых на основании лицензии GPL, а также примеры из книги.</p>
<p><strong>Читателям:</strong><br />
В ходе чтения следует выполнять примеры, описываемые в книге. Каждый пример стоит изменять и переделывать самому с тем, чтобы лучше понимать, как он работает или как сделать так, чтобы все перестало работать.</p>
<p><img src="http://www.linkexchanger.su/wp-content/uploads/2009/04/smil.gif" style="margin-left: 100px" /></p>
<p><strong>От себя:</strong><br />
А от себя хочу добавить, что библиотеке jQuery в книге уделено достаточно много внимания &#8211; этот раздел занимает 160 страниц. Естественно, что стояла задача показать именно то, как jQuery помогает при использовании AJAX, но для этого необходимо было объяснить базовые понятия самой библиотеки. Поэтому в раздел о jQuery были включена глава о функциях ядра библиотеки, очень подробно рассмотрены практически все селекторы jQuery, рассмотрена работа с событиями в jQuery и манипуляции элементами. И только после этого подробно рассказывается об использовании AJAX. Абсолютно все сопровождается примерами с довольно подробными пояснениями. В общем этим разделом можно <strong><em>пользоваться как мануалом</em></strong> по вышеупомянутым разделам библиотеки.<br />
Жаль конечно, что не удалось рассказать о всей библиотеке &#8211; но наверное это тема для отдельной книги.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2009/87.html/feed</wfw:commentRss>
		<slash:comments>69</slash:comments>
		</item>
		<item>
		<title>LiveStreet &#8211; бесплатный движок социальной сети.</title>
		<link>http://www.linkexchanger.su/2008/72.html</link>
		<comments>http://www.linkexchanger.su/2008/72.html#comments</comments>
		<pubDate>Tue, 11 Nov 2008 09:40:29 +0000</pubDate>
		<dc:creator>Gennady</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[LiveStreet]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/2008/72.html</guid>
		<description><![CDATA[Сейчас все большую популярность в интернете приобретают сайты, где содержимым (контентом) сайта управляют сами пользователи. Они могу наполнять сайт информацией, оценивать эту информацию, оценивать других пользователей, составлять различные рейтинги. Одним словом, они имеют возможность &#171;сформировать&#187; такой сайт, который им нужен. В таких сайтах не последнюю роль играет социальная составляющая.
Так как сайт объединяет людей по какому [...]]]></description>
			<content:encoded><![CDATA[<p>Сейчас все большую популярность в интернете приобретают сайты, где содержимым (контентом) сайта управляют сами пользователи. Они могу наполнять сайт информацией, оценивать эту информацию, оценивать других пользователей, составлять различные рейтинги. Одним словом, они имеют возможность &laquo;сформировать&raquo; такой сайт, который им нужен. В таких сайтах не последнюю роль играет социальная составляющая.<span id="more-72"></span></p>
<p>Так как сайт объединяет людей по какому либо признаку: интересы, место жительства, путешествия и т.п., люди не просто обмениваются информацией &#8211; они общаются. Все это можно объединить под одним определением &#8211; социальная сеть. Подача информации зачастую происходит в виде блогов &#8211; то есть в виде сообщений, опубликованных в каком либо блоге, которые можно обсудить в комментариях. Часто еще блог называют сообществом.</p>
<p>Желающие создать собственный сайт такого рода сталкиваются с одной проблемой &#8211; какой движок (скрипт) выбрать для построения сайта, т.к. программировать самому такую систему сложно и дорого. Еще один критерий &#8211; это бесплатность движка, обычно за хорошие движки их создатели просят денег.</p>
<p>В связи с этим хочу представить вам бесплатный движок социальной сети (или даже блоговой сети) от российский разработчиков &#8211; <strong>LiveStreet</strong>. Этот движок написан на PHP5 и использует в качестве хранения данных реляционную базу данных MySql. Внутренняя архитектура построена на принципе MVC (модель-вид-контроллер) с применением объектно-ориентированного программирования.</p>
<p>Вообще движок построен на ядре собственного фреймворка, используя который можно достаточно просто разработать любой сайт. Но это больше касается программистов PHP. Для них, кстати, на сайте проекта есть документация по ядру.</p>
<p>Но нас больше интересует, какие возможности предоставляет <strong>LiveStreet</strong> с точки зрения пользователей. Итак, возможности:</p>
<ul>
<li>Полная поддержка кодировки UTF-8</li>
<li>Ведение персональных блогов</li>
<li>Возможность создания коллективных блогов</li>
<li>Система рейтингов блогов, топиков, комментариев, пользователей</li>
<li>Система голосования за блоги, топики, комментарии, пользователей</li>
<li>Возможность добавлять топики в избранное</li>
<li>Автоподстановка тегов</li>
<li>Коллективная внутренняя почта</li>
<li>Система контроля доступа (ACL) к разным возможностям сети (создание блога, возможность голосования и т.п.)</li>
<li>Возможность создать закрытый сайт</li>
<li>Система инвайтов</li>
<li>Топики-ссылки</li>
<li>Топики-опросы</li>
<li>Администрирование своих блогов</li>
<li>Назначение модераторов блогов</li>
<li>Настройки оповещений на e-mail</li>
</ul>
<p>Как видно из возможностей, движок предоставляет основные возможности для создания своей собственной социальной сети на основе блогов. Хорошим примером такой сети служит довольно популярные сайт <a href="http://habrahabr.ru" rel="nofollow">Хабрахабр</a>.</p>
<p>Что необходимо на хостинге для установки LiveStreet:</p>
<ul>
<li>PHP5 и расширение mbstring для корректной работы с кодировкой UTF-8</li>
<li>Базы данных MySQL5 с типом таблиц InnoDB (хотя будет работать и на MyISAM)</li>
<li>Веб-сервер Apache с модулем mod_rewrite</li>
</ul>
<blockquote><p>Большинство хостингов удовлетворяют этим требованиям.</p></blockquote>
<p>Процесс установки:</p>
<ul>
<li>Скачать архив со страницы http://livestreet.ru/page/download/</li>
<li>Разархивировать в нужный каталог вашего сайта</li>
<li>Выполнить SQL дамп (sql.sql), предварительно создав базу данных</li>
<li>Настроить коннект к БД (config/config.db.php)</li>
<li>Настроить параметры движка (config/config.php)</li>
<li>Дать права 777 каталогам: logs, uploads, templates\compiled, templates\cache и каталогу для хранения временных файлов (/tmp/)</li>
</ul>
<p>Готово! По умолчанию в системе создается администратор admin с паролем admin.</p>
<p>Ответы на большинство вопросов по использованию движка <strong>LiveStreet</strong> можно найт ина сайте проекта <strong><a href="http://livestreet.ru">http://livestreet.ru</a></strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2008/72.html/feed</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>jQuery Form &#8211; делаем ajax-форму</title>
		<link>http://www.linkexchanger.su/2008/45.html</link>
		<comments>http://www.linkexchanger.su/2008/45.html#comments</comments>
		<pubDate>Mon, 10 Mar 2008 21:05:15 +0000</pubDate>
		<dc:creator>Gennady</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[форма]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/2008/45.html</guid>
		<description><![CDATA[Плагин jQuery Form позволяет не только сделать новые ajax-формы, но и довольно просто &#171;проапгрейдить&#187; уже существующие формы таким образом, чтобы их можно было использовать вместе с Ajax. Основные методы, ajaxForm и ajaxSubmit, собирают информацию из элементов формы, поддерживают многочисленные опции, использование которых даст полный контроль над передачей данных.
Итак, начнем. Нам потребуется подключить к странице два [...]]]></description>
			<content:encoded><![CDATA[<p>Плагин <strong>jQuery Form</strong> позволяет не только сделать новые <strong>ajax-формы</strong>, но и довольно просто &laquo;проапгрейдить&raquo; уже существующие формы таким образом, чтобы их можно было использовать вместе с Ajax. Основные методы, <strong>ajaxForm</strong> и <strong>ajaxSubmit</strong>, собирают информацию из элементов формы, поддерживают многочисленные опции, использование которых даст полный контроль над передачей данных.<span id="more-45"></span></p>
<p>Итак, начнем. Нам потребуется подключить к странице два файла: библиотеку <strong>jQuery</strong> и файл <strong>jquery.form.js</strong>. Сделаем это в разделе <strong>HEAD</strong>.</p>
<pre class="brush: xml;">&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery-1.2.1.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery.form.js&quot;&gt;&lt;/script&gt;</pre>
<p>Затем создадим самую простейшую форму, не содержащую какой-либо специальной разметки:</p>
<pre class="brush: xml;">&lt;form id=&quot;myForm&quot; action=&quot;comment.php&quot; method=&quot;post&quot;&gt;
  Имя: &lt;input type=&quot;text&quot; name=&quot;name&quot; /&gt;
  Комментарий: &lt;textarea name=&quot;comment&quot;&gt;&lt;/textarea&gt;
  &lt;input type=&quot;submit&quot; value=&quot;Комментировать&quot; /&gt;
&lt;/form&gt;</pre>
<p>и добавим еще немного javascript:</p>
<pre class="brush: jscript;">&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function(){
   $(&quot;#myForm&quot;).ajaxForm(function() {
     alert(&quot;Спасибо за комментарий!&quot;);
   });
});
&lt;/script&gt;</pre>
<p>Вот так просто, но поспешу Вас разочаровать &#8211; то, что мы сделали, из серии &laquo;пыль в глаза&raquo;. Объясню почему. Когда мы нажмем кнопку &laquo;Комментировать&raquo; значения полей <strong>name</strong> и <strong>comment</strong> будут переданы методом <strong>POST</strong> файлу <strong>comment.php</strong>. Если сервер вернет успешный ответ (т.е. всего лишь код 200) &#8211; пользователь увидит сообщение &laquo;Спасибо за комментарий!&raquo;.</p>
<blockquote><p>Эффектнее было бы не выводить сообщение в <strong>alert()</strong>, а вставить сообщение непосредственно в <strong>DOM</strong>.</p></blockquote>
<p>Так что все, что мы здесь выиграли &#8211; избавились от перезагрузки страницы, в принципе уже неплохо, но хотелось бы большего&#8230;</p>
<p>Но давайте сначала попробуем выяснить, в чем его отличие метода <strong>ajaxForm</strong> от метода <strong>ajaxSubmit</strong>. Оба метода либо не принимают аргументов, либо принимают один аргумент, который может быть или функцией или объектом (в парах ключ/значение могут быть переданы различные опции).</p>
<p>Первое отличие состоит в  том, что метод <strong>ajaxSubmit</strong> отправляет данные из формы, а метод <strong>ajaxForm</strong> &#8211; нет. Когда вызывается метод <strong>ajaxSubmit</strong> он упорядочивает данные формы в строку запроса и отправляет их серверу. Когда же вызывается метод <strong>ajaxForm</strong> &#8211; он только добавляет необходимое событие в форму таким образом, что можно определить, когда пользователь отправил данные.<br />
Второе отличие: при использовании <strong>ajaxForm</strong> передаваемые значения будут включать пару имя/значение для самой кнопки (как в примере, или координаты клика мышью, если используется картинка).<br />
<strong> Вывод:</strong> это не значит, что метод <strong>ajaxForm</strong> &#8211; плохой, а  метод <strong>ajaxSubmit</strong> &#8211; хороший. Просто они разные. И какой именно метод использовать &#8211; надо решать в каждом конкретном случае.</p>
<p>Давайте теперь познакомимся с доступными опциями, которые принимают оба этих метода. Посмотрим фрагмент кода, чтобы увидеть как задаются опции:</p>
<pre class="brush: jscript;">// готовим объект
var options = {
  target: &quot;#divToUpdate&quot;,
  url: &quot;form.php&quot;,
  success: function() {
        alert(&quot;Спасибо за комментарий!&quot;);
  }
};
// передаем опции в  ajaxSubmit
$(&quot;#myForm&quot;).ajaxSubmit(options);</pre>
<p><strong>target</strong> &#8211; идентифицирует тот элемент (или элементы) на странице, который должен быть обновлен при поступлении ответа от сервера. Значение может быть определено как объект или селектор <strong>jQuery</strong> или элемент <strong>DOM</strong>. Значение по умолчанию &#8211; <strong>null</strong>.<br />
<strong>url</strong> &#8211; URL, куда должны быть переданы данные из формы. Значение по умолчанию &#8211; значение атрибута <strong>action</strong> формы.<br />
<strong>type</strong> &#8211; метод, с помощью которого должны быть отправлены данные из формы (<strong>GET</strong> или <strong>POST</strong>). Значение по умолчанию &#8211; значение атрибута <strong>method</strong> формы. Если атрибут не определен, используется метод <strong>GET</strong>.<br />
<strong>beforeSubmit</strong> &#8211; функция, которая будет вызвана до отправки данных из формы. Функция, вызываемая тут, может позволить выполнить какие-либо действия до отправки данных, например проверку введенных данных. И если она возвращает <strong>false</strong> &#8211; данные не будут отправлены на сервер. Принимает три аргумента: массив с данными формы, jQuery-объект формы, объект из опций определенных в <strong>ajaxForm/ajaxSubmit</strong>. Массив данных формы принимает такой вид:</p>
<pre class="brush: jscript;">[ { name: &quot;username&quot;, value: &quot;Vasya&quot; },
 { name: &quot;password&quot;, value: &quot;secret&quot; } ]</pre>
<p>Значение по умолчанию &#8211; <strong>null</strong>.<br />
<strong>success</strong> &#8211; функция, которая будет вызвана после отправки данных серверу и при условии успешного ответа сервера. Полученные данные &#8211; или <strong>responseText</strong> или <strong>responseXML</strong>, в зависимости от значения опции <strong>dataType</strong>. Значение по умолчанию &#8211; <strong>null</strong>.<br />
<strong>dataType</strong> &#8211; определяет ожидаемый тип данных в ответе сервера. Может принимать значения: <strong>null</strong>, &laquo;<strong>xml</strong>&laquo;, &laquo;<strong>script</strong>&laquo;, или &laquo;<strong>json</strong>&laquo;. Опция позволяет точно определить, как именно должен быть обработан ответ сервера.<br />
<strong>- &laquo;xml&raquo;:</strong> if dataType == &laquo;xml&raquo; ответ сервера рассматривается как <strong>XML</strong> и в <strong>success</strong> (если опция определена) отправляется значение <strong>responseXML</strong>;<br />
<strong>- &laquo;json&raquo;:</strong> if dataType == &laquo;json&raquo; ответ сервера будет выполнен и передан в <strong>success</strong> (если опция определена);<br />
<strong>- &laquo;script&raquo;:</strong> if dataType == &laquo;script&raquo; ответ сервера будет выполнен в глобальном контексте;<br />
Значение по умолчанию &#8211; <strong>null</strong>.<br />
<strong>semantic</strong> &#8211; флаг, определяющий должны ли данные передаваться в строгом порядке следования (это происходит медленнее).</p>
<blockquote><p>Упорядочивание данных формы происходит в порядке следования элементов, исключая элементы <strong>input</strong>, имеющие тип <strong>image</strong>.</p></blockquote>
<p>Вы должны всего лишь установить эту опцию в <strong>true</strong>, если Ваш сервер требует строгого порядка следования <strong>И</strong> форма содержит элементы <strong>input</strong> типа <strong>image</strong>. Значение по умолчанию &#8211; <strong>false</strong>.<br />
<strong>resetForm</strong> &#8211; флаг, определяющий должна ли форма быть сброшена если передача данных была успешной.  Значение по умолчанию &#8211; <strong>null</strong>.<br />
<strong>clearForm</strong> &#8211; флаг, определяющий должна ли форма быть очищена если передача данных была успешной.  Значение по умолчанию &#8211; <strong>null</strong>.</p>
<p>Методы <strong>ajaxForm</strong> и <strong>ajaxSubmit</strong> не единственные. Давайте немного познакомимся с остальными.</p>
<p>Метод <strong>formSerialize</strong> &#8211; упорядочивает данные из элементов формы в строку запроса. Метод возвращает строку в формате: name1=value1&amp;name2=value2.</p>
<pre class="brush: jscript;">var qString = $(&quot;#myFormId&quot;).formSerialize();
  // теперь данные могут быть отправлены
  //  через $.get, $.post, $.ajax, и т.д.
$.post(&quot;myscript.php&quot;, qString);</pre>
<p>Метод <strong>fieldSerialize</strong> &#8211; упорядочивает данные из элементов формы в строку запроса. Удобно применять, когда требуется упорядочить в строку запроса только часть данных из формы. Метод возвращает строку в формате: name1=value1&amp;name2=value2</p>
<pre class="brush: jscript;">var qString = $(&quot;#myFormId .myFields&quot;).fieldSerialize();</pre>
<p>Метод <strong>fieldValue</strong> &#8211; возвращает значения выбранных элементов в виде массива. С версии 0.91, метод всегда возвращает именно массив. Если нет корректных данных возвращается пустой массив, в противном случае массив содержит один или более элементов.</p>
<pre class="brush: jscript;">// получаем значения для полей с типом password
var value = $(&quot;#myFormId :password&quot;).fieldValue();
alert(&quot;Пароль: &quot; + value[0]);</pre>
<p>Метод <strong>resetForm</strong> &#8211; сбросит форму в начальное состояние через новый вызов элементов формы из объектной модели документа.</p>
<pre class="brush: jscript;">$(&quot;#myFormId&quot;).resetForm();</pre>
<p>Метод <strong>clearForm</strong> &#8211; очищает элементы формы. Этот метод очистит все элементы ввода с типом text, password, textarea, очистит выбор в элементах select и снимет отметки с элементов radio и checkbox.</p>
<pre class="brush: jscript;">$(&quot;#myFormId&quot;).clearForm();</pre>
<p>Метод <strong>clearFields</strong> &#8211; очищает элементы формы. Удобно применять когда требуется очистить только часть формы.</p>
<pre class="brush: jscript;">$(&quot;#myFormId .myFields&quot;).clearFields();</pre>
<p>Согласен, согласен&#8230; Получилось очень много и довольно нудно. Поэтому вот Вам пример формы, попробуйте его, а при желании посмотрите исходные коды этого примера. Я старался все очень подробно комментировать.</p>
<p><iframe src="http://www.linkexchanger.su/example_jquery/form.html" style="border: medium none " width="420" height="530"></iframe></p>
<blockquote><p>Вы можете скачать <a href="http://www.linkexchanger.su/example_jquery/form.zip">исходный код</a> примера, и при наличии библиотеки jQuery воспроизвести это пример на своем сайте.</p></blockquote>
<p>Важно! Помните, что любая форма &#8211; потенциальная дыра в безопасности. Никогда не стоит полагаться на проверку данных на стороне клиента. Обязательно производите проверку данных на сервере!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2008/45.html/feed</wfw:commentRss>
		<slash:comments>84</slash:comments>
		</item>
		<item>
		<title>Как работать с JSON?</title>
		<link>http://www.linkexchanger.su/2008/41.html</link>
		<comments>http://www.linkexchanger.su/2008/41.html#comments</comments>
		<pubDate>Mon, 03 Mar 2008 05:50:06 +0000</pubDate>
		<dc:creator>Gennady</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/2008/41.html</guid>
		<description><![CDATA[Вероятно Вы уже прочитали статью &#171;Что такое JSON?&#171;. Если нет, то я рекомендую сначала ознакомиться именно с ней, чтобы понять все с самого начала. А здесь мы поговорим о преобразованиях объектов JavaScript в формат JSON и обратных преобразованиях строки ответа от сервера в формате JSON в объект JavaScript, а также рассмотрим средства для работы с [...]]]></description>
			<content:encoded><![CDATA[<p>Вероятно Вы уже прочитали статью &laquo;<a href="http://www.linkexchanger.su/2008/40.html">Что такое JSON?</a>&laquo;. Если нет, то я рекомендую сначала ознакомиться именно с ней, чтобы понять все с самого начала. А здесь мы поговорим о преобразованиях объектов JavaScript в формат <strong>JSON</strong> и обратных преобразованиях строки ответа от сервера в формате <strong>JSON</strong> в объект JavaScript, а также рассмотрим средства для работы с <strong>JSON</strong> на стороне сервера.<span id="more-41"></span></p>
<p>Дуглас Крокфорд (Douglas Crockford), который собственно и предложил <strong>формат JSON</strong> в качестве альтернативы XML при передаче данных от сервера клиенту, в рамках этого проекта разработал специальную утилиту, предназначенную для упомянутых выше преобразований. Исходник можно найти по адресу <a href="http://www.json.org/js.html" target="_blank">http://www.json.org/js.html.</a></p>
<p>В предыдущей статье о <strong>JSON</strong> мы уже немного коснулись преобразования строки данных в объект JavaScript с помощью функции <strong>eval()</strong>, но все-таки нельзя забывать о том, что функция эта не только поможет интерпретировать данные в формат JSON, но и выполнит любой JavaScript-код, который будет ей передан. Так как это обстоятельство может представлять собой потенциальную угрозу, логичнее воспользоваться утилитой Дугласа Крокфорда.</p>
<p>Но давайте обо всем по порядку. Для начала подключим утилиту к нужному файлу:</p>
<pre class="brush: jscript;">&lt;script src=&quot;json.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</pre>
<p>Создадим объект <strong>oAuto</strong> обычным способом, забыв о литеральной нотации.</p>
<pre class="brush: jscript;">var oAuto = new Object();
oAuto.firm = &quot;Audi&quot;;
oAuto.model = &quot;A6&quot;;
oAuto.year = 2008;
oAuto.price = 78000;
oAuto.sellers = new Array(
  &quot;Фирма А&quot;,
  &quot;Фирма Б&quot;,
  &quot;Фирма В&quot;
);</pre>
<p>Передадим объект методу <strong>JSON.stringify()</strong></p>
<pre class="brush: jscript;">document.write(JSON.stringify(oAuto));</pre>
<p>и в результате работы этого небольшого кусочка кода будет выведена <strong>строка в формате JSON</strong>, которую можно передавать по любому адресу.</p>
<pre class="brush: jscript;">{&quot;firm&quot;:&quot;Audi&quot;,&quot;model&quot;:&quot;A6&quot;,&quot;year&quot;:2008,
&quot;price&quot;:78000,&quot;sellers&quot;:[&quot;Фирма А&quot;,&quot;Фирма Б&quot;,&quot;Фирма В&quot;]}</pre>
<p>Предположим теперь, что эту самую строку мы получили в качестве ответа от сервера и ее надо преобразовать в объект JavaScript. Так нет ничего проще. Передаем строку методу <strong>JSON.parse()</strong></p>
<pre class="brush: jscript;">var oAuto = JSON.parse(sAuto);</pre>
<p>и получаем объект JavaScript.</p>
<blockquote><p>Вы можете скачать <a href="http://www.linkexchanger.su/example_json/json.zip">исходный код</a> примера, и испытать его на своем сайте.</p></blockquote>
<p>Необходимо упомянуть также, что метод <strong>JSON.parse()</strong> может принимать опционально еще один параметр.</p>
<pre class="brush: jscript;">var myObject = JSON.parse(myJSONtext, filter);</pre>
<p>Более полную информацию Вы всегда можете найти на сайте <a href="http://www.json.org/json-ru.html">http://www.json.org/</a>.</p>
<p>Мы вкратце познакомились с тем, как можно работать с данными в формате <strong>JSON</strong> на стороне клиента, а как обстоит дело при работе на стороне сервера? Оказывается существует довольно много программного обеспечения для работы с <strong>JSON</strong> в языках на которых пишутся серверные сценарии. <strong>JSON</strong> может применяться в <strong>Pyton</strong>, <strong>C#/.NET</strong>, <strong>PHP</strong>, <strong>ColdFusion</strong>, <strong>Perl</strong>, <strong>Java</strong> и т.д. Полный список можно найти на <a href="http://www.json.org/json-ru.html">http://www.json.org/</a>, а я для примера выбрал <strong>PHP</strong>, как наиболее близкий мне.</p>
<p>Утилита <strong>JSON-PHP</strong> написана Михалем Мигурски (Michal Migurski). Сама утилита &#8211; это один файл JSON.PHP, но для работы с утилитой требуется библиотека <strong>PEAR</strong> (PHP Extension and Application Repository). Скачать утилиту можно отсюда <a href="http://pear.php.net/pepr/pepr-proposal-show.php?id=198" target="_blank">http://pear.php.net/pepr/pepr-proposal-show.php?id=198</a>.</p>
<blockquote><p>Если Ваш хостер не удосужился включить библиотеку PEAR &#8211; не расстраивайтесь. Вы вполне можете сделать все самостоятельно. Не обязательно даже иметь права администратора сервера. Я приведу ссылки. Кому очень понадобится &#8211; тот обязательно разберется.<br />
<a href="http://pear.php.net/manual/en/installation.getting.php" target="_blank">http://pear.php.net/manual/en/installation.getting.php</a> &#8211; см. раздел &laquo;PEAR in hosting environments&raquo;.<br />
В принципе нужно только получить инсталляционный файл, загрузить его на свой сервер, вызвать в адресной строке браузера и далее только следовать инструкциям.<br />
А <a href="http://subscribe.ru/archive/inet.webbuild.php5whatsnew/200512/30010819.html" target="_blank">здесь</a> посмотрите раздел &laquo;Динамическая коррекция пути к включаемым файлам&raquo;.</p></blockquote>
<p>Разберем все на примере. Пусть имеем такое определение класса (для PHP5)</p>
<pre class="brush: php;">
class Auto {
  public $firm;
  public $model;
  public $year;
  public $price;
  public $sellers;

  function Auto($firm,$model,$year,$price) {
    $this-&gt;firm = $firm;
    $this-&gt;model = $model;
    $this-&gt;year = $year;
    $this-&gt;price = $price;
    $this-&gt;sellers = array();
  }
}</pre>
<p>Используем этот класс так:</p>
<pre class="brush: php;">
$oAuto = new Auto(&quot;Audi&quot;, &quot;A6&quot;, 2008, 78000);
$oAuto-&gt;sellers[0] = &quot;Фирма А&quot;;
$oAuto-&gt;sellers[1] = &quot;Фирма Б&quot;;
$oAuto-&gt;sellers[2] = &quot;Фирма В&quot;;
</pre>
<p>Теперь то, что нас интересует больше всего. Подключаем утилиту <strong>JSON-PHP</strong>, создаем новый экземпляр объекта <strong>Services_JSON</strong> и передаем объект <strong>$oAuto</strong> методу <strong>encode()</strong>:</p>
<pre class="brush: php;">require_once(&quot;JSON.php&quot;);
$json = new Services_JSON();
$sJSONText = $json-&gt;encode($oAuto);</pre>
<p>В результате переменная <strong>$sJSONText</strong> будет содержать строку в формате <strong>JSON</strong>:</p>
<pre class="brush: jscript;">{&quot;firm&quot;:&quot;Audi&quot;,&quot;model&quot;:&quot;A6&quot;,&quot;year&quot;:2008,&quot;price&quot;:78000,
&quot;sellers&quot;:[&quot;\u0424\u0438\u0440\u043c\u0430 \u0410&quot;,&quot;\u0424\u0438\u0440\u043c\u0430 \u0411&quot;,&quot;\u0424\u0438\u0440\u043c\u0430 \u0412&quot;]}</pre>
<blockquote><p>Здесь хочу обратить Ваше внимание на то, что утилита <strong>JSON-PHP</strong> понимает строки или в <strong>ASCII</strong>, или в <strong>UTF-8</strong>. Поэтому существенный выигрыш можно получить при использовании латинских символов, тогда как использование кириллицы в кодировке windows-1251 может привести к увеличению объема данных. Обратите внимание на то место в строке, где должны передаваться Фирма А, Фирма Б, Фирма В.</p></blockquote>
<p>Но цели мы достигли &#8211; объект <strong>$oAuto</strong> готов к передаче в сценарий на языке JavaScript.</p>
<p>Разберем обратную операцию &#8211; преобразование строки текста в формате <strong>JSON</strong> в объект <strong>PHP</strong>. Все, что для этого нужно сделать, это передать строку методу <strong>decode()</strong>:</p>
<pre class="brush: php;">$value = $json-&gt;decode($sJSONText);</pre>
<p>Если теперь использовать например <strong>print_r()</strong>, то мы сможем убедиться, что объект был создан:</p>
<pre class="brush: php;">
( [firm] =&gt; Audi [model] =&gt; A6
[year] =&gt; 2008 [price] =&gt; 78000
[sellers] =&gt; Array ( [0] =&gt; Фирма А [1] =&gt; Фирма Б [2] =&gt; Фирма В ) )</pre>
<p>Все это есть в примере, который Вы сможете скачать. Пример включает и утилиту <strong>JSON-PHP</strong>. Естественно, Вам придется немного поправить пример в той части, где корректируются пути к библиотеке <strong>PEAR</strong>, либо удалить этот фрагмент кода, если библиотека у Вас уже подключена.</p>
<blockquote><p>Архив с примером можно <a href="http://www.linkexchanger.su/example_json/json2.zip">скачать</a> здесь.</p></blockquote>
<p>Что можно еще сказать? Разве что упомянуть о том, что утилита <strong>JSON-PHP</strong> не единственная для работы с <strong>JSON</strong> на стороне сервера. Существует расширение PHP &#8211; <strong>php-json</strong> (написано на C Омаром Килани (Omar Kilani)), однако для его установки потребуется умение устанавливать модули расширения PHP. Вот и все, пожалуй.</p>
<p>Буду рад, если найдете время для того, чтобы оставить свои отзывы&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2008/41.html/feed</wfw:commentRss>
		<slash:comments>44</slash:comments>
		</item>
		<item>
		<title>PHP: запись информации в текстовый файл</title>
		<link>http://www.linkexchanger.su/2008/10.html</link>
		<comments>http://www.linkexchanger.su/2008/10.html#comments</comments>
		<pubDate>Sun, 13 Jan 2008 20:00:10 +0000</pubDate>
		<dc:creator>Gennady</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[запись]]></category>
		<category><![CDATA[скрипт]]></category>
		<category><![CDATA[файл]]></category>

		<guid isPermaLink="false">http://www.linkexchanger.su/10</guid>
		<description><![CDATA[Чтение и запись в текстовый файл казалось бы простейшая операция. Блокировал, открыл, записал, закрыл, снял блокировку с файла. Однако просто это только на первый взгляд&#8230;.
Давайте подумаем, что произойдет, если к одному и тому же файлу одновременно обратятся несколько процессов, с целью записать туда какую-либо информацию? Могу сразу ответить: часть, либо вся информация, хранящаяся в файле [...]]]></description>
			<content:encoded><![CDATA[<p>Чтение и запись в текстовый файл казалось бы простейшая операция. Блокировал, открыл, записал, закрыл, снял блокировку с файла. Однако просто это только на первый взгляд&#8230;.</p>
<p>Давайте подумаем, что произойдет, если к одному и тому же файлу одновременно обратятся несколько процессов, с целью записать туда какую-либо информацию? Могу сразу ответить: часть, либо вся информация, хранящаяся в файле будет безвозвратно потеряна. И просто блокировкой файла здесь не обойтись.<span id="more-10"></span></p>
<p>Такая задача встала передо мной при написании скрипта каталога для обмена ссылками <a href="http://www.linkexchanger.ru" target="_blank">LinkExchanger</a>. Информация там должна была храниться именно в файлах. В итоге получилась вот такая функция, код которой приведен ниже&#8230;</p>
<pre class="brush: php;">
function WriteToFile ($path_to_file,$data) {
	$lock = fopen(PATH_BLOCKFILE,&quot;a&quot;);
	if(flock($lock, LOCK_EX)) {
		$tmp=fopen(PATH_TEMPFILE,&quot;w&quot;);
		for($i=0;$i&lt;count($data);$i++) {
			fputs($tmp, &quot;$data[$i]\n&quot;);
		}
		fclose($tmp);
		unlink(&quot;$path_to_file&quot;);
		rename(PATH_TEMPFILE, &quot;$path_to_file&quot;);
		flock($lock, LOCK_UN);
		fclose($lock);
	}
}
</pre>
<p>Давайте разберем очень подробно, как это работает.<br />
Функция WriteToFile принимает два аргумента: путь к файлу, в который будет записана информация и собственно информация, представленная в виде массива. Нам понадобятся еще два файла, пути к которым определяются константами PATH_BLOCKFILE и PATH_TEMPFILE. Собственно из названий понятно, что первый &#8211; это некий блокирующий файл, а второй &#8211; файл для временного хранения информации.</p>
<p>Первое, что мы делаем &#8211; открываем на запись блокирующий файл. Далее ставим на него блокировку, и если эта операция прошла успешно, открываем на запись временный файл, в который и пишем нашу информацию.<br />
Закрываем временный файл, удаляем исходный файл и переименовываем временный файл, давая ему имя исходного. Далее снимаем блокировку с блокирующего файла и закрываем его.<br />
Это все. Проверено годами работы в условиях массового использования и на самых различных хостингах.<br />
Единственное, за чем надо следить, чтобы при добавлении информации не было превышено допустимое дисковое пространство.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.linkexchanger.su/2008/10.html/feed</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
	</channel>
</rss>
