jqGrid Часть I: Знакомство

– Не робейте -, сказала Черная Королева, – это всего-навсего баранья нога, ни больше ни меньше.
Она вам понравится, уверяю вас.
Познакомьтесь. Алиса, это Баранья Нога.
Баранья Нога, это Алиса.

Предисловие

Весь цикл статей направлен в первую очередь на начинающих разработчиков, которые постигают все прелести 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 – в него следует положить
      1. js – в него следует положить

            Теперь следует перепроверить всю структуру каталога еще раз. Именно на этом этапе я допустил первую ошибку, упоминавшуюся во введении.

            • /css/
              • flick/
                • images/
                • jquery-ui-1.7.2.custom.css
              • ui.jqgrid.css
            • /js/
              • i18n/
                • grid.locale-ru.js
              • jquery-1.4.min.js
              • jquery.jqGrid.min.js

            Далее необходимо подключить всю эту кухню

            <!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-разметке.

            Пожалуйста оставляйте только конструктивные комментария и пожелания, а все вопросы задавайте на форуме!