/**
* @fileoverview
* Dynamic Folder Tree
* Generates DHTML tree dynamically (on the fly).
* License: BSD.
* See details at http://www.opensource.org/licenses/bsd-license.php
*
* Copyright (c) 2004, 2005, 2006, 2008
* Vinicius Cubas Brand, Raphael Derosso Pereira, Frank Alcantara, Benoît VAN BOGAERT (as Macq Electronique sub-contractor)
* {viniciuscb,raphaelpereira,frankalcantara, bvanbogaert} at users.sourceforge.net
* All rights reserved.
*/
/**
* Creates the default dFTree layout.
* It is responsible to create and maintain HTML objects.
* @private
*/
function dFTreeDefaultLayout(arrayProps) {
// Mandatory fields
/**
* Control the behaviour of the tree.
* If true and when a node is opened, the other node's brothers are closed.
* This field is mandatory.
* @type boolean
* @public
*/
this.closeBrothers = false;
// Optional fields
// Private fields
for (i in arrayProps)
{
if (i.charAt(0) != '_')
{
eval('this.'+i+' = arrayProps[\''+i+'\'];');
}
}
}
/**
* Insert in the document the HTML code for the root of the tree
* @param {dFTree} tree The reference tree
* @private
*/
dFTreeDefaultLayout.prototype._draw_tree = function(tree) {
if (!getObjectById("dftree_"+tree.name))
{
document.write('
');
}
}
/**
* Compute the rowIndex interval in the tree table related to the children's of the given node.
* @param {dNode} node The reference node
* @return an object representing the row index interval of the given node children
* Attribute interval.startIndex is the row Index of the first child
* Attribute interval.count is the count of rows (including the children of children)
* @private
*/
dFTreeDefaultLayout.prototype._get_children_interval = function(node) {
var startIndex = 0;
var endIndex = 0;
var nodeRow = getObjectById("n"+node.id);
if (nodeRow) {
startIndex = nodeRow.rowIndex + 1;
var table = nodeRow.parentNode.parentNode;
if (table) {
endIndex = table.rows.length;
var parent = node;
var quit = false;
while (!quit && parent)
{
var list = null;
if (parent._parent) {
list = parent._parent._children;
} else {
list = node._myTree._roots;
}
// Search just following brother
var parentIndex = node._myTree._searchNodeIn(parent.id, list);
if (parentIndex < list.length - 1) {
var uncleRow = getObjectById("n"+list[parentIndex+1].id);
if (uncleRow) {
endIndex = uncleRow.rowIndex;
quit = true;
}
}
parent = parent._parent;
}
}
}
return { startIndex: startIndex, count:(endIndex - startIndex) };
}
/**
* Create the HTML objects to draw the given node
* @param {dNode} node The reference node
* @private
*/
dFTreeDefaultLayout.prototype._draw_node = function(node)
{
var str;
var div;
var myPlus = node._properPlus();
var myIcon = node._properIcon();
var myPlusOnClick = node._myTree.name+'.getNodeById(\''+node.id+'\').changeState();';
var captionOnClickEvent = "";
var plusEventHandler = function(){
eval(myPlusOnClick);
}
var captionEventHandler = function(){
eval(captionOnClickEvent);
}
//FIXME put node in a separate function, as node will be necessary in
//various parts
captionOnClickEvent = node._myTree.name+'.getNodeById(\''+node.id+'\')._select(); ';
if (node.onClick) //FIXME when onclick && url
{
captionOnClickEvent += node.onClick;
}
else if (node.url && node.target)
{
captionOnClickEvent += 'window.open(\''+node.url+'\',\''+node.target+'\')';
}
else if (node.url)
{
captionOnClickEvent += 'window.location=\''+node.url+'\'';
}
var table = getObjectById("dftree_"+node._myTree.name);
if (table) {
var rowIndex = table.rows.length; // Row index where to insert the node
var is_shown = true;
if (node._parent != null) {
var interval = this._get_children_interval(node._parent);
rowIndex = interval.startIndex + interval.count;
is_shown = node._parent._io;
}
// Compute current node level,
var level = node._get_level();
// Possibly adjust the colspan for other nodes
if (typeof(node._myTree._levelMax) == "undefined") {
node._myTree._levelMax = level;
} else if (node._myTree._levelMax < level) {
node._myTree._levelMax = level;
}
var objN = table.insertRow(rowIndex);
objN.id = 'n'+node.id;
objN.className = 'son';
if (!is_shown) {
objN.style.display = "none";
}
for(i=0; i 0) {
i--;
if (parent != null) {
this._update_vertical_lines(parent, row.cells[i]);
parent = parent._parent;
}
}
}
/**
* Set the background of the given object objV
* No vertical line is displayed if the given node is the last child of its generation
* @param {dNode} node The reference node
* @param {obj} objV The HTML object to update
* @private
*/
dFTreeDefaultLayout.prototype._update_vertical_lines = function(node, objV)
{
// Update the vertical lines to connect the childrens
var last = node._is_last();
if (node._myTree.useIcons && !last) {
objV.style.background = "transparent url("+node._myTree.icons.line+") repeat-y scroll left top";
}
else
{
objV.style.background = "";
}
}
/**
* Change attributes of the selected node
* @param {dNode} node The reference node
* @private
*/
dFTreeDefaultLayout.prototype._select_node = function(node)
{
var objL;
objL = getObjectById("l"+node.id);
//changes class to selected link
if (objL)
{
objL.className = 'sl';
}
}
/**
* Restore the attributes of a previously selected node
* @param {dNode} node The reference node
* @private
*/
dFTreeDefaultLayout.prototype._unselect_node = function(node)
{
var objL = getObjectById("l"+node.id);
//changes class to selected link
if (objL)
{
objL.className = node.captionClass;
}
}
/**
* Remove the HTML objects related to the given node
* @param {dNode} node The reference node
* @private
*/
dFTreeDefaultLayout.prototype._erase_node = function(node)
{
var objN = getObjectById("n"+node.id);
if (objN)
{
var table = objN.parentNode.parentNode;
table.deleteRow(objN.rowIndex);
}
}
/**
* Adjust the colSpan attribute taking into account the visible cells.
* If colSpan is overestimated regarding the visible cells, some browser
* (namely IE) give some strange results
* @param {obj} table The HTML table
* @param {dFTree} tree The reference tree
* @private
*/
dFTreeDefaultLayout.prototype._clean_table = function(table, tree) {
// Determine the visible column number
var cols = 0;
for (i=0; i 0)
{
this._getCookie();
this._drawBranch(this._roots);
}
}
/**
* Recursive function, draws children
* @param {array} childrenArray List of children
* @private
*/
dFTree.prototype._drawBranch = function(childrenArray) {
var a=0;
for (a;a 1)
{
var n = node._parent._children[node._parent._children.length - 2];
if (n._drawn) n._refresh();
}
}
}
}
}
}
/**
* Remove a node
* @param {dNode} node Node to remove
*/
dFTree.prototype.remove = function(node) {
var childPos;
if (typeof (childPos = this._searchNode(node.id)) != "number")
{
alert("Node '"+node.id+" not found in "+this.name);
}
else
{
// Remove the children
for (i=node._children.length - 1; i>=0; i--) {
if (typeof(node._children[i]) == "object") {
this.remove(node._children[i]);
}
}
node._erase();
var parent = node._parent;
var list = null;
if (parent === null)
{
list = this._roots;
}
else // if (parent !== null)
{
list = parent._children;
}
if (list !== null) {
var auxPos = this._searchNodeIn(node.id, list);
if (typeof(auxPos) == "number")
{
list.splice(auxPos, 1);
}
}
node._parent = null;
this._aNodes.splice(childPos, 1);
if (parent !== null)
{
parent._refresh();
if (parent._children.length >= 1) parent._children[parent._children.length - 1]._refresh();
}
}
}
/**
* Modify the properties of a node
* @param {array} arrayProps The same properties list of dNode. It must contain the property .ID to retrieve the node in the tree.
*/
dFTree.prototype.alter = function(arrayProps) {
if (arrayProps['id'])
{
this.getNodeById(arrayProps['id']).alter(arrayProps);
}
}
/**
* Get a node by its identification
* @return The found dNode object
* @param {string} nodeid The node identification to retrieve
*/
dFTree.prototype.getNodeById = function(nodeid) {
return this._aNodes[this._searchNode(nodeid)];
}
/**
* Searches for a node in the node array.
* @return The position in the array 4it
* @param {string} id The node identification to retrieve
* @private
*/
dFTree.prototype._searchNode = function(id) {
return this._searchNodeIn(id, this._aNodes);
}
/**
* Searches for a node in given array, returning the position of the array 4it
* @return The position in the array 4it
* @param {string} id The node identification to retrieve
* @private
*/
dFTree.prototype._searchNodeIn = function(id, list) {
var a=0;
for (a;a";
}
var global_ie = is_ie();
function is_ie() {
var ua = window.navigator.userAgent.toLowerCase();
if ((ua.indexOf('msie')) != -1) {
return true;
} else {
return false;
}
}