Pull to refresh

Сажаем деревья с jqGrid

Reading time9 min
Views16K
Недавно впервые довелось «пощупать» такой плагин для jQuery как jqGrid. Многим этот плагин, думаю, знаком. Но в рунете не так много материалов по его использованию. Чтож… будем это исправлять!

Итак, jqGrid — довольно мощный плагин для создания различного рода таблиц в своих веб-приложениях. Он позволяет создавать не только обычные двумерные таблицы, но и таблицы с вложенными таблицами (нечто вроде экселевского pivot table), а также деревья (tree). Но обо всем по порядку и в данной статье рассмотрим основные свойства grid'ов и процесс «посадки деревьев».


Основные свойства


Вот полезные ссылки:
оффсайт разработчиков
Вики и документация
Довольно полная и полезная демка

Плагин имеет огромное количество параметров для почти полной кастомизации любого grid'а. Вот основные из них, которые понадобятся нам для примера.

url — свойство определяет источник, который предоставляет данные для наших таблиц и деревьев. Необходим во всех случаях кроме случая, когда элементы таблицы или дерева заранее созданы в виде хардкода прямо в скрипте. Думаю, таким вариантом вряд ли кто-то воспользуется)) Стандартно в нем указывается адрес серверной функции, возвращающей данные в одном из установленных форматов.

datatype — свойство как раз и указывает, в каком формате данные возвращаются с сервера. Имеет множество вариантов использования (это материал для отдельной статьи). Но чаще всего принимает значение «xml» или «json». Объяснять, для чего это, наверное излишне.

mType — определяет, каким методом GET или POST будут отправляться запросы на сервер. Возможные значения «GET»(по умолчанию) и «POST»

treeGrid — определяет, является ли наш грид таблицей или деревом (tree). true-дерево, false-по умолчанию

caption — заголовок таблицы

colNames — названия столбцов, выводимые непосредственно в интерфейсе. Массив строк. В каком порядке введете в массиве, в таком и будут столбцы проименованы.

ExpandColumn — (только при treeGrid: true) определяет имя столбца (colModel -> name, см. ниже) содержимое которого и будет отображаться в интерфейсе. Т.е. у нас в colModel могут быть определены несколько столбцов, но в дереве естественно будет отображаться только один, который мы определим.

ExpandColClick — (только при treeGrid: true). По умолчанию развернуть узел можно только нажав на треугольник слева от названия узла. Но, установив это свойство в true, это можно будет сделать нажатием по самой надписи. Очень удобно, всем советую использовать.

colModel — самый важный атрибут во всем плагине. Определяет свойства для каждого столбца. Перечислю самые необходимые для создания дерева:
name — имя, по которому можно получить доступ к конкретному столбцу или ячейке выбранной строки. Может и не совпадать с интерфейсным именем столбца.
key — логическое значение. Требуется в случае, если с сервера не возвращается id для строк вашей таблицы или дерева. Если установлено в true то атрибут id для строки примет значение этого поля.
hidden — логическое свойство, определяет отображается ли данный столбец или скрыт.
resizable — логическое свойство, определяет можно ли изменять ширину столбца
Далее отдельно расскажу про treeGridModel, знание и понимание которого необходимы для наиболее эффективного использования плагина.

Свойство treeGridModel


Дерево по определению предназначено для отображения информации, имеющей иерархическую структуру. Так вот это свойство как раз и определяет один из двух методов, которыми эта информация может быть предоставлена плагину.
Тут надо отметить, что существует еще одно свойство — treeReader, тесно связанное со свойством treeGridModel. TreeReader расширяет свойство colModel, т.е. автоматически добавляет дополнительные служебные столбцы в конец таблицы скрытыми. И данные, передаваемые с сервера, должны содержать информацию для этих столбцов. Так вот для каждого значения treeGridModel создается свой treeReader. Вообще определяемые формы представления данных описаны в теории баз данных и многим будут знакомы.
Рассмотрим каждое из значений treeGridModel в отдельности:

