TreeGrid

Treegrid is a way to represent hierarchical data in grid.
Treegrid supports both the Nested Set model and the Adjacency model. Good articles describing the Nested Set model can be found here:

http://ftp.ntu.edu.tw/MySQL/tech-resources/articles/hierarchical-data.html
http://www.sitepoint.com/article/hierarchical-data-database

Installation

In order to use this module you should mark the Treegrid when you download the grid. For more information refer to Download.
For Developers - this is the grid.treegrid.js in the src directory.

Before you begin with the tree grid, it is highly recommended to read the articles listed above or any other related to hierarchical data representation articles.

Options

The following options can be set in the grid options to configure the treeGrid

OptionTypeDescriptionDefault
ExpandColClickbooleanwhen true, the tree is expanded and/or collapsed when we click on the text of the expanded column, not only on the imagetrue
ExpandColumnstringindicates which column (name from colModel) should be used to expand the tree grid. If not set the first one is used. Valid only when treeGrid option is set to true.null
treedatatypemixedDetermines the initial datatype (see datatype option). Usually this should not be changed. During the reading process this option is equal to the datatype option.null
treeGridbooleanEnables (disables) the tree grid format.false
treeGridModelstringDeteremines the method used for the treeGrid. Can be nested or adjacency.nested
treeIconsarrayThis array set the icons used in the tree. The icons should be a valid names from UI theme roller images. The default values are: {plus:'ui-icon-triangle-1-e',minus:'ui-icon-triangle-1-s',leaf:'ui-icon-radio-off'}
treeReaderarrayextends the colModel defined in the basic grid. The fields described here are added to end of the colModel array and are hidden. This means that the data returned from the server should have values for these fields. For a full description of all valid values see below.
tree_root_levelnumericDetermines the level where the root element begins when treeGrid is enabled0

If the gridview option in the grid is set to true the treeGrid will not be constructed instead that set to true.

The treeReader property adds dynamically columns to the colModel property of the basic grid when treeGrid property is set to true. Syntax:

treeReader : {
   property1 : value1
   ...
   propertyN : valueN
}

The treeReader property is adds diffrent columns in the colModel depending on the treeGridModel property - i.e. we have diffrent configurations for different models - Nested Set Model and Adjacency Model.

Currently jqGrid can work only with data returned from server. There are some tricks and articles wich describes how to work with local data.

It is important to note here that the data returned from the server should be sorted in an appropriate way; for example

SELECT category_name, level, lft, rgt FROM categories ORDER BY lft;

 Tree Grid

Methods

In the methods below, record means the current record, which can be obtained via the getInd method like this:

var record = jQuery("#grid_id").getInd(rowid,true);

