[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 /* Dynamic Folder Tree 2 * Generates DHTML tree dynamically (on the fly). 3 * License: GNU LGPL 4 * 5 * Copyright (c) 2004, Vinicius Cubas Brand, Raphael Derosso Pereira 6 * {viniciuscb,raphaelpereira} at users.sourceforge.net 7 * All rights reserved. 8 * 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25 // NODE 26 //Usage: a = new dNode({id:2, caption:'tree root', url:'http://www.w3.org'}); 27 function dNode(arrayProps) { 28 //mandatory fields 29 this.id; //node id 30 this.caption; //node caption 31 32 //optional fields 33 this.url; //url to open 34 this.target; //target to open url 35 this.onClick; //javascript to execute onclick 36 this.onOpen; //javascript to execute when a node of the tree opens 37 this.onClose; //javascript to execute when a node of the tree closes 38 this.onFirstOpen; //javascript to execute only on the first open 39 this.iconClosed; //img.src of closed icon 40 this.iconOpen; //img.src of open icon 41 this.runJS = true; //(bool) if true, runs the on* props defined above 42 this.plusSign = true; //(bool) if the plus sign will appear or not 43 this.captionClass = 'l'; //(string) the class for this node's caption 44 45 46 //The parameters below are private 47 this._opened = false; //already opened 48 this._io = false; //is opened 49 50 this._children = []; //references to children 51 this._parent; //pointer to parent 52 this._myTree; //pointer to myTree 53 this._drawn = false; 54 55 for (var i in arrayProps) 56 { 57 if (i.charAt(0) != '_') 58 { 59 eval('this.'+i+' = arrayProps[\''+i+'\'];'); 60 } 61 } 62 } 63 64 //changes node state from open to closed, and vice-versa 65 dNode.prototype.changeState = function() 66 { 67 if (this._io) 68 { 69 this.close(); 70 } 71 else 72 { 73 this.open(); 74 } 75 76 //cons = COokie of Node Status 77 //setCookie("cons"+this.id,this._io); 78 } 79 80 dNode.prototype.open = function () { 81 if (!this._io) 82 { 83 if (!this._opened && this.runJS && this.onFirstOpen != null) 84 { 85 eval(this.onFirstOpen); 86 } 87 else if (this.runJS && this.onOpen != null) 88 { 89 eval(this.onOpen); 90 } 91 92 this._debug = true; 93 this._opened = true; 94 this._io = true; 95 this._refresh(); 96 } 97 } 98 99 100 dNode.prototype.close = function() { 101 if (this._io) 102 { 103 if (this.runJS && this.onClose != null) 104 { 105 eval(this.onClose); 106 } 107 this._io = false; 108 this._refresh(); 109 } 110 } 111 112 //alter node label and other properties 113 dNode.prototype.alter = function(arrayProps) 114 { 115 for (var i in arrayProps) 116 { 117 if (i != 'id' && i.charAt(0) != '_') 118 { 119 eval('this.'+i+' = arrayProps[\''+i+'\'];'); 120 } 121 } 122 } 123 124 //css and dhtml refresh part 125 dNode.prototype._refresh = function() { 126 var nodeDiv = getObjectById("n"+this.id+this._myTree.name); 127 var plusSpan = getObjectById("p"+this.id+this._myTree.name); 128 var captionSpan = getObjectById("l"+this.id+this._myTree.name); 129 var childrenDiv = getObjectById("ch"+this.id+this._myTree.name); 130 131 if (nodeDiv != null) 132 { 133 //Handling open and close: checks this._io and changes class as needed 134 if (!this._io) //just closed 135 { 136 childrenDiv.className = "closed"; 137 } 138 else //just opened 139 { 140 //prevents IE undesired behaviour when displaying empty DIVs 141 /* if (this._children.length > 0) 142 {*/ 143 childrenDiv.className = "opened"; 144 // } 145 } 146 147 plusSpan.innerHTML = this._properPlus(); 148 149 captionSpan.innerHTML = this.caption; 150 } 151 152 //alter onLoad, etc 153 154 } 155 156 //gets the proper plus for this moment 157 dNode.prototype._properPlus = function() 158 { 159 if (!this._io) 160 { 161 if (this._myTree.useIcons) 162 { 163 return (this.plusSign)?imageHTML(this._myTree.icons.plus):""; 164 } 165 else 166 { 167 return (this.plusSign)?"+":""; 168 } 169 } 170 else 171 { 172 if (this._myTree.useIcons) 173 { 174 return (this.plusSign)?imageHTML(this._myTree.icons.minus):""; 175 } 176 else 177 { 178 return (this.plusSign)?"-":""; 179 } 180 } 181 } 182 183 //changes node to selected style class. Perform further actions. 184 dNode.prototype._select = function() 185 { 186 var captionSpan; 187 188 if (this._myTree._selected) 189 { 190 this._myTree._selected._unselect(); 191 } 192 this._myTree._selected = this; 193 194 captionSpan = getObjectById("l"+this.id+this._myTree.name); 195 196 //changes class to selected link 197 if (captionSpan) 198 { 199 captionSpan.className = 'sl'; 200 } 201 202 } 203 204 //changes node to unselected style class. Perform further actions. 205 dNode.prototype._unselect = function() 206 { 207 var captionSpan = getObjectById("l"+this.id+this._myTree.name); 208 209 this._myTree._lastSelected = this._myTree._selected; 210 this._myTree._selected = null; 211 212 //changes class to selected link 213 if (captionSpan) 214 { 215 captionSpan.className = this.captionClass; 216 } 217 } 218 219 220 //state can be open or closed 221 //warning: if drawed node is not child or root, bugs will happen 222 dNode.prototype._draw = function() 223 { 224 var str; 225 var _this = this; 226 var divN, divCH, spanP, spanL, parentChildrenDiv; 227 var myClass = (this._io)? "opened" : "closed"; 228 var myPlus = this._properPlus(); 229 var append = true; 230 var captionOnClickEvent = null; 231 // var cook; 232 233 var plusEventHandler = function(){ 234 _this.changeState(); 235 } 236 237 var captionEventHandler = function(){ 238 eval(captionOnClickEvent); 239 } 240 241 242 /* if (this.myTree.followCookies) 243 { 244 this._io = getCookie("cons"+this.id); 245 }*/ 246 247 //FIXME put this in a separate function, as this will be necessary in 248 //various parts 249 250 if (this.onClick) //FIXME when onclick && url 251 { 252 captionEventHandler = function () { _this._select(); typeof(_this.onClick) == 'function' ? _this.onClick() : eval(_this.onClick); }; 253 } 254 else if (this.url && this.target) 255 { 256 captionEventHandler = function () { _this._select(); window.open(_this.url,_this.target); }; 257 } 258 else if (this.url) 259 { 260 captionEventHandler = function () { _this._select(); window.location=_this.url; }; 261 } 262 263 264 //The div of this node 265 divN = document.createElement('div'); 266 divN.id = 'n'+this.id+this._myTree.name; 267 divN.className = 'son'; 268 // divN.style.border = '1px solid black'; 269 270 //The span that holds the plus/minus sign 271 spanP = document.createElement('span'); 272 spanP.id = 'p'+this.id+this._myTree.name; 273 spanP.className = 'plus'; 274 spanP.onclick = plusEventHandler; 275 spanP.innerHTML = myPlus; 276 // spanP.style.border = '1px solid green'; 277 278 //The span that holds the label/caption 279 spanL = document.createElement('span'); 280 spanL.id = 'l'+this.id+this._myTree.name; 281 spanL.className = this.captionClass; 282 spanL.onclick = captionEventHandler; 283 spanL.innerHTML = this.caption; 284 // spanL.style.border = '1px solid red'; 285 286 //The div that holds the children 287 divCH = document.createElement('div'); 288 divCH.id = 'ch'+this.id+this._myTree.name; 289 divCH.className = myClass; 290 // divCH.style.border = '1px solid blue'; 291 292 // div.innerHTML = str; 293 divN.appendChild(spanP); 294 divN.appendChild(spanL); 295 divN.appendChild(divCH); 296 297 298 if (this._parent != null) 299 { 300 parentChildrenDiv = getObjectById("ch"+this._parent.id+this._myTree.name); 301 } 302 else //is root 303 { 304 parentChildrenDiv = getObjectById("dftree_"+this._myTree.name); 305 } 306 307 if (parentChildrenDiv) 308 { 309 parentChildrenDiv.appendChild(divN); 310 } 311 } 312 313 // TREE 314 //Usage: t = new dFTree({name:t, caption:'tree root', url:'http://www.w3.org'}); 315 function dFTree(arrayProps) { 316 //mandatory fields 317 this.name; //the value of this must be the name of the object 318 319 //optional fields 320 this.is_dynamic = true; //tree is dynamic, i.e. updated on the fly 321 this.followCookies = true;//use previous state (o/c) of nodes 322 this.useIcons = false; //use icons or not 323 324 325 //arrayProps[icondir]: Icons Directory 326 iconPath = (arrayProps['icondir'] != null)? arrayProps['icondir'] : ''; 327 328 this.icons = { 329 root : iconPath+'/foldertree_base.gif', 330 folder : iconPath+'/foldertree_folder.gif', 331 folderOpen : iconPath+'/foldertree_folderopen.gif', 332 node : iconPath+'/foldertree_folder.gif', 333 empty : iconPath+'/foldertree_empty.gif', 334 line : iconPath+'/foldertree_line.gif', 335 join : iconPath+'/foldertree_join.gif', 336 joinBottom : iconPath+'/foldertree_joinbottom.gif', 337 plus : iconPath+'/foldertree_plus.gif', 338 plusBottom : iconPath+'/foldertree_plusbottom.gif', 339 minus : iconPath+'/foldertree_minus.gif', 340 minusBottom : iconPath+'/foldertree_minusbottom.gif', 341 nlPlus : iconPath+'/foldertree_nolines_plus.gif', 342 nlMinus : iconPath+'/foldertree_nolines_minus.gif' 343 }; 344 345 //private 346 this._root = false; //reference to root node 347 this._aNodes = []; 348 this._lastSelected; //The last selected node 349 this._selected; //The actual selected node 350 351 for (var i in arrayProps) 352 { 353 if (i.charAt(0) != '_') 354 { 355 eval('this.'+i+' = arrayProps[\''+i+'\'];'); 356 } 357 } 358 } 359 360 dFTree.prototype.draw = function(dest_element) { 361 var main_div; 362 363 if (!getObjectById("dftree_"+this.name) && dest_element) 364 { 365 main_div = document.createElement('div'); 366 main_div.id = 'dftree_'+this.name; 367 dest_element.appendChild(main_div); 368 this._drawn = true; 369 } 370 371 if (this._root != false) 372 { 373 this._root._draw(); 374 this._drawBranch(this._root._children); 375 } 376 377 } 378 379 //Transforms tree in HTML code 380 dFTree.prototype.toString = function() { 381 var str = ''; 382 383 if (!getObjectById("dftree_"+this.name)) 384 { 385 str = '<div id="dftree_'+this.name+'"></div>'; 386 } 387 return str; 388 389 /* if (this.root != false) 390 { 391 this.root._draw(); 392 this._drawBranch(this.root.children); 393 }*/ 394 } 395 396 //Recursive function, draws children 397 dFTree.prototype._drawBranch = function(childrenArray) { 398 var a=0; 399 for (a;a<childrenArray.length;a++) 400 { 401 childrenArray[a]._draw(); 402 this._drawBranch(childrenArray[a]._children); 403 } 404 } 405 406 //add into a position 407 dFTree.prototype.add = function(node,pid) { 408 var auxPos; 409 var addNode = false; 410 411 if (typeof (auxPos = this._searchNode(node.id)) != "number") 412 { 413 // if parent exists, add node as its child 414 if (typeof (auxPos = this._searchNode(pid)) == "number") 415 { 416 node._parent = this._aNodes[auxPos]; 417 this._aNodes[auxPos]._children[this._aNodes[auxPos]._children.length] = node; 418 addNode = true; 419 } 420 else //if parent cannot be found and there is a tree root, ignores node 421 { 422 if (!this._root) 423 { 424 this._root = node; 425 addNode = true; 426 } 427 } 428 if (addNode) 429 { 430 this._aNodes[this._aNodes.length] = node; 431 node._myTree = this; 432 if (this.is_dynamic && this._drawn) 433 { 434 node._draw(); 435 } 436 } 437 } 438 else { 439 var arrayProps = new Array(); 440 441 arrayProps['id'] = node.id; 442 arrayProps['caption'] = node.caption; 443 444 arrayProps['url'] = node.url; 445 arrayProps['target'] = node.target; 446 arrayProps['onClick'] = node.onClick; 447 arrayProps['onOpen'] = node.onOpen; 448 arrayProps['onClose'] = node.onClose; 449 arrayProps['onFirstOpen'] = node.onFirstOpen; 450 arrayProps['iconClosed'] = node.iconClosed; 451 arrayProps['iconOpen'] = node.iconOpen; 452 arrayProps['runJS'] = node.runJS; 453 arrayProps['plusSign'] = node.plusSign; 454 arrayProps['captionClass'] = node.captionClass; 455 456 delete node; 457 458 this.alter(arrayProps); 459 } 460 461 } 462 463 //arrayProps: same properties of Node 464 dFTree.prototype.alter = function(arrayProps) { 465 this.getNodeById(arrayProps['id']).alter(arrayProps); 466 } 467 468 dFTree.prototype.getNodeById = function(nodeid) { 469 return this._aNodes[this._searchNode(nodeid)]; 470 } 471 472 dFTree.prototype.openTo = function(nodeid) 473 { 474 var node = this.getNodeById(nodeid); 475 476 if (node && node._parent) 477 { 478 node._parent.open(); 479 this.openTo(node._parent.id); 480 } 481 } 482 483 //Searches for a node in the node array, returning the position of the array 4it 484 dFTree.prototype._searchNode = function(id) { 485 var a=0; 486 for (a;a<this._aNodes.length;a++) 487 { 488 if (this._aNodes[a].id == id) 489 { 490 return a; 491 } 492 } 493 return false; 494 } 495 496 497 //Auxiliar functions 498 499 //For multi-browser compatibility 500 function getObjectById(name) 501 { 502 if (document.getElementById) 503 { 504 return document.getElementById(name); 505 } 506 else if (document.all) 507 { 508 return document.all[name]; 509 } 510 else if (document.layers) 511 { 512 return document.layers[name]; 513 } 514 return false; 515 } 516 517 // [Cookie] Clears a cookie 518 function clearCookie(cookieName) { 519 var now = new Date(); 520 var yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24); 521 this.setCookie(cookieName, 'cookieValue', yesterday); 522 this.setCookie(cookieName, 'cookieValue', yesterday); 523 }; 524 525 // [Cookie] Sets value in a cookie 526 function setCookie(cookieName, cookieValue, expires, path, domain, secure) { 527 document.cookie = 528 escape(cookieName) + '=' + escape(cookieValue) 529 + (expires ? '; expires=' + expires.toGMTString() : '') 530 + (path ? '; path=' + path : '') 531 + (domain ? '; domain=' + domain : '') 532 + (secure ? '; secure' : ''); 533 }; 534 535 // [Cookie] Gets a value from a cookie 536 function getCookie(cookieName) { 537 var cookieValue = ''; 538 var posName = document.cookie.indexOf(escape(cookieName) + '='); 539 if (posName != -1) { 540 var posValue = posName + (escape(cookieName) + '=').length; 541 var endPos = document.cookie.indexOf(';', posValue); 542 if (endPos != -1) 543 { 544 cookieValue = unescape(document.cookie.substring(posValue, endPos)); 545 } 546 else 547 { 548 cookieValue = unescape(document.cookie.substring(posValue)); 549 } 550 } 551 return (cookieValue); 552 }; 553 554 555 function imageHTML(src,attributes) { 556 if (attributes != null) 557 { 558 attributes = ''; 559 } 560 return "<img "+attributes+" src=\""+src+"\">"; 561 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |