2 * Original Author of this file: Martin Mouritzen. (martin@nano.dk)
\r
5 * (Lack of) Documentation:
\r
8 * If a finishedLoading method exists, it will be called when the tree is loaded.
\r
9 * (good to display a div, etc.).
\r
12 * You have to set the variable rootNode (as a TreeNode).
\r
14 * You have to set a container element, this is the element in which the tree will be.
\r
18 * Save cookies better (only 1 cookie for each tree). Else the page will totally cookieclutter.
\r
20 ***********************************************************************
\r
21 * Configuration variables.
\r
22 ************************************************************************/
\r
24 // Should the rootNode be displayed.
\r
25 var showRootNode = true;
\r
27 // Should the dashed lines between nodes be shown.
\r
28 var showLines = true;
\r
30 // Should the nodes be sorted? (You can either specify a number, then it will be sorted by that, else it will
\r
31 // be sorted alphabetically (by name).
\r
32 var sortNodes = true;
\r
34 // This is IMPORTANT... use an unique id for each document you use the tree in. (else they'll get mixed up).
\r
35 var documentID = window.location.href;
\r
37 // being read from cookie.
\r
38 var nodesOpen = new Array();
\r
40 // RootNode of the tree.
\r
43 // Container to display the Tree in.
\r
46 // Shows/Hides subnodes on startup
\r
47 var showAllNodesOnStartup = false;
\r
49 // Is the roots dragable?
\r
50 var dragable = false;
\r
53 /************************************************************************
\r
54 * The following is just instancevariables.
\r
55 ************************************************************************/
\r
58 // rootNodeCallBack name (if null, it's not selectable).
\r
59 var rootNodeCallBack = null;
\r
62 var selectedNode = null;
\r
65 var statearray = new Array();
\r
67 var treeNodeEdited = null;
\r
69 var editaborted = false;
\r
71 var floatDragElement = null;
\r
72 var colouredElement = null;
\r
73 var draggedNodeID = null;
\r
74 var lastDraggedOnNodeID = null;
\r
78 * The TreeNode Object
\r
79 * @param id unique id of this treenode
\r
80 * @param name The title of this node
\r
81 * @param icon The icon if this node (Can also be an array with 2 elements, the first one will represent the closed state, and the next one the open state)
\r
82 * @param param A parameter, this can be pretty much anything. (eg. an array with information).
\r
83 * @param orderNumber an orderNumber If one is given the nodes will be sorted by this (else they'll be sorted alphabetically (If sorting is on).
\r
85 function TreeNode(id,name,icon,param,orderNumber) {
\r
87 this.childs = new Array();
\r
88 this.name = (name == null ? 'unset name' : name);
\r
89 this.icon = (icon == null ? '' : icon);
\r
91 this.handler = null;
\r
92 this.param = (param == null ? '' : param);
\r
93 this.orderNumber = (orderNumber == null ? -1 : orderNumber);
\r
95 this.openeventlisteners = new Array();
\r
96 this.editeventlisteners = new Array();
\r
97 this.moveeventlisteners = new Array();
\r
98 this.haschilds = false;
\r
99 this.editable = false;
\r
100 this.linestring = '';
\r
102 this.nextSibling = null;
\r
103 this.prevSibling = null;
\r
105 this.childsHasBeenFetched = false;
\r
107 this.getID = function() {
\r
110 this.setName = function(newname) {
\r
111 this.name = newname;
\r
113 this.getName = function() {
\r
116 this.getParam = function() {
\r
119 this.setIcon = function(icon) {
\r
122 this.getIcon = function() {
\r
123 if (typeof(this.icon) == 'object') {
\r
124 return this.icon[0];
\r
128 this.getOpenIcon = function() {
\r
129 if (typeof(this.icon) == 'object') {
\r
130 return this.icon[1];
\r
134 this.hasIcon = function () {
\r
135 return this.icon != '';
\r
137 this.getOrderNumber = function() {
\r
138 return this.orderNumber;
\r
140 this.addOpenEventListener = function(event) {
\r
141 this.openeventlisteners[this.openeventlisteners.length] = event;
\r
143 this.gotOpenEventListeners = function() {
\r
144 return (this.openeventlisteners.length > 0);
\r
146 this.addEditEventListener = function(event) {
\r
147 this.editeventlisteners[this.editeventlisteners.length] = event;
\r
149 this.gotEditEventListeners = function() {
\r
150 return (this.editeventlisteners.length > 0);
\r
152 this.addMoveEventListener = function(event) {
\r
153 this.moveeventlisteners[this.moveeventlisteners.length] = event;
\r
155 this.gotMoveEventListeners = function() {
\r
156 return (this.moveeventlisteners.length > 0);
\r
158 this.addChild = function(childNode) {
\r
159 var possiblePrevNode = this.childs[this.childs.length - 1]
\r
160 if (possiblePrevNode) {
\r
161 possiblePrevNode.nextSibling = childNode;
\r
162 childNode.prevSibling = possiblePrevNode;
\r
163 // alert(childNode.prevSibling);
\r
166 this.childs[this.childs.length] = childNode;
\r
167 childNode.setParent(this);
\r
170 function sortByOrder(a,b) {
\r
171 var order1 = a.getOrderNumber();
\r
172 var order2 = b.getOrderNumber();
\r
173 if (order1 == -1 || order2 == -1) {
\r
174 return a.getName().toLowerCase() > b.getName().toLowerCase() ? 1 : -1;
\r
177 if (order1 == order2) {
\r
178 // If they got the same order number, then we'll sort by their title.
\r
179 return a.getName().toLowerCase() > b.getName().toLowerCase() ? 1 : -1;
\r
182 return order1 - order2;
\r
186 this.childs.sort(sortByOrder);
\r
189 this.removeChild = function(childNode) {
\r
191 for (var i=0;i<this.childs.length;i++) {
\r
193 this.childs[i] = this.childs[i + 1];
\r
195 if (this.childs[i] == childNode) {
\r
196 if (i == (this.childs.length - 1)) {
\r
197 this.childs[i] = null;
\r
200 this.childs[i] = this.childs[i + 1];
\r
206 this.childs.length = this.childs.length-1;
\r
209 this.resetChilds = function() {
\r
210 this.childs = new Array();
\r
212 this.setHasChilds = function(hasChilds) {
\r
213 this.haschilds = hasChilds;
\r
215 this.hasChilds = function() {
\r
216 if (this.haschilds == true) {
\r
219 return (this.childs.length > 0);
\r
221 this.getChildCount = function() {
\r
222 return this.childs.length;
\r
224 this.getFirstChild = function() {
\r
225 if (this.hasChilds()) {
\r
226 return this.childs[0];
\r
230 this.gotHandler = function() {
\r
231 return this.handler != null;
\r
233 this.setHandler = function(handler) {
\r
234 this.handler = handler;
\r
236 this.getHandler = function() {
\r
237 return this.handler;
\r
239 this.setParent = function(parent) {
\r
240 this.parent = parent;
\r
242 this.getParent = function() {
\r
243 return this.parent;
\r
245 this.getLineString = function() {
\r
246 return this.linestring;
\r
248 this.setLineString = function(string) {
\r
249 this.linestring = string;
\r
251 this.isEditable = function() {
\r
252 return this.editable;
\r
254 this.setEditable = function(editable) {
\r
255 this.editable = editable;
\r
259 function getTreeNode(nodeID) {
\r
260 return findNodeWithID(rootNode,nodeID);
\r
262 function findNodeWithID(node,nodeID) {
\r
263 if (node.getID() == nodeID) {
\r
267 if (node.hasChilds()) {
\r
268 for(var i=0;i<node.getChildCount();i++) {
\r
269 var value = findNodeWithID(node.childs[i],nodeID);
\r
270 if (value != false) {
\r
278 function readStates() {
\r
279 //setCookie('tree' + documentID,'');
\r
280 states = getCookie('tree' + documentID);
\r
281 if (states != null) {
\r
282 var array = states.split(';');
\r
283 for(var i=0;i<array.length;i++) {
\r
284 var singlestate = array[i].split('|');
\r
285 statearray[i] = new Array();
\r
286 statearray[i]["key"] = singlestate[0];
\r
287 statearray[i]["state"] = singlestate[1];
\r
291 function getState(nodeID) {
\r
292 for(var i=0;i<statearray.length;i++) {
\r
293 if (statearray[i]["key"] == nodeID) {
\r
294 state = statearray[i]["state"];
\r
295 if (state == null || state == '') {
\r
303 function writeStates(nodeID,newstate) {
\r
307 for(var i=0;i<statearray.length;i++) {
\r
308 if (statearray[i]["key"] == nodeID) {
\r
309 statearray[i]["state"] = newstate;
\r
312 if (statearray[i]["state"] != null) {
\r
313 str += statearray[i]["key"] + '|' + statearray[i]["state"] + ';';
\r
316 if (found == false) {
\r
317 statearray[statearray.length] = new Array();
\r
318 statearray[statearray.length - 1]["key"] = nodeID;
\r
319 statearray[statearray.length - 1]["state"] = newstate;
\r
320 if (newstate != null) {
\r
321 str += nodeID + '|' + newstate + ';';
\r
324 setCookie('tree' + documentID,str);
\r
326 function showTree(path) {
\r
331 window.onblur = blurSelection;
\r
332 window.onfocus = focusSelection;
\r
334 str = '<div id="node' + rootNode.getID() + '" class="treetitle" style="display:' + (showRootNode == true ? 'block' : 'none') + '">';
\r
336 if (rootNode.hasIcon()) {
\r
337 str += '<img src="' + rootNode.getIcon() + '" style="vertical-align:middle;">';
\r
339 str += '<span style="vertical-align:middle;"> ' + rootNode.getName() + '</span>';
\r
340 str += '</nobr></div>';
\r
342 if (rootNode.hasChilds()) {
\r
343 for(i=0;i<rootNode.childs.length;i++) {
\r
344 nodeContents = showNode(rootNode.childs[i],(i == (rootNode.getChildCount() -1)));
\r
345 str = str + nodeContents;
\r
348 container.innerHTML = str;
\r
349 if (window.finishedLoading) {
\r
354 * Shows the given node, and subnodes.
\r
356 function showNode(treeNode,lastNode) {
\r
357 linestring = treeNode.getLineString();
\r
358 var state = getState(treeNode.getID());
\r
360 str = '<div style="filter:alpha(opacity=100);" ondragenter="dragEnter(' + treeNode.getID() + ');" ondragleave="dragLeave();" ondragstart="startDrag(' + treeNode.getID() + ');" ondrag="dragMove();" ondragend="endDrag(' + treeNode.getID() + ')" id="node' + treeNode.getID() + '">';
\r
362 for(var y=0;y<linestring.length;y++) {
\r
363 if (linestring.charAt(y) == 'I') {
\r
364 str += '<img src="' + href + 'static/' + (showLines ? 'line' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
\r
366 else if (linestring.charAt(y) == 'B') {
\r
367 str += '<img src="' + href + 'static/white.gif" style="width:19px;height:20px;vertical-align:middle;">';
\r
370 if (treeNode.hasChilds()) {
\r
371 // If this is the first child of the rootNode, and showRootNode is false, we want to display a different icon.
\r
372 if (!showRootNode && (treeNode.getParent() == rootNode) && (treeNode.getParent().getFirstChild() == treeNode)) {
\r
374 str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (state == 'open' ? (showLines ? 'minus_no_root' : 'minus_nolines') : (showLines ? 'plus_no_root' : 'plus_nolines')) + '.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
\r
377 str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (state == 'open' ? 'minus_last' : 'plus_last') + '_no_root.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
\r
382 str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (state == 'open' ? (showLines ? 'minus' : 'minus_nolines') : (showLines ? 'plus' : 'plus_nolines')) + '.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
\r
385 str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (state == 'open' ? (showLines ? 'minus_last' : 'minus_nolines') : (showLines ? 'plus_last' : 'plus_nolines')) + '.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
\r
390 // If this is the first child of the rootNode, and showRootNode is false, we want to display a different icon.
\r
391 if (!showRootNode && (treeNode.getParent() == rootNode) && (treeNode.getParent().getFirstChild() == treeNode)) {
\r
393 str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (showLines ? 't_no_root' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
\r
396 str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/white.gif" style="width:19px;height:20px;vertical-align:middle;">';
\r
401 str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (showLines ? 't' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
\r
404 str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (showLines ? 'lastnode' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
\r
408 iconStartImage = treeNode.getIcon();
\r
409 if (state != 'closed') {
\r
410 if (treeNode.hasChilds()) {
\r
411 iconStartImage = treeNode.getOpenIcon();
\r
415 str += '<img id="iconimage' + treeNode.getID() + '" src="' + iconStartImage + '" style="vertical-align:middle;" OnClick="selectNode(' + treeNode.getID() + ')">';
\r
416 str += ' <span unselectable="ON" style="vertical-align:middle;" class="treetitle" ID="title' + treeNode.getID() + '" OnDblClick="handleNode(' + treeNode.getID() + ')" OnClick="selectNode(' + treeNode.getID() + ')">';
\r
417 str += treeNode.getName();
\r
422 if (treeNode.hasChilds()) {
\r
423 if (state == 'open') {
\r
424 str += '<div id="node' + treeNode.getID() + 'sub" style="display:block;">';
\r
425 fireOpenEvent(treeNode);
\r
426 // alert('openevent: ' + treeNode.getName());
\r
429 str += '<div id="node' + treeNode.getID() + 'sub" style="display:' + (showAllNodesOnStartup == true ? 'block;' : 'none;') + ';">';
\r
431 var subgroupstr = '';
\r
440 for(var z=0;z<treeNode.getChildCount();z++) {
\r
441 treeNode.childs[z].setLineString(linestring + newChar);
\r
443 for(var z=0;z<treeNode.getChildCount();z++) {
\r
444 subgroupstr += showNode(treeNode.childs[z],(z == (treeNode.getChildCount() -1)));
\r
446 str += subgroupstr;
\r
450 str += '<div id="node' + treeNode.getID() + 'sub" style="display:none;">';
\r
456 function mouseMove() {
\r
461 function mouseUp() {
\r
463 alert('dropped on something!');
\r
467 function startDrag(nodeID) {
\r
471 draggedNodeID = nodeID;
\r
473 var srcObj = window.event.srcElement;
\r
474 while(srcObj.tagName != 'DIV') {
\r
475 srcObj = srcObj.parentElement;
\r
477 floatDragElement = document.createElement('DIV');
\r
479 floatDragElement.innerHTML = srcObj.innerHTML;
\r
480 floatDragElement.childNodes[0].removeChild(floatDragElement.childNodes[0].childNodes[0]);
\r
482 document.body.appendChild(floatDragElement);
\r
483 floatDragElement.style.zIndex = 100;
\r
484 floatDragElement.style.position = 'absolute';
\r
485 floatDragElement.style.filter='progid:DXImageTransform.Microsoft.Alpha(1,opacity=60);';
\r
487 function findSpanChild(element) {
\r
488 if (element.tagName == 'SPAN') {
\r
492 if (element.childNodes) {
\r
493 for(var i=0;i<element.childNodes.length;i++) {
\r
494 var value = findSpanChild(element.childNodes[i]);
\r
495 if (value != false) {
\r
503 function dragEnter(nodeID) {
\r
507 lastDraggedOnNodeID = nodeID;
\r
509 if (colouredElement) {
\r
510 findSpanChild(colouredElement).className = 'treetitle';
\r
512 colouredElement = window.event.srcElement;
\r
513 while(colouredElement.tagName != 'DIV') {
\r
514 colouredElement = colouredElement.parentElement;
\r
515 if (colouredElement.tagName == 'BODY') {
\r
516 // Something gone seriously wrong.
\r
517 alert('Drag failure, reached <BODY>!');
\r
521 findSpanChild(colouredElement).className = 'treetitleselectedfocused';
\r
523 function dragLeave() {
\r
528 function endDrag(nodeID) {
\r
532 if (lastDraggedOnNodeID != null) {
\r
533 fireMoveEvent(getTreeNode(lastDraggedOnNodeID),draggedNodeID,lastDraggedOnNodeID);
\r
536 function dragProceed() {
\r
540 var dragged = getTreeNode(draggedNodeID);
\r
541 var newparent = getTreeNode(lastDraggedOnNodeID);
\r
543 var oldparent = dragged.getParent();
\r
545 oldparent.removeChild(dragged);
\r
546 newparent.addChild(dragged);
\r
548 refreshNode(oldparent);
\r
549 refreshNode(newparent);
\r
553 function dragCancel() {
\r
560 * Don't call this yourself.
\r
562 function _dragClean() {
\r
566 if (colouredElement) {
\r
567 findSpanChild(colouredElement).className = 'treetitle';
\r
570 floatDragElement.parentElement.removeChild(floatDragElement);
\r
571 floatDragElement = null;
\r
572 colouredElement = null;
\r
573 draggedNodeID = null;
\r
574 lastDraggedOnNodeID = null;
\r
576 function dragMove() {
\r
580 floatDragElement.style.top = window.event.clientY;
\r
581 floatDragElement.style.left = window.event.clientX;
\r
583 function editEnded() {
\r
584 if (treeNodeEdited != null) {
\r
585 // treeNodeEdited.getID();
\r
586 var editTitle = document.getElementById('title' + treeNodeEdited.getID());
\r
587 var input = editTitle.childNodes[0];
\r
589 var newValue = input.value;
\r
591 if (newValue == treeNodeEdited.getName()) {
\r
592 editTitle.innerHTML = newValue;
\r
593 treeNodeEdited = null;
\r
597 fireEditEvent(treeNodeEdited,newValue);
\r
599 if (!editaborted) {
\r
600 treeNodeEdited.setName(newValue);
\r
601 editTitle.innerHTML = newValue;
\r
604 treeNodeEdited = null;
\r
607 function selectNode(nodeID) {
\r
608 var treeNode = getTreeNode(nodeID);
\r
610 if (selectedNode != null) {
\r
611 if (selectedNode == nodeID) {
\r
612 if (treeNode.isEditable()) {
\r
613 if (treeNodeEdited == treeNode) {
\r
616 treeNodeEdited = treeNode;
\r
617 var editTitle = document.getElementById('title' + treeNode.getID());
\r
618 editTitle.className = 'editednode';
\r
621 editTitle.innerHTML = '<input type="text" onKeypress="if (event.keyCode == 13) { this.onblur = null; editEnded(); }" name="editednode" class="editednodeinput">';
\r
622 var input = editTitle.childNodes[0];
\r
623 input.value = treeNode.getName();
\r
626 input.onblur = editEnded;
\r
630 if (treeNodeEdited != null) {
\r
633 var oldNodeTitle = document.getElementById('title' + selectedNode);
\r
634 oldNodeTitle.className = 'treetitle';
\r
636 selectedNode = nodeID;
\r
637 var nodetitle = document.getElementById('title' + selectedNode);
\r
638 nodetitle.className = 'treetitleselectedfocused';
\r
640 if (treeNode.gotHandler()) {
\r
641 eval(treeNode.getHandler() + '(getTreeNode(' + nodeID + '));');
\r
644 standardClick(treeNode);
\r
647 function refreshNode(treeNode) {
\r
648 var submenu = document.getElementById('node' + treeNode.getID() + 'sub');
\r
650 for(var i=0;i<treeNode.getChildCount();i++) {
\r
651 var parent = treeNode.getParent();
\r
653 treeNode.childs[i].setLineString(treeNode.getLineString() + 'B');
\r
656 if (parent.childs[parent.childs.length - 1] == treeNode) {
\r
657 treeNode.childs[i].setLineString(treeNode.getLineString() + 'B');
\r
660 treeNode.childs[i].setLineString(treeNode.getLineString() + 'I');
\r
663 str += showNode(treeNode.childs[i],i == (treeNode.getChildCount() - 1));
\r
665 var actionimage = document.getElementById('handler' + treeNode.getID());
\r
666 if (treeNode.getChildCount() == 0) {
\r
667 // TreeNode haven't got any children, make sure the right image is displayed.
\r
668 if (actionimage.src.indexOf('last') == -1) {
\r
669 actionimage.src = href + 'static/' + (showLines ? 't' : 'white') + '.gif';
\r
672 actionimage.src = href + 'static/' + (showLines ? 'lastnode' : 'white') + '.gif';
\r
674 actionimage.onclick = null;
\r
676 // Close the submenu
\r
678 submenu.style.display = 'none';
\r
682 // We have children, make sure to display the + and - icon.
\r
683 if (actionimage.src.indexOf('plus') != -1) {
\r
684 // The TreeNode have already got children, and displays them.
\r
686 else if (actionimage.src.indexOf('minus') != -1) {
\r
687 // The TreeNode have already got children, and displays them.
\r
690 if (actionimage.src.indexOf('last') == -1) {
\r
691 actionimage.outerHTML = '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/' + (showLines ? 'plus' : 'plus_nolines') + '.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
\r
694 actionimage.outerHTML = '<img id="handler' + treeNode.getID() + '" src="' + href + 'static/plus_last.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
\r
698 submenu.innerHTML = str;
\r
700 function handleNode(nodeID) {
\r
701 var treeNode = getTreeNode(nodeID);
\r
702 if (!treeNode.hasChilds()) { // No reason to handle a node without childs.
\r
706 var submenu = document.getElementById('node' + nodeID + 'sub');
\r
708 var iconimageholder = document.getElementById('iconimage' + nodeID);
\r
709 var actionimage = document.getElementById('handler' + nodeID);
\r
711 // This will be used if showRootNode is set to false.
\r
712 var firstChildOfRoot = false;
\r
713 if (actionimage.src.indexOf('_no_root') != -1) {
\r
714 firstChildOfRoot = true;
\r
717 if (submenu.style.display == 'none') {
\r
718 writeStates(nodeID,'open');
\r
719 fireOpenEvent(treeNode);
\r
720 submenu.style.display = 'block';
\r
722 iconimageholder.src = treeNode.getOpenIcon();
\r
724 if (actionimage.src.indexOf('last') == -1) {
\r
725 actionimage.src = href + 'static/' + ((firstChildOfRoot) ? 'minus_no_root' : (showLines ? 'minus' : 'minus_nolines')) + '.gif';
\r
728 actionimage.src = href + 'static/' + ((firstChildOfRoot) ? 'minus_last_no_root' : (showLines ? 'minus_last' : 'minus_nolines')) + '.gif';
\r
732 writeStates(nodeID,'closed');
\r
733 submenu.style.display = 'none';
\r
735 iconimageholder.src = treeNode.getIcon();
\r
737 if (actionimage.src.indexOf('last') == -1) {
\r
738 actionimage.src = href + 'static/' + ((firstChildOfRoot) ? 'plus_no_root' : (showLines ? 'plus' : 'plus_nolines')) + '.gif';
\r
741 actionimage.src = href + 'static/' + ((firstChildOfRoot) ? 'plus_last_no_root' : (showLines ? 'plus_last' : 'plus_nolines')) + '.gif';
\r
745 function fireOpenEvent(treeNode) {
\r
746 if (treeNode.gotOpenEventListeners()) {
\r
747 for(var i=0;i<treeNode.openeventlisteners.length;i++) {
\r
748 eval(treeNode.openeventlisteners[i] + '(' + treeNode.getID() + ');');
\r
752 function fireEditEvent(treeNode,newVal) {
\r
753 if (treeNode.gotEditEventListeners()) {
\r
754 for(var i=0;i<treeNode.editeventlisteners.length;i++) {
\r
755 eval(treeNode.editeventlisteners[i] + '(' + treeNode.getID() + ',\'' + escape(newVal) + '\');');
\r
759 function fireMoveEvent(treeNode,draggedNodeID,droppedOnNodeID) {
\r
760 if (treeNode.gotMoveEventListeners()) {
\r
761 for(var i=0;i<treeNode.moveeventlisteners.length;i++) {
\r
762 eval(treeNode.moveeventlisteners[i] + '(' + draggedNodeID + ',' + droppedOnNodeID + ');');
\r
766 function blurSelection() {
\r
767 if (selectedNode != null) {
\r
768 var oldNodeTitle = document.getElementById('title' + selectedNode);
\r
769 oldNodeTitle.className = 'treetitleselectedblured';
\r
772 function focusSelection() {
\r
773 if (selectedNode != null) {
\r
774 var oldNodeTitle = document.getElementById('title' + selectedNode);
\r
775 oldNodeTitle.className = 'treetitleselectedfocused';
\r
778 function getCookieVal (offset) {
\r
779 var endstr = document.cookie.indexOf (";",offset);
\r
780 if (endstr == -1) {
\r
781 endstr = document.cookie.length;
\r
783 return unescape(document.cookie.substring(offset,endstr));
\r
785 function getCookie (name) {
\r
786 var arg = name + "=";
\r
787 var alen = arg.length;
\r
788 var clen = document.cookie.length;
\r
792 if (document.cookie.substring(i, j) == arg) {
\r
793 return getCookieVal(j);
\r
795 i = document.cookie.indexOf(" ", i) + 1;
\r
802 function setCookie (name, value) {
\r
803 var argv = setCookie.arguments;
\r
804 var argc = setCookie.arguments.length;
\r
805 var expires = (argc > 2) ? argv[2] : null;
\r
806 var path = (argc > 3) ? argv[3] : null;
\r
807 var domain = (argc > 4) ? argv[4] : null;
\r
808 var secure = (argc > 5) ? argv[5] : false;
\r
809 document.cookie = name + "=" + escape (value) + ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + ((path == null) ? "" : ("; path=" + path)) + ((domain == null) ? "" : ("; domain=" + domain)) + ((secure == true) ? "; secure" : "");
\r
811 function expandNode() {
\r
812 var state = getState(selectedNode);
\r
813 if (state == 'open') {
\r
814 var currentTreeNode = getTreeNode(selectedNode);
\r
815 if (currentTreeNode.hasChilds()) {
\r
816 selectNode(currentTreeNode.childs[0].getID());
\r
820 handleNode(selectedNode);
\r
823 function subtractNode() {
\r
824 var state = getState(selectedNode);
\r
825 if (state == 'closed') {
\r
826 var currentTreeNode = getTreeNode(selectedNode);
\r
827 var parent = currentTreeNode.getParent();
\r
828 if (parent != null && parent != rootNode) {
\r
829 selectNode(parent.getID());
\r
833 handleNode(selectedNode);
\r
836 function selectPrevNode() {
\r
837 var currentTreeNode = getTreeNode(selectedNode);
\r
838 if (currentTreeNode.prevSibling != null) {
\r
840 var state = getState(currentTreeNode.prevSibling.getID());
\r
842 if (state == 'open' && currentTreeNode.prevSibling.hasChilds()) {
\r
843 // We have to find the last open child of the previoussiblings childs.
\r
844 var current = currentTreeNode.prevSibling.childs[currentTreeNode.prevSibling.childs.length - 1];
\r
845 var currentstate = 'open';
\r
846 while (current.hasChilds() && (getState(current.getID()) == 'open')) {
\r
847 current = current.childs[current.childs.length - 1];
\r
849 selectNode(current.getID());
\r
852 selectNode(currentTreeNode.prevSibling.getID());
\r
856 if (currentTreeNode.getParent() != null && currentTreeNode.getParent() != rootNode) {
\r
857 selectNode(currentTreeNode.getParent().getID());
\r
861 function selectNextNode() {
\r
862 var currentTreeNode = getTreeNode(selectedNode);
\r
864 var state = getState(selectedNode);
\r
865 if (state == 'open' && currentTreeNode.hasChilds()) {
\r
866 selectNode(currentTreeNode.childs[0].getID());
\r
869 if (currentTreeNode.nextSibling != null) {
\r
870 selectNode(currentTreeNode.nextSibling.getID());
\r
873 // Continue up the tree until we either hit null, or a parent which have a child.
\r
874 var parent = currentTreeNode;
\r
875 while ((parent = parent.getParent()) != rootNode) {
\r
876 if (parent.nextSibling != null) {
\r
877 selectNode(parent.nextSibling.getID());
\r
882 if (currentTreeNode.getParent().nextSibling != null) {
\r
883 selectNode(currentTreeNode.getParent().nextSibling.getID());
\r
889 function keyDown(event) {
\r
890 if (window.event) {
\r
891 event = window.event;
\r
893 if (event.keyCode == 38) { // Up
\r
897 else if (event.keyCode == 40) { // Down
\r
901 else if (event.keyCode == 37) { // left
\r
905 else if (event.keyCode == 39) { // right
\r
910 document.onkeydown = keyDown;
\r