NOTE: This no longer works as of version 3.7.x. Use var record = jQuery(”#grid_id”).getRowData(rowid); instead.

Where rowid is the id of the row. Note the second parameter in the method. If the second parameter is omited or set to false (default) the returned value is the index of the row. If the row can not be found a false is returned.

MethodParametersDescription
addChildNode nodeid, parentid, data Add a node in the tree according the value of the parentid parameter. The nodeid is the unique values in the row. If set to empty string the method gets the next max number + 1 from the data. if parendid is null the node is added as root. If the parentid is valid id of existing row the data is added as child of the that row. Data is a data to be inserted.
collapseNoderecordCollapse the node at specified record
collapseRowrecordCollapse the current row
delTreeNoderowidWhere rowid is the id of the row. Deletes the specified node and all child nodes of that node. Does not delete the node at server
expandNoderecordExpand the node at the specified record
expandRowrecordExpand the current row
getNodeAncestorsrecordreturns array of the ancestors of the specified record
getNodeDepthrecordreturns the depth of the specified record
getNodeParentrecordReturns the parent node of the specified record
getNodeChildrenrecordReturns array of child nodes of the specified record; returns empty array if none
getRootNodesnoneReturns an array of the current root nodes.
isNodeLoadedrecordReturns true if the node is already loaded
isVisibleNoderecordReturns true or false if the node is visible or not
setTreeRowrowid, data The same as setRowData
SortTreedirectionDirection is 1 (meaning ascending) or -1 (meaning descending); sorts the tree with the currently set sortname (sortname is from grid option)

Cautions and Limitations

  • Currently adding nodes with addRowData is not supported.
  • Currently it is not recommended to combine inline editing and form editing with treegrid, or the expanded column will not be editable.
  • Adding nodes is currently not supported.
  • Pager functionality currently disabled for treeGrid
  • When we initialize the grid and the data is read, the datatype is automatically set to local. This is required because treegrid supports autoloading tree nodes. This means that, for speed or efficiency, you can load the data only for the root level first and load the data for a particular child node only when the operator clicks to expand that node. The grid will determine that there is no data and try to load the node from the server, but in this case the data that is sent to the server has to have additional parameters. Setting datatype to local permits intervening before the request is made to build the request correctly. See the Nested Set Model and Adjacency Model on what is posted to the server

Discussion

Ken, 2009/09/17 18:46

The need for treedatatype?

Short Story: Should we remove treedatatype from the code? It appears to be a synonym for datatype.

Background: I recently had a bug in my code where I set treedatatype:'json', but forgot to set datatype (admitted jqGrid newbie mistake). The result was a treeGrid that failed to load initially, but successfully loaded after refresh. Digging into grid.base.js and grid.treegrid.js, I noticed that treedatatype is originally set to datatype, then datatype is later overwritten with treedatatype.

Should we remove treedatatype? …or is there another (or future) use for treedatatype that I am missing?

Thank you

Ye Chenhui, 2009/12/22 04:07

Is there any events support for treegrid just like 'onNodeExpanded' or 'onNodeCollapsed' ?

Thank you.

Tony Tomov, 2009/12/22 11:36

Hello, Currently no. The treeGrid component will be developed in the future with the ability not only for this, but to insert, add and delete tree nodes.

Tony

alnkapa, 2012/01/25 08:48

try this. $('#_my_grid').find ('.tree-wrap-ltr').find('.ui-icon-triangle-1-e').click(function (event) { to do list event.stopPropagation(); });

Shanmugam, 2010/09/28 12:21

Is there any update in this? Is it possible to addRowData with the any of current releases? I am not able to edit cell content as well in the tree grid. Any clue?

Thanks,

Shanmugam

Chris, 2010/09/30 07:14

Also looking for an update. Is it possible to insert and edit tree nodes?

Toby Newlin, 2010/10/14 19:46

The isNodeLoaded function does not appear to be returning the correct value for a node that has not been loaded yet. The debugger shows the value for rc[isLeaf] as 'false' and the number of node children is zero. The current implementation checks that rc[isLeaf] is defined, not that it has a particular value. So it seems the method will always return true (unless rc.loaded is defined, but I don't see that set anywhere in the tree grid code).

should the statement:

} else if ( rc[isLeaf] || $(t).jqGrid(“getNodeChildren”, rc).length > 0) {

instead be:

} else if ( (rc[isLeaf] == “true” || $($t).jqGrid(“getNodeChildren”, rc) > 0) {

Or maybe I am misunderstanding something…Thanks, Toby

pioto, 2010/12/15 18:25

Is there a reason that the multiselect and altRows settings get forcibly disabled? I can sorta get why altRows would be disabled (it probably would require doing a complete traversal of the table every time you open/close a node). But I can't understand why multiselect is disabled.

If nothing else, this should probably be documented, along with the other things that are forced off in this mode?

JinYoung Heo, 2011/01/27 09:32

When there is a child node that belongs to two or more parent nodes, treegrid doesn't work properly. In other words:

+ A (parent_group_id)

+ C  (child_group_id)
  + 1 (member_id)
  + 2 (member_id)
  + 3 (member_id)
+ D  (child_group_id)
+ E  (child_group_id)

+ B (parent_group_id)

+ C  (child_group_id)
  + 1 (member_id)
  + 2 (member_id)
  + 3 (member_id)
+ F  (child_group_id)
+ G  (child_group_id)

We didn't want to have duplicated group in our system. Therefore we made code to share common sub groups such as C. However, under this situation, treegrid seems to be malfunction. Is there any advice?

Paul Abrams, 2011/01/27 20:09

If you have a child node that belongs to two or more parent nodes, then you don't have a tree, you have a graph.

Nicolas, 2011/02/02 10:54

you can compose your id with a random number : id_random then split on server

Anant, 2011/07/04 10:40

HI, I want to display the folder structure of a drive of system. First I show all the drives available and than when user clicks on the Drive node, it will display folders inside it.

Is there a way I can pass the nodeid to the server where nodeid should be the folder/drive name what user clicked on?

piyush Goyal, 2011/07/27 17:29

Can we have pager enabled with treeGrid (by any hack or something).

teazos, 2011/08/11 20:27

How to extended all node when treegrid loading?

vva, 2011/08/28 09:28
  gridComplete: function(){
	    setTimeout(function(){	   
	       rootNode = $( "#youGridObject" ).jqGrid('getRowData')[0];
	       rootNode._id_ = rootNode.id;
	       $( "#youGridObject" ).jqGrid('expandRow'   ,rootNode);
	       $( "#youGridObject" ).jqGrid('expandNode'  ,rootNode);	
	       $( "#youGridObject" ).jqGrid('setSelection',rootNode.id);       
	    }, 10);

}
roshan, 2011/11/27 17:12

In your demo example of treeview, you have 'id' as a key column but if i change that column to any other column by adding colmodel as { name: 'id1', index: 'id1', width: 1, hidden: true, key: true } then it gives me error Cannot read property 'rowIndex' of undefined. In my application i want all nodes exapanded by default. for that i have added exapnded:true and loaded:true values in data.

alnkapa, 2012/01/25 16:22

It is possible that some way to get a list of open items in the tree?

josiane, 2012/03/02 13:12

how can i catch the parent_id when i am adding it is not post does anyone has an idea??

Mark Servais, 2012/06/01 23:30

We are currently having a difficult time trying to auto expand a jqGrid treegrid to the 3rd level of the tree so that all children are visible. The current data set is thousands or rows deep and we were forced to dynamically load each node when requested to be expanded, which requires reloading the grid. Expanded node ids are saved in an array as a saved tree state so that the nodes can be re-expanded when the tree is redisplayed. This goes through the process of loading each node from the database as the expansion happens. AS each node is dynamically loaded and expended gridComplete and loadComplete events are handled as expected.

We are trying to trigger the 3rd level expansion by utilizing the save tree state and the existing logic to break out the tree appropriately within the existing logic. The problem we are experiencing is that the tree cannot expand out fast enough in order to be processed, and we can never break the tree apart completely.

Here is the function to iterate through the parents to capture the appropriate ids to expand:

function ExpandGridLevel(level) { if (ExpandGridLevels == false) { ExpandTotalLevels = level; ExpandLevelCurrent = 0; ExpandGridLevels = true; } if (!TreeExpandState) { TreeExpandState = new Array(); } $(”.treeclick”, ”#Grid”).each(function () { if ($(this).hasClass(“tree-plus”)) { var id = $(this).parents(“tr”).attr(“id”); var rowLevel = $(”#MaGrid”).getLocalRow(id); if (rowLevel.level == ExpandLevelCurrent) { TreeExpandState.push(id); $(this).removeClass(“tree-plus”); $(this).addClass(“tree-minus”); } } }); $(this).trigger(“reloadGrid”); $(”#Grid”).jqGrid(“setGridParam”, { datatype: “local” }); ExpandLevelCurrent++; RefreshGrid(); }

Our gridComplete and loadComplete sections of code:

loadComplete: function (data) { $(”#Grid”).jqGrid(“setGridParam”, { datatype: “local” }); if (TreeExpandState.length == 0) { setTimeout(function () { ExpandGridLevel (ExpandTotalLevels); }, 3000); } }

gridComplete: function () { if (TreeExpandState) { var rowId = TreeExpandState.shift(); ExpandNode(rowId); } }

Is what we are trying to do possible with jqGrid? If so, how do we know when the tree expansion is truly complete and we can reiterate over the expended grid to begin the expansion of the next level of parents?

Leo Hinojosa, 2012/07/31 23:48

In case someone needs this, If you have a treegrid with checkboxes, but only need the last leaf to have the checkbox control, you can easily empty the parent cells by using the gridComplete function and the first td ( which has the IsLeaf column )

gridComplete:function(){

var r = $(this).find("tr td:first-child");
r.each(function (index, instance) {
          var _td = $(instance);
          if(_td.text()==='false') {
               _td.siblings().find('input').each(function (sindex, sinstance) {
               $(sinstance).parent().empty();
           });
     }
});

}

Kishor Mali, 2013/02/11 14:46

ExpandColumn not work with rownumbers:true


;