4 * jqGrid extension - Tree Grid
\r
5 * Tony Tomov tony@trirand.com
\r
6 * http://trirand.com/blog/
\r
7 * Dual licensed under the MIT and GPL licenses:
\r
8 * http://www.opensource.org/licenses/mit-license.php
\r
9 * http://www.gnu.org/licenses/gpl.html
\r
12 setTreeNode : function(rd, row){
\r
13 return this.each(function(){
\r
15 if(!$t.grid || !$t.p.treeGrid) { return; }
\r
17 if(!$t.p.expColInd) {
\r
18 for (var key in $t.p.colModel){
\r
19 if($t.p.colModel[key].name == $t.p.ExpandColumn) {
\r
21 $t.p.expColInd = expCol;
\r
26 if(!$t.p.expColInd ) {$t.p.expColInd = expCol;}
\r
28 expCol = $t.p.expColInd;
\r
30 var level = $t.p.treeReader.level_field;
\r
31 var expanded = $t.p.treeReader.expanded_field;
\r
32 var isLeaf = $t.p.treeReader.leaf_field;
\r
33 row.lft = rd[$t.p.treeReader.left_field];
\r
34 row.rgt = rd[$t.p.treeReader.right_field];
\r
35 row.level = rd[level];
\r
38 rd[isLeaf] = (parseInt(row.rgt,10) === parseInt(row.lft,10)+1) ? 'true' : 'false';
\r
40 var curExpand = (rd[expanded] && rd[expanded] == "true") ? true : false;
\r
41 var curLevel = parseInt(row.level,10);
\r
43 if($t.p.tree_root_level === 0) {
\r
48 lftpos = curLevel -1;
\r
50 var twrap = document.createElement("div");
\r
51 $(twrap).addClass("tree-wrap").width(ident*18);
\r
52 var treeimg = document.createElement("div");
\r
53 $(treeimg).css("left",lftpos*18);
\r
54 twrap.appendChild(treeimg);
\r
56 if(rd[isLeaf] == "true") {
\r
57 $(treeimg).addClass("tree-leaf");
\r
60 if(rd[expanded] == "true") {
\r
61 $(treeimg).addClass("tree-minus treeclick");
\r
62 row.expanded = true;
\r
64 $(treeimg).addClass("tree-plus treeclick");
\r
65 row.expanded = false;
\r
68 if(parseInt(rd[level],10) !== parseInt($t.p.tree_root_level,10)) {
\r
69 if(!$($t).isVisibleNode(row)){
\r
70 $(row).css("display","none");
\r
73 var mhtm = $("td:eq("+expCol+")",row).html();
\r
74 var thecell = $("td:eq("+expCol+")",row).html("<span>"+mhtm+"</span>").prepend(twrap);
\r
75 $(".treeclick",thecell).click(function(e){
\r
76 var target = e.target || e.srcElement;
\r
77 var ind =$(target,$t.rows).parents("tr:first")[0].rowIndex;
\r
78 if(!$t.rows[ind].isLeaf){
\r
79 if($t.rows[ind].expanded){
\r
80 $($t).collapseRow($t.rows[ind]);
\r
81 $($t).collapseNode($t.rows[ind]);
\r
83 $($t).expandRow($t.rows[ind]);
\r
84 $($t).expandNode($t.rows[ind]);
\r
87 e.stopPropagation();
\r
91 expandRow: function (record){
\r
92 this.each(function(){
\r
94 if(!$t.grid || !$t.p.treeGrid) { return; }
\r
95 var childern = $($t).getNodeChildren(record);
\r
96 //if ($($t).isVisibleNode(record)) {
\r
97 $(childern).each(function(i){
\r
98 $(this).css("display","");
\r
100 $($t).expandRow(this);
\r
106 collapseRow : function (record) {
\r
107 this.each(function(){
\r
109 if(!$t.grid || !$t.p.treeGrid) { return; }
\r
110 var childern = $($t).getNodeChildren(record);
\r
111 $(childern).each(function(i){
\r
112 $(this).css("display","none");
\r
113 $($t).collapseRow(this);
\r
118 getRootNodes : function() {
\r
120 this.each(function(){
\r
122 if(!$t.grid || !$t.p.treeGrid) { return; }
\r
123 $($t.rows).each(function(i){
\r
124 if(parseInt(this.level,10) === parseInt($t.p.tree_root_level,10)) {
\r
131 getNodeDepth : function(rc) {
\r
133 this.each(function(){
\r
134 if(!this.grid || !this.p.treeGrid) { return; }
\r
135 ret = parseInt(rc.level,10) - parseInt(this.p.tree_root_level,10);
\r
139 getNodeParent : function(rc) {
\r
141 this.each(function(){
\r
142 if(!this.grid || !this.p.treeGrid) { return; }
\r
143 var lft = parseInt(rc.lft,10), rgt = parseInt(rc.rgt,10), level = parseInt(rc.level,10);
\r
144 $(this.rows).each(function(){
\r
145 if(parseInt(this.level,10) === level-1 && parseInt(this.lft) < lft && parseInt(this.rgt) > rgt) {
\r
153 getNodeChildren : function(rc) {
\r
155 this.each(function(){
\r
156 if(!this.grid || !this.p.treeGrid) { return; }
\r
157 var lft = parseInt(rc.lft,10), rgt = parseInt(rc.rgt,10), level = parseInt(rc.level,10);
\r
158 var ind = rc.rowIndex;
\r
159 $(this.rows).slice(1).each(function(i){
\r
160 if(parseInt(this.level,10) === level+1 && parseInt(this.lft,10) > lft && parseInt(this.rgt,10) < rgt) {
\r
168 getNodeAncestors : function(rc) {
\r
169 var ancestors = [];
\r
170 this.each(function(){
\r
171 if(!this.grid || !this.p.treeGrid) { return; }
\r
172 var parent = $(this).getNodeParent(rc);
\r
174 ancestors.push(parent);
\r
175 parent = $(this).getNodeParent(parent);
\r
180 isVisibleNode : function(rc) {
\r
182 this.each(function(){
\r
184 if(!$t.grid || !$t.p.treeGrid) { return; }
\r
185 var ancestors = $($t).getNodeAncestors(rc);
\r
186 $(ancestors).each(function(){
\r
187 result = result && this.expanded;
\r
188 if(!result) {return false;}
\r
193 isNodeLoaded : function(rc) {
\r
195 this.each(function(){
\r
197 if(!$t.grid || !$t.p.treeGrid) { return; }
\r
198 if(rc.loaded !== undefined) {
\r
199 result = rc.loaded;
\r
200 } else if( rc.isLeaf || $($t).getNodeChildren(rc).length > 0){
\r
208 expandNode : function(rc) {
\r
209 return this.each(function(){
\r
210 if(!this.grid || !this.p.treeGrid) { return; }
\r
212 if( $(this).isNodeLoaded(rc) ) {
\r
213 rc.expanded = true;
\r
214 $("div.treeclick",rc).removeClass("tree-plus").addClass("tree-minus");
\r
216 rc.expanded = true;
\r
217 $("div.treeclick",rc).removeClass("tree-plus").addClass("tree-minus");
\r
218 this.p.treeANode = rc.rowIndex;
\r
219 this.p.datatype = this.p.treedatatype;
\r
220 $(this).setGridParam({postData:{nodeid:rc.id,n_left:rc.lft,n_right:rc.rgt,n_level:rc.level}});
\r
221 $(this).trigger("reloadGrid");
\r
222 this.treeANode = 0;
\r
223 $(this).setGridParam({postData:{nodeid:'',n_left:'',n_right:'',n_level:''}})
\r
228 collapseNode : function(rc) {
\r
229 return this.each(function(){
\r
230 if(!this.grid || !this.p.treeGrid) { return; }
\r
232 rc.expanded = false;
\r
233 $("div.treeclick",rc).removeClass("tree-minus").addClass("tree-plus");
\r
237 SortTree : function( newDir) {
\r
238 return this.each(function(){
\r
239 if(!this.grid || !this.p.treeGrid) { return; }
\r
242 roots = $(this).getRootNodes();
\r
244 roots.sort(function(a, b) {
\r
245 if (a.sortKey < b.sortKey) {return -newDir;}
\r
246 if (a.sortKey > b.sortKey) {return newDir;}
\r
249 // Sorting children
\r
250 for (i = 0, len = roots.length; i < len; i++) {
\r
253 $(this).collectChildrenSortTree(records, rec, newDir);
\r
256 $.each(records, function(index, row) {
\r
257 $('tbody',$t.grid.bDiv).append(row);
\r
258 row.sortKey = null;
\r
262 collectChildrenSortTree : function(records, rec, newDir) {
\r
263 return this.each(function(){
\r
264 if(!this.grid || !this.p.treeGrid) { return; }
\r
267 children = $(this).getNodeChildren(rec);
\r
268 children.sort(function(a, b) {
\r
269 if (a.sortKey < b.sortKey) {return -newDir;}
\r
270 if (a.sortKey > b.sortKey) {return newDir;}
\r
273 for (i = 0, len = children.length; i < len; i++) {
\r
274 child = children[i];
\r
275 records.push(child);
\r
276 $(this).collectChildrenSortTree(records, child,newDir);
\r
281 setTreeRow : function(rowid, data) {
\r
282 var nm, success=false;
\r
283 this.each(function(){
\r
285 if(!t.grid || !t.p.treeGrid) { return false; }
\r
287 var ind = $(t).getInd(t.rows,rowid);
\r
288 if(!ind) {return success;}
\r
290 $(this.p.colModel).each(function(i){
\r
292 if(data[nm] !== 'undefined') {
\r
293 if(nm == t.p.ExpandColumn && t.p.treeGrid===true) {
\r
294 $("td:eq("+i+") > span:first",t.rows[ind]).html(data[nm]);
\r
296 $("td:eq("+i+")",t.rows[ind]).html(data[nm]);
\r
305 delTreeNode : function (rowid) {
\r
306 return this.each(function () {
\r
308 if(!$t.grid || !$t.p.treeGrid) { return; }
\r
309 var rc = $($t).getInd($t.rows,rowid,true);
\r
311 var dr = $($t).getNodeChildren(rc);
\r
313 for (var i=0;i<dr.length;i++){
\r
314 $($t).delRowData(dr[i].id);
\r
317 $($t).delRowData(rc.id);
\r