Nano Tree : Tree : GUI Components JAVASCRIPT DHTML TUTORIALS


JAVASCRIPT DHTML TUTORIALS » GUI Components » Tree »

 

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 ? -: 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 == -|| order2 == -1) {
          return a.getName().toLowerCase() > b.getName().toLowerCase() : -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;
          }
          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[ithis.childs[i + 1];
      }
      if (this.childs[i== childNode) {
        if (i == (this.childs.length - 1)) {
          this.childs[inull;
        }
        else {
          this.childs[ithis.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[inew 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.lengthnew 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;">&nbsp;' + 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 += '&nbsp;<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(" ", i1;
    if (i == 0) {
      break;
    }
  }
  return null;
}
function setCookie (name, value) {  
  var argv = setCookie.arguments;  
  var argc = setCookie.arguments.length;  
  var expires = (argc > 2? argv[2null;  
  var path = (argc > 3? argv[3null;  
  var domain = (argc > 4? argv[4null;  
  var secure = (argc > 5? argv[5false;  
  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 leastInternet Explorer and Mozilla<br>
        <p style="font-style:italic;">CopyRight Martin Mouritzen</p>
        </div>
      </div>
      <br>
    </td>
  </tr>
</table>
</body></html>

           
       

Download : Download nav_nanotree.zip nav_nanotree.zip


-

Leave a Comment / Note


 
Verification is used to prevent unwanted posts (spam). .

Follow Navioo On Twitter

JAVASCRIPT DHTML TUTORIALS

 Navioo GUI Components
» Tree