— Не робейте -, сказала Черная Королева, – это всего-навсего баранья нога, ни больше ни меньше.
Она вам понравится, уверяю вас.
Познакомьтесь. Алиса, это Баранья Нога.
Баранья Нога, это Алиса.
Предисловие
Весь цикл статей направлен в первую очередь на начинающих разработчиков, которые постигают все прелести jQuery. Которые имеют базовые знания и понимания работы с этой библиотекой. Для разработчиков, которые впервые слышат слово jQuery я бы посоветовал цикл видео уроков Евгений Попова (Уроки 1-4 и Уроки 5-6) или книгу Геннадия Самкова jQuery. Сборник рецептов.
Во всех статьях, я постараюсь максимально подробно охватить материал, чтобы исключить появление примитивных вопросов.Также хочется сразу предупредить, я не буду учить вас программированию на PHP, этот материал как и весь ресурс посвящен в первую очередь jQuery и технологиям AJAX. Поэтому пожалйста не задавайте вопросы «как мне защититься от хакеров?», «как мне сделать авторизацию?» и т.п., на эту тему вы всегда сможете найти массу материала на дружественных сайтах.
Введение
Любой набор данных можно представить в виде двумерного массива – таблицы. Я считаю таблицу одним из фундаментальных элементов представления информации. Благодаря такой структуре организации человек может увидеть, оценить и легко манипулировать данными в такой форме.
В данном цикле статей я постараюсь познакомить вас и вместе с вами сам постигнуть все прелести замечательнейшего плагина для jQuery – jqGrid. Чтобы дать вам почувствовать этого «монстра», да-да именно «монстра», я приведу ссылку на демо-галерею сайта разработчика. Рекомендую посмотреть все примеры работы с таблицей.
Лично я, когда увидел «это» был шокирован и решил разобрать этот плагин. Но сразу же был разочарован, он не заработал! А перепроверив все еще раз я понял, что проблема не в плагине, а во мне. Вот еще одна причина, по которой я сел за этот цикл. Далее меня настигло еще одно разочарование, скрипт вызывал ошибку в IE и отказывался работать. Это было связанно с багом в коде плагина, которую устранили к версии 3.6.1 (На момент написания статьи, последняя версия была 3.6.2). Таким образом я «вляпался» в этот плагин. Уверен вы устали от моей пустой болтовни и следует перейти к делу.
I. Подготовка к установке
Перед началом любых работ нам необходимо заготовить «инструменты» и «материалы».
Инструменты (которые использую я)
- Apache/2.2.9
- PHP/5.2.6
- MySQL-server/5.0.51a-24
Вобщем все стандартные пакеты в репозитории Debian. Если вы предпочитаете Windows, то я могу посоветовать вам Denwer
Материалы
- jQuery – скачать с официального сайта или подключить по ссылке Google http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js
- jQueryUI CSS Framework (проще говоря тема для jQueryUI) – выбирайте и скачивате на официальном сайте
- jqGrid Plugin – скачивайте с официального сайта. ВАЖНО! Выберите все модули, т.к. мы пока разбираемся и будем тестировать все возможности jqGrid! В дальнейшей работе, вы можете выбирать только те модули которые вам необходимы.
II. Документ, в котором будет использоваться jqGrid
Аннотация:
- Весь материал, который начинается с этого момента я буду осваивать заново, поэтому все ответы на вопросы я буду искать вмести с вами.
- Мы будем работать с кириллицей в кодировке UTF-8. Но я дам некоторые рекомендации при использовании плагина с кодировкой Windows-1251(CP1251) .
1) Html – разметка
Итак создадим документ с разметкой следующего вида:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Осваиваем jqGrid с Linkexchanger</title></head> <body> <table id="le_table"></table> <div id="le_tablePager"></div> </body> </html>
Как видите самый незаурядный код чистой страницы, где <table id=»le_table»></table> это и есть таблица которую вы видели на демо, а <div id=»le_tablePager»></div> – это элемент таблицы, «статус бар» (status bar), о нем поговорим позже. Здесь следует сказать, что в качестве селектора таблицы лучше использовать именно атрибут ID, почему? Ответ на этот вопрос будет дан по мере изучения плагина.
2) Html + CSS + JS
Далее переходим к подключаем необходимые стили и скрипты. Для начала создадим на сервере, в рабочем каталоге следующую структуру.
- css/ – в этом каталоге будут все *.css файлы и прочие файлы относящиеся к визуальному оформлению страницы.
- js/ – в этом каталоге будут все *.js файлы
Теперь по каждому каталогу подробнее:
- css – в него следует положить
- js – в него следует положить
Теперь следует перепроверить всю структуру каталога еще раз. Именно на этом этапе я допустил первую ошибку, упоминавшуюся во введении.
- /css/
- flick/
- images/
- …
- jquery-ui-1.7.2.custom.css
- ui.jqgrid.css
- flick/
- /js/
- i18n/
- grid.locale-ru.js
- …
- jquery-1.4.min.js
- jquery.jqGrid.min.js
- i18n/
Далее необходимо подключить всю эту кухню
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Осваиваем jqGrid с Linkexchanger</title> <link rel="stylesheet" type="text/css" media="screen" href="css/flick/jquery-ui-1.7.2.custom.css" /> <link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css" mce_href="css/ui.jqgrid.css" /> <style>html, body { margin: 0; padding: 0; font-size: 80%; } </style> <script type="text/javascript" src="js/jquery-1.4.min.js"></script> <script type="text/javascript" src="js/i18n/grid.locale-ru.js"></script> <script type="text/javascript" src="js/jquery.jqgrid.min.js"></script> </head> <body> <table id="le_table"></table> <div id="le_tablePager"></div> </body> </html>
Как видите в разметке есть еще дополнительный стиль. Этот стиль задает базовые параметры для отступов и самое главное размер шрифта! Если этого не сделать, то при использовании jQueryUI CSS Framework размер шрифта будет «не маленьким» и при этом различным в различных браузерах.
3) MySQL
Как бы мы не хотели, но в данной статье мы никак не сможем обойтись без базы данных. Поэтому я подготовил для вас дамп. Вы можете скачать его по этой ссылке или с моего домашнего сервера и экспортировать в любую БД (MySQL) например используя phpMyAdmin, у данного дампа есть один ньюанс. Аименно у некоторых названий городов «искаверкана» кодировка, т.е. проблема в дампе, но никак не в плагине!
В дампе сохранены 10тыс городов с кодами страны, региона, названием на англ., долготой, широтой, и nbit. Фактически это кусок одной таблицы БД распределения IP адресов в интернете. В принципе нам абсолютно не важно, что это будет за БД и для опытов подойдет и такая.
4) PHP
На данном этапе следует создать PHP скрипт, который будет возвращать таблице, запрашиваемую ею информацию. Вот пример такого скрипта для наших нужд
<?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("SELECT COUNT(*) AS count FROM cities"); $row = mysql_fetch_array($result,MYSQL_ASSOC); // Теперь эта переменная хранит кол-во записей в таблице $count = $row['count']; // Рассчитаем сколько всего страниц займут данные в БД if( $count > 0 && $limit > 0) { $total_pages = ceil($count/$limit); } else { $total_pages = 0; } // Если по каким-то причинам клиент запросил if ($page > $total_pages) $page=$total_pages; // Рассчитываем стартовое значение для LIMIT запроса $start = $limit*$page - $limit; // Зашита от отрицательного значения if($start < 0) $start = 0; // Запрос выборки данных $query = "SELECT id, country_code, region_code, city, latitude, longitude, nbip FROM cities ORDER BY ".$sidx." ".$sord." LIMIT ".$start.", ".$limit; $result = mysql_query($query); // Начало xml разметки $s = "<?xml version='1.0' encoding='utf-8'?>"; $s .= "<rows>"; $s .= "<page>".$page."</page>"; $s .= "<total>".$total_pages."</total>"; $s .= "<records>".$count."</records>"; // Строки данных для таблицы // Не забудьте обернуть //текстовые данные в <![CDATA[]]> while($row = mysql_fetch_assoc($result)) { $s .= "<row id='". $row[id]."'>"; $s .= "<cell><![CDATA[". $row[country_code]."]]></cell>"; $s .= "<cell>". $row[region_code]."</cell>"; $s .= "<cell><![CDATA[". $row[city]."]]></cell>"; $s .= "<cell>". $row[latitude]."</cell>"; $s .= "<cell>". $row[longitude]."</cell>"; $s .= "<cell>". $row[nbip]."</cell>"; $s .= "</row>"; } $s .= "</rows>"; // Перед выводом не забывайте выставить header // с типом контента и кодировкой header("Content-type: text/xml;charset=utf-8"); echo $s; ?>
5) Инициализация плагина
Последний этап подготовительных работ. Здесь мы должны инициализировать плагин JqGrid. Делается это вызовом метода jqGrid(), который в качестве параметра, принимает объект со свойствами таблицы.
Теперь давайте посмотрим на примере разметки, приведенной выше.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Осваиваем jqGrid с Linkexchanger</title> <link rel="stylesheet" type="text/css" media="screen" href="css/flick/jquery-ui-1.7.2.custom.css" /> <link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css" mce_href="css/ui.jqgrid.css" /> <style>html, body { margin: 0; padding: 0; font-size: 80%; } </style> <script type="text/javascript" src="js/jquery-1.4.min.js"></script> <script type="text/javascript" src="js/i18n/grid.locale-ru.js"></script> <script type="text/javascript" src="js/jquery.jqgrid.min.js"></script> <script type="text/javascript"> $(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' }); }); </script> </head> <body> <table id="le_table></table> <div id="le_tablePager"></div> </body> </html>
Cейчас можно взглянуть результаты наших трудов. Вот ссылка на просмотр ДЕМО1 и на архив с ДЕМО1 (тот же архив на зеркале)
III. Разбор параметров
Остался последний пункт сегодняшней статьи в котором я дам пояснения по каждому из используемых в данном примере свойств плагина.
- url – этот параметр указывает URL на скрипт
- datatype – тип возвращаемых сервером данных. В данном примере, плагин ожидает данные с сервера в виде XML. Забегая наперед скажу что в следующей статье мы рассмотрим ответ сервера в виде JSON и Offline варианты использования плагина.
- mtype – определяет каким методом будут переданы данные серверу
- colNames – массив с заголовками столбцов таблицы
- colModel – параметр-массив, каждый элемент которого является объектом свойств столбца с данными
- name – «имя колонки», используется внутренними механизмами jqGrid
- index – «имя колонки», передается серверу при запросах данных
- width – ширина столбца в пикселах
- pager – определяет элемент, который будет преобразован в «панель-листалку». Может быть как строкой (‘#le_tablePager’) так и объектом jQuery ($(‘#le_tablePager’)). При этом сами разработчики рекомендуют присваивать этому параметру как раз объект jQuery.
- rowNum – определяет количество записей запрашиваемых у сервера и отображаемых за «один раз» (я написал именно так, потому что jqGrid может динамически подгружать строки с данными, что будет рассмотрено в последующих статьях) по умолчанию.
- rowList — параметр-массив. На основе этого параметра строится выпадающий список, позволяющий изменять кол-во записей выводимых за «один раз»
- sortname – определяет index(столбец) по которому будут отсортированы записи
- sortorder – определяет направление сортировки. asc – по возрастанию, desc – по убыванию.
Говоря о параметрах (options) следует сказать, что это лишь крохотная их часть. Эти параметры обеспечивают только базовую функциональность таблице. Множество других параметров мы с вами рассмотрим в последующих статьях, а пока поэкспериментируйте с теми что использованы в этом примере.
IV. Содержание следующей статьи
- Другие способы загрузки данных
- В виде JSON объекта
- В виде массива
- Конвертирование простой таблицы в jqGrid
- Форматирование данных
- Встроенные функции форматирования
- Пользовательские функции форматирования
- Дополнительные панели и панели инструментов
- Панель-листалка
- Панели инструментов
- Пользовательская панель
- Управление столбцами данных
Выводы
В данной статье мы познакомились с плагином jqGrid, запустили его в базовой функциональности и создали полигон для будущих примеров.
В ходе работы мы поняли принцип работы плагина. Фактически сам плагин это интерфейс пользователя, который отправляет AJAX запросы серверу и получает от него ответ. Таблица отправляет все необходимые параметры, для выборки данных на стороне сервера, в виде GET запроса, а сервер возвращает в виде набора строк в XML-разметке.
Пожалуйста оставляйте только конструктивные комментария и пожелания, а все вопросы задавайте на форуме!