Here’s some experience with jqGrid – a jQuery plugin. It’s well-known, but there is still little information on using it. Let’s fix that!
jqGrid is a powerful plugin for creating different kinds of tables in web applications. Not only does it let one create two-dimensional tables, but also provides for nested tables (something like MS Excel’s ® “pivot tables”) and trees. So let’s look at these two methods.
Basic features
It is recommended to take a look at the project’s web site, wiki and documentation, and the pretty demo.
The plugin has a wealth of parameters for a nearly full customization of any grid. Here are the basics, the parameters that will be used in the example.
url – this attribute defines the source of data for our tables and trees. It is needed in all cases except for when the elements have been pre-created and hard-coded in the script itself (not likely to happen). Usually this attribute is assigned a server function address that returns data in one of the pre-defined formats.
datatype – this attribute defines the format of the data being returned from the server. The attribute has many different applications (enough to write another article). The most common value for this attribute is «xml» or «json» for obvious reasons.
mType – defines whether GET or POST will be used to send requests to the server. The default value is POST.
treeGrid – defines if the grid is a table or a tree. The default is false, true – means the the table is a tree.
caption – table heading
colNames – names of the columns, that are entered in the interface. This is an array of strings. Whichever order is used will be the order of column names.
ExpandColumn – (only with treeGrid: true) defines the name of the column (colModel → name, see below) the contents of which will be shown in the interface. A colModel can have several columns defined, but only one will be shown in a tree.
ExpandColClick – (only with treeGrid: true). By default, a branch can be expanded by clicking the triangle to the left of the name. Setting this attribute to true will make the branch expandable by clicking it’s name. Very convenient, highly recommended.
colModel – the plugin’s main attribute. It defines the values for every column. Here are main ones used to create a tree:
name – the name used for accessing any specific column or a cell in a selected row. This may not match the name of the column in the interface
key – binary attribute, required if the server does not return the line id for the table or the tree. When true, the line’s id attribute will take the value of this field.
hidden – binary attribute, defines whether the width of the column is hidden
resizable – binary attribute, defines whether the column width can be changed
treeGridModel – this element is of utmost importance for the effective use of the plugin, and needs to be discussed in further detail
treeGridModel
A tree by definition is used for displaying categorized information. It is treeGridModel that defines one of the two ways to supply information to the plugin.
Here it should be noted that there is another attribute – treeReader, that is closely related to treeGridModel. treeReader expands the colModel attribute by auto-adding additional hidden service columns to the end of the table. The data sent from the server must contain information to be placed in these columns. Thus every treeGridModel requires its own treeReader. Definable forms of data presentation are described in database theory and should be familiar to most readers.
Here are the values of treeGridModel:
adjacency – provides for the simplest and easiest to understand form of categorized data presentation. Every line has a level and the parent’s identifier assigned to it. Here’s what treeReader looks like:
treeReader = {
level_field: "level", //nesting level for the root element it is usually 0
parent_id_field: "parent", //parent element's identificator, null for the root element
leaf_field: "isLeaf", //is the element expandable
expanded_field: "expanded" //is the element expanded by default
}
The usage is pretty basic. As long as the data is transferred correctly – everything will work fine.
nested – the default value. This presentation form is more complicated but has a series of advantages compared to adjacency for complex trees. The key concept here is use of left and right keys instead of the parent’s identifier. The keys define the beginning of the branch and the end.
treeReader : {
level_field: "level",
left_field:"lft", //the left key, defines the starting point of a branch
right_field: "rgt", //the right key, defines the ending of a branch
leaf_field: "isLeaf",
expanded_field: "expanded"
}
The bottom two attributes are the same as in adjacency treeGridMode. More info can be found on both nested set and adjacency list.
Example
Now lets apply the theory above. Let’s create a tree of car makes and models for car lovers.
We want something like this:
-
-
Insert the HTML layout
<divstyle="width:180px;">
<tableid="treeGrid">
</table>
</div>here is only here to define the width of our grid. The main element is the empty table.
div -
Add this jQuery code to create our grid
$('#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:"Menu",
ExpandColumn:"name",
ExpandColClick:true,
autowidth:true
});
The plugin will then require xml data from cars_tree.xml where the tree structure is an adjacency list. -
Here’s what our xml file will look like:
<rows>
<row>
<cell>0</cell>
<cell>Car</cell>
<cell>0</cell>
<cell></cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>1</cell>
<cell>Honda</cell>
<cell>1</cell>
<cell>0</cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>2</cell>
<cell>Civic</cell>
<cell>2</cell>
<cell>1</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>3</cell>
<cell>Cr-v</cell>
<cell>2</cell>
<cell>1</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>4</cell>
<cell>Hummer</cell>
<cell>1</cell>
<cell>0</cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>5</cell>
<cell>H2</cell>
<cell>2</cell>
<cell>4</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>6</cell>
<cell>Ford</cell>
<cell>1</cell>
<cell>0</cell>
<cell>true</cell>
<cell>false</cell>
</row>
</rows>
Let’s look at what is being sent to our grid. Every line’s first two cells correspond to the two columns that we’ve defined in colModel – the id and the name. The other four correspond to the treeReader for treeColModel: ‘adjacency’, nesting level (3rd cell), parent’s id (4th cell), whether the cell is expandable (5th cell), whether the cell is expanded by default at grid loading (6th cell). -
If we need to build our tree based on xml data in the nested set form, all we need to do is change one line of the scipt:
treeGridModel:'adjacency',changes to
treeGridModel:'nested',treeGridModel attribute can simply be removed because it is nested by default.
Here’s what the xml file will look like:
<rows>
<row>
<cell>0</cell>
<cell>Авто</cell>
<cell>0</cell>
<cell>1</cell>
<cell>14</cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>1</cell>
<cell>Honda</cell>
<cell>1</cell>
<cell>2</cell>
<cell>7</cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>2</cell>
<cell>Civic</cell>
<cell>2</cell>
<cell>3</cell>
<cell>4</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>3</cell>
<cell>Cr-v</cell>
<cell>2</cell>
<cell>5</cell>
<cell>6</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>4</cell>
<cell>Hummer</cell>
<cell>1</cell>
<cell>8</cell>
<cell>11</cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>5</cell>
<cell>H2</cell>
<cell>2</cell>
<cell>9</cell>
<cell>10</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>6</cell>
<cell>Ford</cell>
<cell>1</cell>
<cell>12</cell>
<cell>13</cell>
<cell>true</cell>
<cell>false</cell>
</row>
</rows>Notice that the number of cells in every row has increased by one. That is because treeReader has changed. The first two cells remain the same – values for the colModel. The 3rd cell is the level of nesting, the 4th and the 5th define the beginning and the end of the branch (once again, follow the links above for extra information). The 6th and the 7th cells define whether the branch is expandable and whether it is expanded by default.
Conclusion
The article attempts to show the most basic use of jqGrid plugin for jQuery in presenting categorized data in a tree. There are many other ways to utilize jqGrid, in further writings we will continue elaborating on the use of this powerful data presentation tool.
-
-
Here’s what our xml file will look like:
<rows>
<row>
<cell>0</cell>
<cell>Car</cell>
<cell>0</cell>
<cell></cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>1</cell>
<cell>Honda</cell>
<cell>1</cell>
<cell>0</cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>2</cell>
<cell>Civic</cell>
<cell>2</cell>
<cell>1</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>3</cell>
<cell>Cr-v</cell>
<cell>2</cell>
<cell>1</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>4</cell>
<cell>Hummer</cell>
<cell>1</cell>
<cell>0</cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>5</cell>
<cell>H2</cell>
<cell>2</cell>
<cell>4</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>6</cell>
<cell>Ford</cell>
<cell>1</cell>
<cell>0</cell>
<cell>true</cell>
<cell>false</cell>
</row>
</rows>
Let’s look at what is being sent to our grid. Every line’s first two cells correspond to the two columns that we’ve defined in colModel – the id and the name. The other four correspond to the treeReader for treeColModel: ‘adjacency’, nesting level (3rd cell), parent’s id (4th cell), whether the cell is expandable (5th cell), whether the cell is expanded by default at grid loading (6th cell). -
If we need to build our tree based on xml data in the nested set form, all we need to do is change one line of the scipt:
treeGridModel:'adjacency',changes to
treeGridModel:'nested',treeGridModel attribute can simply be removed because it is nested by default.
Here’s what the xml file will look like:
<rows>
<row>
<cell>0</cell>
<cell>Авто</cell>
<cell>0</cell>
<cell>1</cell>
<cell>14</cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>1</cell>
<cell>Honda</cell>
<cell>1</cell>
<cell>2</cell>
<cell>7</cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>2</cell>
<cell>Civic</cell>
<cell>2</cell>
<cell>3</cell>
<cell>4</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>3</cell>
<cell>Cr-v</cell>
<cell>2</cell>
<cell>5</cell>
<cell>6</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>4</cell>
<cell>Hummer</cell>
<cell>1</cell>
<cell>8</cell>
<cell>11</cell>
<cell>false</cell>
<cell>false</cell>
</row>
<row>
<cell>5</cell>
<cell>H2</cell>
<cell>2</cell>
<cell>9</cell>
<cell>10</cell>
<cell>true</cell>
<cell>true</cell>
</row>
<row>
<cell>6</cell>
<cell>Ford</cell>
<cell>1</cell>
<cell>12</cell>
<cell>13</cell>
<cell>true</cell>
<cell>false</cell>
</row>
</rows>Notice that the number of cells in every row has increased by one. That is because treeReader has changed. The first two cells remain the same – values for the colModel. The 3rd cell is the level of nesting, the 4th and the 5th define the beginning and the end of the branch (once again, follow the links above for extra information). The 6th and the 7th cells define whether the branch is expandable and whether it is expanded by default.
Conclusion
The article attempts to show the most basic use of jqGrid plugin for jQuery in presenting categorized data in a tree. There are many other ways to utilize jqGrid, in further writings we will continue elaborating on the use of this powerful data presentation tool.
