Nano Tree
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>NanoTree</title>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<!-- std_treelook.css -->
<style REL="STYLESHEET" TYPE="text/css">
/* Tree Style */
.treetitle {
padding:2px;
cursor:default;
font-family: Tahoma,Verdana,Arial, Helvetica, sans-serif;
font-size: 11px;
color: #000000;
}
.editednode {
padding:2px;
cursor:default;
background-color: #FFFFFF;;
color: #000000;
font-family: Tahoma,Verdana,Arial, Helvetica, sans-serif;
font-size: 11px;
}
.editednodeinput {
background-color: #FFFFFF;;
color: #000000;
width: 150px;
height: 17px;
border-style: solid;
border-width: 1px;
border-color: #000000;
font-family: Tahoma,Verdana,Arial, Helvetica, sans-serif;
font-size: 11px;
}
.treetitleselectedfocused {
padding:2px;
cursor:default;
background-color: highlight;
color: highlighttext;
font-family: Tahoma,Verdana,Arial, Helvetica, sans-serif;
font-size: 11px;
}
.treetitleselectedblured {
padding:2px;
cursor:default;
background-color: menu;
color: windowtext;
font-family: Tahoma,Verdana,Arial, Helvetica, sans-serif;
font-size: 11px;
}
</style>
<!-- nanotree.js -->
<script type="text/javascript" language="JavaScript">
/**
* Original Author of this file: Martin Mouritzen. (martin@nano.dk)
*
*
* (Lack of) Documentation:
*
*
* If a finishedLoading method exists, it will be called when the tree is loaded.
* (good to display a div, etc.).
*
*
* You have to set the variable rootNode (as a TreeNode).
*
* You have to set a container element, this is the element in which the tree will be.
*
*
* TODO:
* Save cookies better (only 1 cookie for each tree). Else the page will totally cookieclutter.
*
***********************************************************************
* Configuration variables.
************************************************************************/
// Should the rootNode be displayed.
var showRootNode = true;
// Should the dashed lines between nodes be shown.
var showLines = true;
// Should the nodes be sorted? (You can either specify a number, then it will be sorted by that, else it will
// be sorted alphabetically (by name).
var sortNodes = true;
// This is IMPORTANT... use an unique id for each document you use the tree in. (else they'll get mixed up).
var documentID = window.location.href;
// being read from cookie.
var nodesOpen = new Array();
// RootNode of the tree.
var rootNode;
// Container to display the Tree in.
var container;
// Shows/Hides subnodes on startup
var showAllNodesOnStartup = false;
// Is the roots dragable?
var dragable = false;
/************************************************************************
* The following is just instancevariables.
************************************************************************/
var href = '';
// rootNodeCallBack name (if null, it's not selectable).
var rootNodeCallBack = null;
// selectedNode
var selectedNode = null;
var states = '';
var statearray = new Array();
var treeNodeEdited = null;
var editaborted = false;
var floatDragElement = null;
var colouredElement = null;
var draggedNodeID = null;
var lastDraggedOnNodeID = null;
/**
* The TreeNode Object
* @param id unique id of this treenode
* @param name The title of this node
* @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)
* @param param A parameter, this can be pretty much anything. (eg. an array with information).
* @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).
*/
function TreeNode(id,name,icon,param,orderNumber) {
this.id = id;
this.childs = new Array();
this.name = (name == null ? 'unset name' : name);
this.icon = (icon == null ? '' : icon);
this.parent = null;
this.handler = null;
this.param = (param == null ? '' : param);
this.orderNumber = (orderNumber == null ? -1 : orderNumber);
this.openeventlisteners = new Array();
this.editeventlisteners = new Array();
this.moveeventlisteners = new Array();
this.haschilds = false;
this.editable = false;
this.linestring = '';
this.nextSibling = null;
this.prevSibling = null;
this.childsHasBeenFetched = false;
this.getID = function() {
return this.id;
}
this.setName = function(newname) {
this.name = newname;
}
this.getName = function() {
return this.name;
}
this.getParam = function() {
return this.param;
}
this.setIcon = function(icon) {
this.icon = icon;
}
this.getIcon = function() {
if (typeof(this.icon) == 'object') {
return this.icon[0];
}
return this.icon;
}
this.getOpenIcon = function() {
if (typeof(this.icon) == 'object') {
return this.icon[1];
}
return this.icon;
}
this.hasIcon = function () {
return this.icon != '';
}
this.getOrderNumber = function() {
return this.orderNumber;
}
this.addOpenEventListener = function(event) {
this.openeventlisteners[this.openeventlisteners.length] = event;
}
this.gotOpenEventListeners = function() {
return (this.openeventlisteners.length > 0);
}
this.addEditEventListener = function(event) {
this.editeventlisteners[this.editeventlisteners.length] = event;
}
this.gotEditEventListeners = function() {
return (this.editeventlisteners.length > 0);
}
this.addMoveEventListener = function(event) {
this.moveeventlisteners[this.moveeventlisteners.length] = event;
}
this.gotMoveEventListeners = function() {
return (this.moveeventlisteners.length > 0);
}
this.addChild = function(childNode) {
var possiblePrevNode = this.childs[this.childs.length - 1]
if (possiblePrevNode) {
possiblePrevNode.nextSibling = childNode;
childNode.prevSibling = possiblePrevNode;
// alert(childNode.prevSibling);
}
this.childs[this.childs.length] = childNode;
childNode.setParent(this);
if (sortNodes) {
function sortByOrder(a,b) {
var order1 = a.getOrderNumber();
var order2 = b.getOrderNumber();
if (order1 == -1 || order2 == -1) {
return a.getName().toLowerCase() > b.getName().toLowerCase() ? 1 : -1;
}
else {
if (order1 == order2) {
// If they got the same order number, then we'll sort by their title.
return a.getName().toLowerCase() > b.getName().toLowerCase() ? 1 : -1;
}
else {
return order1 - order2;
}
}
}
this.childs.sort(sortByOrder);
}
}
this.removeChild = function(childNode) {
var found = false;
for (var i=0;i<this.childs.length;i++) {
if (found) {
this.childs[i] = this.childs[i + 1];
}
if (this.childs[i] == childNode) {
if (i == (this.childs.length - 1)) {
this.childs[i] = null;
}
else {
this.childs[i] = this.childs[i + 1];
}
found = true;
}
}
if (found) {
this.childs.length = this.childs.length-1;
}
}
this.resetChilds = function() {
this.childs = new Array();
}
this.setHasChilds = function(hasChilds) {
this.haschilds = hasChilds;
}
this.hasChilds = function() {
if (this.haschilds == true) {
return true;
}
return (this.childs.length > 0);
}
this.getChildCount = function() {
return this.childs.length;
}
this.getFirstChild = function() {
if (this.hasChilds()) {
return this.childs[0];
}
return null;
}
this.gotHandler = function() {
return this.handler != null;
}
this.setHandler = function(handler) {
this.handler = handler;
}
this.getHandler = function() {
return this.handler;
}
this.setParent = function(parent) {
this.parent = parent;
}
this.getParent = function() {
return this.parent;
}
this.getLineString = function() {
return this.linestring;
}
this.setLineString = function(string) {
this.linestring = string;
}
this.isEditable = function() {
return this.editable;
}
this.setEditable = function(editable) {
this.editable = editable;
}
}
function getTreeNode(nodeID) {
return findNodeWithID(rootNode,nodeID);
}
function findNodeWithID(node,nodeID) {
if (node.getID() == nodeID) {
return node;
}
else {
if (node.hasChilds()) {
for(var i=0;i<node.getChildCount();i++) {
var value = findNodeWithID(node.childs[i],nodeID);
if (value != false) {
return value;
}
}
}
return false;
}
}
function readStates() {
//setCookie('tree' + documentID,'');
states = getCookie('tree' + documentID);
if (states != null) {
var array = states.split(';');
for(var i=0;i<array.length;i++) {
var singlestate = array[i].split('|');
statearray[i] = new Array();
statearray[i]["key"] = singlestate[0];
statearray[i]["state"] = singlestate[1];
}
}
}
function getState(nodeID) {
for(var i=0;i<statearray.length;i++) {
if (statearray[i]["key"] == nodeID) {
state = statearray[i]["state"];
if (state == null || state == '') {
state = 'closed';
}
return state;
}
}
return "closed";
}
function writeStates(nodeID,newstate) {
//alert(nodeID);
var str = '';
var found = false;
for(var i=0;i<statearray.length;i++) {
if (statearray[i]["key"] == nodeID) {
statearray[i]["state"] = newstate;
found = true;
}
if (statearray[i]["state"] != null) {
str += statearray[i]["key"] + '|' + statearray[i]["state"] + ';';
}
}
if (found == false) {
statearray[statearray.length] = new Array();
statearray[statearray.length - 1]["key"] = nodeID;
statearray[statearray.length - 1]["state"] = newstate;
if (newstate != null) {
str += nodeID + '|' + newstate + ';';
}
}
setCookie('tree' + documentID,str);
}
function showTree(path) {
readStates();
href = path;
window.focus();
window.onblur = blurSelection;
window.onfocus = focusSelection;
var str = '';
str = '<div id="node' + rootNode.getID() + '" class="treetitle" style="display:' + (showRootNode == true ? 'block' : 'none') + '">';
str += '<nobr>';
if (rootNode.hasIcon()) {
str += '<img src="' + rootNode.getIcon() + '" style="vertical-align:middle;">';
}
str += '<span style="vertical-align:middle;"> ' + rootNode.getName() + '</span>';
str += '</nobr></div>';
if (rootNode.hasChilds()) {
for(i=0;i<rootNode.childs.length;i++) {
nodeContents = showNode(rootNode.childs[i],(i == (rootNode.getChildCount() -1)));
str = str + nodeContents;
}
}
container.innerHTML = str;
if (window.finishedLoading) {
finishedLoading();
}
}
/**
* Shows the given node, and subnodes.
*/
function showNode(treeNode,lastNode) {
linestring = treeNode.getLineString();
var state = getState(treeNode.getID());
var str;
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() + '">';
str += '<nobr>';
for(var y=0;y<linestring.length;y++) {
if (linestring.charAt(y) == 'I') {
str += '<img src="' + href + 'nanoImages/' + (showLines ? 'line' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
}
else if (linestring.charAt(y) == 'B') {
str += '<img src="' + href + 'nanoImages/white.gif" style="width:19px;height:20px;vertical-align:middle;">';
}
}
if (treeNode.hasChilds()) {
// If this is the first child of the rootNode, and showRootNode is false, we want to display a different icon.
if (!showRootNode && (treeNode.getParent() == rootNode) && (treeNode.getParent().getFirstChild() == treeNode)) {
if (!lastNode) {
str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'nanoImages/' + (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() + ');">';
}
else {
str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'nanoImages/' + (state == 'open' ? 'minus_last' : 'plus_last') + '_no_root.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
}
}
else {
if (!lastNode) {
str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'nanoImages/' + (state == 'open' ? (showLines ? 'minus' : 'minus_nolines') : (showLines ? 'plus' : 'plus_nolines')) + '.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
}
else {
str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'nanoImages/' + (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() + ');">';
}
}
}
else {
// If this is the first child of the rootNode, and showRootNode is false, we want to display a different icon.
if (!showRootNode && (treeNode.getParent() == rootNode) && (treeNode.getParent().getFirstChild() == treeNode)) {
if (!lastNode) {
str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'nanoImages/' + (showLines ? 't_no_root' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
}
else {
str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'nanoImages/white.gif" style="width:19px;height:20px;vertical-align:middle;">';
}
}
else {
if (!lastNode) {
str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'nanoImages/' + (showLines ? 't' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
}
else {
str += '<img id="handler' + treeNode.getID() + '" src="' + href + 'nanoImages/' + (showLines ? 'lastnode' : 'white') + '.gif" style="width:19px;height:20px;vertical-align:middle;">';
}
}
}
iconStartImage = treeNode.getIcon();
if (state != 'closed') {
if (treeNode.hasChilds()) {
iconStartImage = treeNode.getOpenIcon();
}
}
str += '<img id="iconimage' + treeNode.getID() + '" src="' + iconStartImage + '" style="vertical-align:middle;" OnClick="selectNode(' + treeNode.getID() + ')">';
str += ' <span unselectable="ON" style="vertical-align:middle;" class="treetitle" ID="title' + treeNode.getID() + '" OnDblClick="handleNode(' + treeNode.getID() + ')" OnClick="selectNode(' + treeNode.getID() + ')">';
str += treeNode.getName();
str += '</span>';
str += '</nobr>';
str += '</div>';
if (treeNode.hasChilds()) {
if (state == 'open') {
str += '<div id="node' + treeNode.getID() + 'sub" style="display:block;">';
fireOpenEvent(treeNode);
// alert('openevent: ' + treeNode.getName());
}
else {
str += '<div id="node' + treeNode.getID() + 'sub" style="display:' + (showAllNodesOnStartup == true ? 'block;' : 'none;') + ';">';
}
var subgroupstr = '';
var newChar = '';
if (!lastNode) {
newChar = 'I';
}
else {
newChar = 'B';
}
for(var z=0;z<treeNode.getChildCount();z++) {
treeNode.childs[z].setLineString(linestring + newChar);
}
for(var z=0;z<treeNode.getChildCount();z++) {
subgroupstr += showNode(treeNode.childs[z],(z == (treeNode.getChildCount() -1)));
}
str += subgroupstr;
str += '</div>';
}
else {
str += '<div id="node' + treeNode.getID() + 'sub" style="display:none;">';
str += '</div>';
}
return str;
}
/*
function mouseMove() {
if (dragging) {
alert('bob');
}
}
function mouseUp() {
if (dragging) {
alert('dropped on something!');
}
}
*/
function startDrag(nodeID) {
if (!dragable) {
return;
}
draggedNodeID = nodeID;
var srcObj = window.event.srcElement;
while(srcObj.tagName != 'DIV') {
srcObj = srcObj.parentElement;
}
floatDragElement = document.createElement('DIV');
floatDragElement.innerHTML = srcObj.innerHTML;
floatDragElement.childNodes[0].removeChild(floatDragElement.childNodes[0].childNodes[0]);
document.body.appendChild(floatDragElement);
floatDragElement.style.zIndex = 100;
floatDragElement.style.position = 'absolute';
floatDragElement.style.filter='progid:DXImageTransform.Microsoft.Alpha(1,opacity=60);';
}
function findSpanChild(element) {
if (element.tagName == 'SPAN') {
return element;
}
else {
if (element.childNodes) {
for(var i=0;i<element.childNodes.length;i++) {
var value = findSpanChild(element.childNodes[i]);
if (value != false) {
return value;
}
}
return false;
}
}
}
function dragEnter(nodeID) {
if (!dragable) {
return;
}
lastDraggedOnNodeID = nodeID;
if (colouredElement) {
findSpanChild(colouredElement).className = 'treetitle';
}
colouredElement = window.event.srcElement;
while(colouredElement.tagName != 'DIV') {
colouredElement = colouredElement.parentElement;
if (colouredElement.tagName == 'BODY') {
// Something gone seriously wrong.
alert('Drag failure, reached <BODY>!');
return;
}
}
findSpanChild(colouredElement).className = 'treetitleselectedfocused';
}
function dragLeave() {
if (!dragable) {
return;
}
}
function endDrag(nodeID) {
if (!dragable) {
return;
}
if (lastDraggedOnNodeID != null) {
fireMoveEvent(getTreeNode(lastDraggedOnNodeID),draggedNodeID,lastDraggedOnNodeID);
}
}
function dragProceed() {
if (!dragable) {
return;
}
var dragged = getTreeNode(draggedNodeID);
var newparent = getTreeNode(lastDraggedOnNodeID);
var oldparent = dragged.getParent();
oldparent.removeChild(dragged);
newparent.addChild(dragged);
refreshNode(oldparent);
refreshNode(newparent);
_dragClean()
}
function dragCancel() {
if (!dragable) {
return;
}
_dragClean()
}
/**
* Don't call this yourself.
*/
function _dragClean() {
if (!dragable) {
return;
}
if (colouredElement) {
findSpanChild(colouredElement).className = 'treetitle';
}
floatDragElement.parentElement.removeChild(floatDragElement);
floatDragElement = null;
colouredElement = null;
draggedNodeID = null;
lastDraggedOnNodeID = null;
}
function dragMove() {
if (!dragable) {
return;
}
floatDragElement.style.top = window.event.clientY;
floatDragElement.style.left = window.event.clientX;
}
function editEnded() {
if (treeNodeEdited != null) {
// treeNodeEdited.getID();
var editTitle = document.getElementById('title' + treeNodeEdited.getID());
var input = editTitle.childNodes[0];
var newValue = input.value;
if (newValue == treeNodeEdited.getName()) {
editTitle.innerHTML = newValue;
treeNodeEdited = null;
return;
}
fireEditEvent(treeNodeEdited,newValue);
if (!editaborted) {
treeNodeEdited.setName(newValue);
editTitle.innerHTML = newValue;
}
treeNodeEdited = null;
}
}
function selectNode(nodeID) {
var treeNode = getTreeNode(nodeID);
if (selectedNode != null) {
if (selectedNode == nodeID) {
if (treeNode.isEditable()) {
if (treeNodeEdited == treeNode) {
return;
}
treeNodeEdited = treeNode;
var editTitle = document.getElementById('title' + treeNode.getID());
editTitle.className = 'editednode';
editTitle.innerHTML = '<input type="text" onKeypress="if (event.keyCode == 13) { this.onblur = null; editEnded(); }" name="editednode" class="editednodeinput">';
var input = editTitle.childNodes[0];
input.value = treeNode.getName();
input.focus();
input.select();
input.onblur = editEnded;
}
return;
}
if (treeNodeEdited != null) {
editEnded();
}
var oldNodeTitle = document.getElementById('title' + selectedNode);
oldNodeTitle.className = 'treetitle';
}
selectedNode = nodeID;
var nodetitle = document.getElementById('title' + selectedNode);
nodetitle.className = 'treetitleselectedfocused';
if (treeNode.gotHandler()) {
eval(treeNode.getHandler() + '(getTreeNode(' + nodeID + '));');
}
else {
standardClick(treeNode);
}
}
function refreshNode(treeNode) {
var submenu = document.getElementById('node' + treeNode.getID() + 'sub');
var str = '';
for(var i=0;i<treeNode.getChildCount();i++) {
var parent = treeNode.getParent();
if (!parent) {
treeNode.childs[i].setLineString(treeNode.getLineString() + 'B');
}
else {
if (parent.childs[parent.childs.length - 1] == treeNode) {
treeNode.childs[i].setLineString(treeNode.getLineString() + 'B');
}
else {
treeNode.childs[i].setLineString(treeNode.getLineString() + 'I');
}
}
str += showNode(treeNode.childs[i],i == (treeNode.getChildCount() - 1));
}
var actionimage = document.getElementById('handler' + treeNode.getID());
if (treeNode.getChildCount() == 0) {
// TreeNode haven't got any children, make sure the right image is displayed.
if (actionimage.src.indexOf('last') == -1) {
actionimage.src = href + 'nanoImages/' + (showLines ? 't' : 'white') + '.gif';
}
else {
actionimage.src = href + 'nanoImages/' + (showLines ? 'lastnode' : 'white') + '.gif';
}
actionimage.onclick = null;
// Close the submenu
if (submenu) {
submenu.style.display = 'none';
}
}
else {
// We have children, make sure to display the + and - icon.
if (actionimage.src.indexOf('plus') != -1) {
// The TreeNode have already got children, and displays them.
}
else if (actionimage.src.indexOf('minus') != -1) {
// The TreeNode have already got children, and displays them.
}
else {
if (actionimage.src.indexOf('last') == -1) {
actionimage.outerHTML = '<img id="handler' + treeNode.getID() + '" src="' + href + 'nanoImages/' + (showLines ? 'plus' : 'plus_nolines') + '.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
}
else {
actionimage.outerHTML = '<img id="handler' + treeNode.getID() + '" src="' + href + 'nanoImages/plus_last.gif" style="width:19px;height:20px;vertical-align:middle;" OnClick="handleNode(' + treeNode.getID() + ');">';
}
}
}
submenu.innerHTML = str;
}
function handleNode(nodeID) {
var treeNode = getTreeNode(nodeID);
if (!treeNode.hasChilds()) { // No reason to handle a node without childs.
return;
}
var submenu = document.getElementById('node' + nodeID + 'sub');
var iconimageholder = document.getElementById('iconimage' + nodeID);
var actionimage = document.getElementById('handler' + nodeID);
// This will be used if showRootNode is set to false.
var firstChildOfRoot = false;
if (actionimage.src.indexOf('_no_root') != -1) {
firstChildOfRoot = true;
}
if (submenu.style.display == 'none') {
writeStates(nodeID,'open');
fireOpenEvent(treeNode);
submenu.style.display = 'block';
iconimageholder.src = treeNode.getOpenIcon();
if (actionimage.src.indexOf('last') == -1) {
actionimage.src = href + 'nanoImages/' + ((firstChildOfRoot) ? 'minus_no_root' : (showLines ? 'minus' : 'minus_nolines')) + '.gif';
}
else {
actionimage.src = href + 'nanoImages/' + ((firstChildOfRoot) ? 'minus_last_no_root' : (showLines ? 'minus_last' : 'minus_nolines')) + '.gif';
}
}
else {
writeStates(nodeID,'closed');
submenu.style.display = 'none';
iconimageholder.src = treeNode.getIcon();
if (actionimage.src.indexOf('last') == -1) {
actionimage.src = href + 'nanoImages/' + ((firstChildOfRoot) ? 'plus_no_root' : (showLines ? 'plus' : 'plus_nolines')) + '.gif';
}
else {
actionimage.src = href + 'nanoImages/' + ((firstChildOfRoot) ? 'plus_last_no_root' : (showLines ? 'plus_last' : 'plus_nolines')) + '.gif';
}
}
}
function fireOpenEvent(treeNode) {
if (treeNode.gotOpenEventListeners()) {
for(var i=0;i<treeNode.openeventlisteners.length;i++) {
eval(treeNode.openeventlisteners[i] + '(' + treeNode.getID() + ');');
}
}
}
function fireEditEvent(treeNode,newVal) {
if (treeNode.gotEditEventListeners()) {
for(var i=0;i<treeNode.editeventlisteners.length;i++) {
eval(treeNode.editeventlisteners[i] + '(' + treeNode.getID() + ',\'' + escape(newVal) + '\');');
}
}
}
function fireMoveEvent(treeNode,draggedNodeID,droppedOnNodeID) {
if (treeNode.gotMoveEventListeners()) {
for(var i=0;i<treeNode.moveeventlisteners.length;i++) {
eval(treeNode.moveeventlisteners[i] + '(' + draggedNodeID + ',' + droppedOnNodeID + ');');
}
}
}
function blurSelection() {
if (selectedNode != null) {
var oldNodeTitle = document.getElementById('title' + selectedNode);
oldNodeTitle.className = 'treetitleselectedblured';
}
}
function focusSelection() {
if (selectedNode != null) {
var oldNodeTitle = document.getElementById('title' + selectedNode);
oldNodeTitle.className = 'treetitleselectedfocused';
}
}
function getCookieVal (offset) {
var endstr = document.cookie.indexOf (";",offset);
if (endstr == -1) {
endstr = document.cookie.length;
}
return unescape(document.cookie.substring(offset,endstr));
}
function getCookie (name) {
var arg = name + "=";
var alen = arg.length;
var clen = document.cookie.length;
var i = 0;
while (i < clen) {
var j = i + alen;
if (document.cookie.substring(i, j) == arg) {
return getCookieVal(j);
}
i = document.cookie.indexOf(" ", i) + 1;
if (i == 0) {
break;
}
}
return null;
}
function setCookie (name, value) {
var argv = setCookie.arguments;
var argc = setCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;
var path = (argc > 3) ? argv[3] : null;
var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
document.cookie = name + "=" + escape (value) + ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + ((path == null) ? "" : ("; path=" + path)) + ((domain == null) ? "" : ("; domain=" + domain)) + ((secure == true) ? "; secure" : "");
}
function expandNode() {
var state = getState(selectedNode);
if (state == 'open') {
var currentTreeNode = getTreeNode(selectedNode);
if (currentTreeNode.hasChilds()) {
selectNode(currentTreeNode.childs[0].getID());
}
}
else {
handleNode(selectedNode);
}
}
function subtractNode() {
var state = getState(selectedNode);
if (state == 'closed') {
var currentTreeNode = getTreeNode(selectedNode);
var parent = currentTreeNode.getParent();
if (parent != null && parent != rootNode) {
selectNode(parent.getID());
}
}
else {
handleNode(selectedNode);
}
}
function selectPrevNode() {
var currentTreeNode = getTreeNode(selectedNode);
if (currentTreeNode.prevSibling != null) {
var state = getState(currentTreeNode.prevSibling.getID());
if (state == 'open' && currentTreeNode.prevSibling.hasChilds()) {
// We have to find the last open child of the previoussiblings childs.
var current = currentTreeNode.prevSibling.childs[currentTreeNode.prevSibling.childs.length - 1];
var currentstate = 'open';
while (current.hasChilds() && (getState(current.getID()) == 'open')) {
current = current.childs[current.childs.length - 1];
}
selectNode(current.getID());
}
else {
selectNode(currentTreeNode.prevSibling.getID());
}
}
else {
if (currentTreeNode.getParent() != null && currentTreeNode.getParent() != rootNode) {
selectNode(currentTreeNode.getParent().getID());
}
}
}
function selectNextNode() {
var currentTreeNode = getTreeNode(selectedNode);
var state = getState(selectedNode);
if (state == 'open' && currentTreeNode.hasChilds()) {
selectNode(currentTreeNode.childs[0].getID());
}
else {
if (currentTreeNode.nextSibling != null) {
selectNode(currentTreeNode.nextSibling.getID());
}
else {
// Continue up the tree until we either hit null, or a parent which have a child.
var parent = currentTreeNode;
while ((parent = parent.getParent()) != rootNode) {
if (parent.nextSibling != null) {
selectNode(parent.nextSibling.getID());
break;
}
}
/*
if (currentTreeNode.getParent().nextSibling != null) {
selectNode(currentTreeNode.getParent().nextSibling.getID());
}
*/
}
}
}
function keyDown(event) {
if (window.event) {
event = window.event;
}
if (event.keyCode == 38) { // Up
selectPrevNode();
return false;
}
else if (event.keyCode == 40) { // Down
selectNextNode();
return false;
}
else if (event.keyCode == 37) { // left
subtractNode();
return false;
}
else if (event.keyCode == 39) { // right
expandNode();
return false;
}
}
document.onkeydown = keyDown;
</script>
<script type="text/javascript" language="JavaScript">
showRootNode = false;
sortNodes = false;
dragable = false;
/**
* Needed to initialize the tree.
* And to call showTree(imagePath); to actually show the tree.
* Alternatively this can be done in a script block at the bottom of the page.
* Though this method is somewhat cleaner.
*/
function init() {
container = document.getElementById('examplediv');
showTree('');
}
/**
* Called when a user clicks on a node.
* @param treeNode the TreeNode object which have been clicked.
*/
function standardClick(treeNode) {
var mytext = document.getElementById('mytext');
var param = treeNode.getParam();
mytext.innerHTML = (param == '') ? treeNode.getName() : param;
}
function nodeEdited(treeNode) {
}
var closedGif = 'nanoImages/folder_closed.gif';
var openGif = 'nanoImages/folder_open.gif';
var pageIcon = 'nanoImages/page16x16.gif';
var userIcon = 'nanoImages/user_16x16.gif';
var helpIcon = 'nanoImages/help_16x16.gif';
rootNode = new TreeNode(1,'RootNode');
var node1 = new TreeNode(2,'subpage 1',helpIcon,'<P>This treenode can be renamed (Try to click onnce more on the node).<br>(You have to handle the renaming itself in a function though, since this is implementation specific. ie: Go down in a database and change the titel of a page).<br>A good example would be to open a PHP script to do the renaming, this can for example be done by setting location.href on a hidden iframe, or by setting the src attribute on a script element.</P>');
node1.setEditable(true);
node1.addEditEventListener('nodeEdited');
var node2 = new TreeNode(3,'subpage 2',new Array(closedGif,openGif));
var node2a = new TreeNode(4,'1st subpage to Node 2',new Array(closedGif,openGif));
var node2aa = new TreeNode(5,'subpage to subpage of Node2',new Array(closedGif,openGif));
var node2aaa = new TreeNode(6,'Some child',pageIcon);
var node2aab = new TreeNode(7,'Some child',pageIcon);
var node2aac = new TreeNode(8,'Some child',pageIcon);
node2aa.addChild(node2aaa);
node2aa.addChild(node2aab);
node2aa.addChild(node2aac);
node2a.addChild(node2aa);
var node2b = new TreeNode(9,'2nd subpage to Node 2',pageIcon);
var node2c = new TreeNode(10,'3rd subpageto Node 2',pageIcon);
node2.addChild(node2a);
node2.addChild(node2b);
node2.addChild(node2c);
var node3 = new TreeNode(11,'subpage 3',new Array(closedGif,openGif));
var node3a = new TreeNode(12,'Yet another child',pageIcon);
node3.addChild(node3a);
var node4 = new TreeNode(13,'subpage 4',userIcon);
// rootNode.addChild(node1);
rootNode.addChild(node2);
rootNode.addChild(node3);
// rootNode.addChild(node4);
</script>
<style type="text/css">
div,p,a {
font-family: Verdana,Arial;
font-size: 11px;
}
#exampletable {
width: 100%;
height: 100%;
}
#examplediv {
width: 250px;
height: 100%;
overflow: auto;
}
.explanation {
font-weight: bold;
font-style: italic;
}
</style>
</head>
<body OnLoad="init();">
<table id="exampletable">
<tr>
<td valign="top" style="width: 250px;">
<div id="examplediv"></div>
</td>
<td valign="top">
<div style="background-color:#EEE;border-style:dashed;border-color:#000000;border-width:1px;padding:5px;">
<div style="font-weight: bold;">NanoTree.</div>
<div id="mytext">
<p>NanoTree is a JavaScript tree, published under the <a href="http://www.gnu.org/copyleft/lesser.html">LGPL License</a>, which is developed to work in (at least) Internet Explorer and Mozilla<br>
<p style="font-style:italic;">CopyRight Martin Mouritzen</p>
</div>
</div>
<br>
</td>
</tr>
</table>
</body></html>
nanotree.zip( 15 k)Related examples in the same category