/** * @version $Id: tree.js 81 2009-06-05 16:31:31Z happynoodleboy $ * @package JCE * @copyright Copyright (C) 2005 - 2009 Ryan Demmer. All rights reserved. * @author Ryan Demmer * @license GNU/GPL * JCE is free software. This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses. */ /* Class: Tree Note: The Sortables require an XHTML doctype. Arguments: container - the container element options - an Object, see options below. Options: rootName - the root name. Defaults to 'Root' rootClass - the root node class. Defaults to 'root' collapseTree - collapse all other tree nodes on the same level when one is opened. Defaults to false. useLink - Use the link href Events: onNodeToggle - function executed when a node is toggled onNodeClick - function executed when a node is clicked onNodeLoad - function executed when a node is loaded onNodeCreate - function executed when a node is created */ var Tree = new Class({ getOptions : function(){ return { rootName: 'Root', rootClass: 'root', loaderClass: 'load', collapseTree: false, charLength: false, onInit: Class.empty, onNodeClick: Class.empty, onNodeLoad: Class.empty, onNodeCreate: Class.empty }; }, initialize : function(container, options){ this.setOptions(this.getOptions(), options); this.container = $(container); this.fireEvent('onInit', function(){ this.nodeEvents(); }.bind(this)); return this; }, nodeEvents : function(parent){ if(!parent){ parent = this.container; } $ES('div.tree-row', parent).each(function(el){ el.addEvent('mouseover', function(){ el.addClass('hover'); }) el.addEvent('mouseout', function(){ el.removeClass('hover'); }) }); $ES('div.tree-image', parent).each(function(el){ var p = this.findParent(el); el.addEvent('click', function(e){ this.toggleNode(e, p); }.bind(this)) if(this.getNode(p)){ el.addClass('open'); } }.bind(this)); $ES('span', this.container).each(function(el){ if(window.ie){ el.onselectstart = function(){ return false; } } if(window.gecko){ el.setStyle('moz-user-select', 'none'); } if(this.getNode(el.getParent())){ el.addClass('open'); } }.bind(this)); $ES('a', this.container).each(function(el){ var p = this.findParent(el); el.addEvent('click', function(e){ this.fireEvent('onNodeClick', [e, p]); }.bind(this)) }.bind(this)); }, /** * Does a parent (ul) have childnodes * @param {String} The parent * @return {Boolean}. */ hasNodes : function(parent){ if($type(parent) == 'string'){ parent = this.findParent(parent); } var c = parent.childNodes; return c.length > 1 || (c.length == 1 && c[0].className != 'spacer'); }, /** * Does the node exist? * @param {String} The node title * @param {String or Element} The parent node * @return {Boolean}. */ isNode : function(id, parent){ return this.findNode(id, parent) ? true : false; }, /** * Does a parent have subnodes? * @param {String or Element} The parent node * @return {Boolean}. */ getNode : function(parent){ if($type(parent) == 'string'){ parent = this.findParent(parent); } return $E('ul.tree-node', parent); }, /** * Reset all nodes. Set to closed */ resetNodes : function(){ $ES('span', this.container).each(function(el){ el.removeClass('open'); }); $ES('div.tree-image', this.container).each(function(el){ el.removeClass('open'); }); }, /** * Rename a node * @param {String} The node title * @param {String} The new title */ renameNode : function(id, name){ var parent = string.dirname(id); var node = this.findNode(id, parent); // Rename the node node.setProperty('id', name); // Rename the span $E('a', node).setHTML(string.basename(name)); // Rename each of the child nodes $ES('li[id^='+ this._escape(encodeURI(id)) +']', node).each(function(n){ var nt = n.getProperty('id'); n.setProperty('id', nt.replace(id, name)); }); }, /** * Remove a node * @param {String} The node title */ removeNode : function(id){ var parent = string.dirname(id); var node = this.findNode(id, parent); var ul = node.getParent(); // Remove the node node.remove(); // Remove it if it is now empty if(ul && !this.hasNodes(ul)){ ul.remove(); } }, /** * Create a node