adjacency — позволяет использовать наиболее простую и понятную форму представления иерархических данных. Суть ее в том, что для каждой строки указывается уровень ее вложенности и идентификатор родительского элемента. Вот так выглядит treeReader:
treeReader = {<br>  level_field: "level", //уровень вложенности элемента, для корневого элемента обычно 0<br>  parent_id_field: "parent", //идентификатор родительского элемента, для корневого элемента null<br>  leaf_field: "isLeaf", //является ли элемент раскрываемым<br>  expanded_field: "expanded" //является ли элемент раскрытым сразу после загрузки данных<br>}<br><br>* This source code was highlighted with Source Code Highlighter.

Как видим, тут все довольно просто. Главное, эти данные правильно передать и все будет отлично работать.

nested — значение по умолчанию. Форма представления данных более сложная, но имеет ряд преимуществ по сравнению с adjacency при работе с деревьями, имеющими большой уровень вложенности. Суть ее в том, что для элемента указывается не родительский элемент, а указываются левый и правый ключи, которые определяют точку отсчета начала ветки и точку останова конца ветки соответственно.
treeReader : {<br>  level_field: "level",<br>  left_field:"lft", //левый ключ, определяет точку отсчета начала ветки<br>  right_field: "rgt", //правый ключ, определяет точку останова конца ветки<br>  leaf_field: "isLeaf",<br>  expanded_field: "expanded"<br>}<br><br>* This source code was highlighted with Source Code Highlighter.

Первое и два последних свойства аналогичны соответствующим свойствам для adjacency treeGridModel.
Для более подробной информации советую обратиться к следующим ресурсам по nested set и adjacency list

ПРИМЕРЫ


Теперь на конкретных примерах рассмотрим работу плагина. Допустим, что мы большие любители автомобилей и нам необходимо создать некое дерево, содержащее марки авто и разные модели для одной марки. В общем, хотим получить что-то такое
Пример создания дерева (tree) с jqGrid

  • 1) Нам необходимо вставить следующую html-разметку
    <div style="width:180px;"><br> <table id="treeGrid"><br> </table><br></div><br><br>* This source code was highlighted with Source Code Highlighter.

    div тут совсем необязателен, он лишь ограничивает ширину нашего грида. Главным элементом является пустой элемент table.
  • 2) Добавляем следующие jQuery-код, который и отвечает за создание нашего грида
    $('#treeGrid').jqGrid({
            url: "cars_tree.xml",
            datatype: "xml",
            height: "auto",
            mType: 'GET',       
            treeGridModel: 'adjacency',
            colNames: ["my_id", "my_name"],
            colModel: [ 
             { name: "id", width: 1, hidden: true, key:true },
             { name: "name" }
            ],
            treeGrid: true,
            caption: "Меню",
            ExpandColumn: "name",
            ExpandColClick:true,
            autowidth: true
          });


    * This source code was highlighted with Source Code Highlighter.

    Как мы видим, мы должны предоставить плагину данные в формате xml из файла cars_tree.xml, где древовидная структура представлена в виде adjacency list.
  • 3) Вот так выглядит наш xml-файл
    <rows><br> <row><br> <cell>0</cell><br> <cell>Авто</cell><br> <cell>0</cell><br> <cell></cell><br> <cell>false</cell><br> <cell>false</cell><br> </row><br> <row><br> <cell>1</cell><br> <cell>Honda</cell><br> <cell>1</cell><br> <cell>0</cell><br> <cell>false</cell><br> <cell>false</cell><br> </row><br> <row><br> <cell>2</cell><br> <cell>Civic</cell><br> <cell>2</cell><br> <cell>1</cell><br> <cell>true</cell><br> <cell>true</cell><br> </row><br> <row><br> <cell>3</cell><br> <cell>Cr-v</cell><br> <cell>2</cell><br> <cell>1</cell><br> <cell>true</cell><br> <cell>true</cell><br> </row><br> <row><br> <cell>4</cell><br> <cell>Hummer</cell><br> <cell>1</cell><br> <cell>0</cell><br> <cell>false</cell><br> <cell>false</cell><br> </row><br> <row><br> <cell>5</cell><br> <cell>H2</cell> <br> <cell>2</cell><br> <cell>4</cell><br> <cell>true</cell><br> <cell>true</cell><br> </row><br> <row> <br> <cell>6</cell><br> <cell>Lada</cell><br> <cell>1</cell><br> <cell>0</cell><br> <cell>true</cell><br> <cell>false</cell><br> </row><br></rows><br><br>* This source code was highlighted with Source Code Highlighter.


    Рассмотрим, что передается нашему гриду… В каждой строке первые две ячейки соответствуют двум столбцам, которые мы прописали в colModel, т.е. id и name. Остальные четыре соответствуют treeReader для treeColModel: 'adjacency', т.е. 3-я ячейка-уровень вложенности, 4-я ячейка — id родительского элемента, 5-я ячейка — раскрываема ли эта ячейка, 6-я — раскрыта ли она сразу после загрузки грида.
  • 4) Если же нам необходимо построить наше дерево на основе xml-данных, представленных в виде nested set, то нам нужно изменить лишь одну строчку кода в скрипте:
    treeGridModel: 'adjacency',<br><br>* This source code was highlighted with Source Code Highlighter.

    заменить на
    treeGridModel: 'nested',<br><br>* This source code was highlighted with Source Code Highlighter.

    или просто удалить, потому что nested для treeGridModel — значение по умолчанию.
    А xml-файл будет теперь иметь вид:
    <rows><br><row ><br><cell>0</cell><br><cell>Авто</cell><br><cell>0</cell><br><cell>1</cell><br><cell>14</cell><br><cell>false</cell><br><cell>false</cell><br></row><br><row><br><cell>1</cell><br><cell>Honda</cell><br><cell>1</cell><br><cell>2</cell><br><cell>7</cell><br><cell>false</cell><br><cell>false</cell><br></row><br><row><br><cell>2</cell><br><cell>Civic</cell><br><cell>2</cell><br><cell>3</cell><br><cell>4</cell><br><cell>true</cell><br><cell>true</cell><br></row><br><row ><br><cell>3</cell><br><cell>Cr-v</cell><br><cell>2</cell><br><cell>5</cell><br><cell>6</cell><br><cell>true</cell><br><cell>true</cell><br></row><br><row><br><cell>4</cell><br><cell>Hummer</cell><br><cell>1</cell><br><cell>8</cell><br><cell>11</cell><br><cell>false</cell><br><cell>false</cell><br></row><br><row ><br><cell>5</cell><br><cell>H2</cell><br><cell>2</cell><br><cell>9</cell><br><cell>10</cell><br><cell>true</cell><br><cell>true</cell><br></row><br><row><br><cell>6</cell><br><cell>Lada</cell><br><cell>1</cell><br><cell>12</cell><br><cell>13</cell><br><cell>true</cell><br><cell>false</cell><br></row><br></rows><br><br>* This source code was highlighted with Source Code Highlighter.


    Как видно, количество ячеек в каждой строке увеличилось на одну. Это из-за изменения treeReader.
    Первые две ячейки в строке — то же самое, что и было — значения для colModel. 3-я ячейка — уровень вложенности, 4-я и 5-я — определяют начало и конец ветки(повторюсь, что почитать дополнительно про это можно по выше указанным ссылкам), 6-я и 7-я — так же определяют, раскрываем ли узел и раскрыт ли на момент загрузки дерева.


Заключение


В данной статье мы рассмотрели вариант простейшего использования плагина jqGrid для создания представления иерархической структуры данных в виде дерева. Это один из многих вариантов использования плагина. В следующих публикациях продолжу описание этого мощного инструмента для создания веб-таблиц.
Tags:
Hubs:
+36
Comments26

Articles