X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/c930e9176a5a85509c5b0230e2bff5c22a591432..2e847cf21b8ab9d15fa167b315ca5b2fa92638fc:/pkgs/pkg-tree-debug.js diff --git a/pkgs/pkg-tree-debug.js b/pkgs/pkg-tree-debug.js index 848afea5..639fb788 100644 --- a/pkgs/pkg-tree-debug.js +++ b/pkgs/pkg-tree-debug.js @@ -1,6 +1,6 @@ /*! - * Ext JS Library 3.0.0 - * Copyright(c) 2006-2009 Ext JS, LLC + * Ext JS Library 3.1.1 + * Copyright(c) 2006-2010 Ext JS, LLC * licensing@extjs.com * http://www.extjs.com/license */ @@ -118,11 +118,19 @@ new Ext.Viewport({ */ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { rootVisible : true, - animate: Ext.enableFx, + animate : Ext.enableFx, lines : true, enableDD : false, hlDrop : Ext.enableFx, - pathSeparator: "/", + pathSeparator : '/', + + /** + * @cfg {Array} bubbleEvents + *
An array of events that, when fired, should be bubbled to any parent container. + * See {@link Ext.util.Observable#enableBubble}. + * Defaults to []. + */ + bubbleEvents : [], initComponent : function(){ Ext.tree.TreePanel.superclass.initComponent.call(this); @@ -138,7 +146,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { dataUrl: this.dataUrl, requestMethod: this.requestMethod }); - }else if(typeof l == 'object' && !l.load){ + }else if(Ext.isObject(l) && !l.load){ l = new Ext.tree.TreeLoader(l); } this.loader = l; @@ -167,7 +175,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {Node} node The newly appended node * @param {Number} index The index of the newly appended node */ - "append", + 'append', /** * @event remove * Fires when a child node is removed from a node in this tree. @@ -175,7 +183,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {Node} parent The parent node * @param {Node} node The child node removed */ - "remove", + 'remove', /** * @event movenode * Fires when a node is moved to a new location in the tree @@ -185,7 +193,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {Node} newParent The new parent of this node * @param {Number} index The index it was moved to */ - "movenode", + 'movenode', /** * @event insert * Fires when a new child node is inserted in a node in this tree. @@ -194,7 +202,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {Node} node The child node inserted * @param {Node} refNode The child node the node was inserted before */ - "insert", + 'insert', /** * @event beforeappend * Fires before a new child is appended to a node in this tree, return false to cancel the append. @@ -202,7 +210,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {Node} parent The parent node * @param {Node} node The child node to be appended */ - "beforeappend", + 'beforeappend', /** * @event beforeremove * Fires before a child is removed from a node in this tree, return false to cancel the remove. @@ -210,7 +218,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {Node} parent The parent node * @param {Node} node The child node to be removed */ - "beforeremove", + 'beforeremove', /** * @event beforemovenode * Fires before a node is moved to a new location in the tree. Return false to cancel the move. @@ -220,7 +228,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {Node} newParent The new parent the node is moving to * @param {Number} index The index it is being moved to */ - "beforemovenode", + 'beforemovenode', /** * @event beforeinsert * Fires before a new child is inserted in a node in this tree, return false to cancel the insert. @@ -229,20 +237,20 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {Node} node The child node to be inserted * @param {Node} refNode The child node the node is being inserted before */ - "beforeinsert", + 'beforeinsert', /** * @event beforeload * Fires before a node is loaded, return false to cancel * @param {Node} node The node being loaded */ - "beforeload", + 'beforeload', /** * @event load * Fires when a node is loaded * @param {Node} node The node that was loaded */ - "load", + 'load', /** * @event textchange * Fires when the text for a node is changed @@ -250,7 +258,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {String} text The new text * @param {String} oldText The old text */ - "textchange", + 'textchange', /** * @event beforeexpandnode * Fires before a node is expanded, return false to cancel. @@ -258,7 +266,7 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {Boolean} deep * @param {Boolean} anim */ - "beforeexpandnode", + 'beforeexpandnode', /** * @event beforecollapsenode * Fires before a node is collapsed, return false to cancel. @@ -266,54 +274,75 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { * @param {Boolean} deep * @param {Boolean} anim */ - "beforecollapsenode", + 'beforecollapsenode', /** * @event expandnode * Fires when a node is expanded * @param {Node} node The node */ - "expandnode", + 'expandnode', /** * @event disabledchange * Fires when the disabled status of a node changes * @param {Node} node The node * @param {Boolean} disabled */ - "disabledchange", + 'disabledchange', /** * @event collapsenode * Fires when a node is collapsed * @param {Node} node The node */ - "collapsenode", + 'collapsenode', /** * @event beforeclick * Fires before click processing on a node. Return false to cancel the default action. * @param {Node} node The node * @param {Ext.EventObject} e The event object */ - "beforeclick", + 'beforeclick', /** * @event click * Fires when a node is clicked * @param {Node} node The node * @param {Ext.EventObject} e The event object */ - "click", + 'click', + /** + * @event containerclick + * Fires when the tree container is clicked + * @param {Tree} this + * @param {Ext.EventObject} e The event object + */ + 'containerclick', /** * @event checkchange * Fires when a node with a checkbox's checked property changes * @param {Node} this This node * @param {Boolean} checked */ - "checkchange", + 'checkchange', + /** + * @event beforedblclick + * Fires before double click processing on a node. Return false to cancel the default action. + * @param {Node} node The node + * @param {Ext.EventObject} e The event object + */ + 'beforedblclick', /** * @event dblclick * Fires when a node is double clicked * @param {Node} node The node * @param {Ext.EventObject} e The event object */ - "dblclick", + 'dblclick', + /** + * @event containerdblclick + * Fires when the tree container is double clicked + * @param {Tree} this + * @param {Ext.EventObject} e The event object + */ + 'containerdblclick', /** * @event contextmenu * Fires when a node is right clicked. To display a context menu in response to this @@ -361,13 +390,20 @@ new Ext.tree.TreePanel({ * @param {Node} node The node * @param {Ext.EventObject} e The event object */ - "contextmenu", + 'contextmenu', + /** + * @event containercontextmenu + * Fires when the tree container is right clicked + * @param {Tree} this + * @param {Ext.EventObject} e The event object + */ + 'containercontextmenu', /** * @event beforechildrenrendered * Fires right before the child nodes for a node are rendered * @param {Node} node The node */ - "beforechildrenrendered", + 'beforechildrenrendered', /** * @event startdrag * Fires when a node starts being dragged @@ -375,7 +411,7 @@ new Ext.tree.TreePanel({ * @param {Ext.tree.TreeNode} node * @param {event} e The raw browser event */ - "startdrag", + 'startdrag', /** * @event enddrag * Fires when a drag operation is complete @@ -383,7 +419,7 @@ new Ext.tree.TreePanel({ * @param {Ext.tree.TreeNode} node * @param {event} e The raw browser event */ - "enddrag", + 'enddrag', /** * @event dragdrop * Fires when a dragged node is dropped on a valid DD target @@ -392,7 +428,7 @@ new Ext.tree.TreePanel({ * @param {DD} dd The dd it was dropped on * @param {event} e The raw browser event */ - "dragdrop", + 'dragdrop', /** * @event beforenodedrop * Fires when a DD object is dropped on a node in this tree for preprocessing. Return false to cancel the drop. The dropEvent @@ -408,11 +444,11 @@ new Ext.tree.TreePanel({ * to be inserted by setting them on this object. *
this
reference) in which the function is executed. Defaults to the current Node.
+ * @param {Array} args (optional) The args to call the function with (default to passing the current Node)
*/
bubble : function(fn, scope, args){
var p = this;
@@ -2042,13 +2149,12 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
},
/**
- * Cascades down the tree from this node, calling the specified function with each node. The scope (this) of
- * function call will be the scope provided or the current node. The arguments to the function
+ * Cascades down the tree from this node, calling the specified function with each node. The arguments to the function
* will be the args provided or the current node. If the function returns false at any point,
* the cascade is stopped on that branch.
* @param {Function} fn The function to call
- * @param {Object} scope (optional) The scope of the function (defaults to current node)
- * @param {Array} args (optional) The args to call the function with (default to passing the current node)
+ * @param {Object} scope (optional) The scope (this
reference) in which the function is executed. Defaults to the current Node.
+ * @param {Array} args (optional) The args to call the function with (default to passing the current Node)
*/
cascade : function(fn, scope, args){
if(fn.apply(scope || this, args || [this]) !== false){
@@ -2060,13 +2166,12 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
},
/**
- * Interates the child nodes of this node, calling the specified function with each node. The scope (this) of
- * function call will be the scope provided or the current node. The arguments to the function
+ * Interates the child nodes of this node, calling the specified function with each node. The arguments to the function
* will be the args provided or the current node. If the function returns false at any point,
* the iteration stops.
* @param {Function} fn The function to call
- * @param {Object} scope (optional) The scope of the function (defaults to current node)
- * @param {Array} args (optional) The args to call the function with (default to passing the current node)
+ * @param {Object} scope (optional) The scope (this
reference) in which the function is executed. Defaults to the current Node in the iteration.
+ * @param {Array} args (optional) The args to call the function with (default to passing the current Node)
*/
eachChild : function(fn, scope, args){
var cs = this.childNodes;
@@ -2094,10 +2199,9 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
},
/**
- * Finds the first child by a custom function. The child matches if the function passed
- * returns true.
- * @param {Function} fn
- * @param {Object} scope (optional)
+ * Finds the first child by a custom function. The child matches if the function passed returns true
.
+ * @param {Function} fn A function which must return true
if the passed Node is the required Node.
+ * @param {Object} scope (optional) The scope (this
reference) in which the function is executed. Defaults to the Node being tested.
* @return {Node} The found child or null if none was found
*/
findChildBy : function(fn, scope){
@@ -2111,9 +2215,9 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
},
/**
- * Sorts this nodes children using the supplied sort function
- * @param {Function} fn
- * @param {Object} scope (optional)
+ * Sorts this nodes children using the supplied sort function.
+ * @param {Function} fn A function which, when passed two Nodes, returns -1, 0 or 1 depending upon required sort order.
+ * @param {Object} scope (optional)The scope (this
reference) in which the function is executed. Defaults to the browser window.
*/
sort : function(fn, scope){
var cs = this.childNodes;
@@ -2163,545 +2267,571 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
toString : function(){
return "[Node"+(this.id?" "+this.id:"")+"]";
}
-});/**
- * @class Ext.tree.TreeNode
- * @extends Ext.data.Node
- * @cfg {String} text The text for this node
- * @cfg {Boolean} expanded true to start the node expanded
- * @cfg {Boolean} allowDrag False to make this node undraggable if {@link #draggable} = true (defaults to true)
- * @cfg {Boolean} allowDrop False if this node cannot have child nodes dropped on it (defaults to true)
- * @cfg {Boolean} disabled true to start the node disabled
- * @cfg {String} icon The path to an icon for the node. The preferred way to do this
- * is to use the cls or iconCls attributes and add the icon via a CSS background image.
- * @cfg {String} cls A css class to be added to the node
- * @cfg {String} iconCls A css class to be added to the nodes icon element for applying css background images
- * @cfg {String} href URL of the link used for the node (defaults to #)
- * @cfg {String} hrefTarget target frame for the link
- * @cfg {Boolean} hidden True to render hidden. (Defaults to false).
- * @cfg {String} qtip An Ext QuickTip for the node
- * @cfg {Boolean} expandable If set to true, the node will always show a plus/minus icon, even when empty
- * @cfg {String} qtipCfg An Ext QuickTip config for the node (used instead of qtip)
- * @cfg {Boolean} singleClickExpand True for single click expand on this node
- * @cfg {Function} uiProvider A UI class to use for this node (defaults to Ext.tree.TreeNodeUI)
- * @cfg {Boolean} checked True to render a checked checkbox for this node, false to render an unchecked checkbox
- * (defaults to undefined with no checkbox rendered)
- * @cfg {Boolean} draggable True to make this node draggable (defaults to false)
- * @cfg {Boolean} isTarget False to not allow this node to act as a drop target (defaults to true)
- * @cfg {Boolean} allowChildren False to not allow this node to have child nodes (defaults to true)
- * @cfg {Boolean} editable False to not allow this node to be edited by an (@link Ext.tree.TreeEditor} (defaults to true)
- * @constructor
- * @param {Object/String} attributes The attributes/config for the node or just a string with the text for the node
- */
-Ext.tree.TreeNode = function(attributes){
- attributes = attributes || {};
- if(typeof attributes == "string"){
- attributes = {text: attributes};
- }
- this.childrenRendered = false;
- this.rendered = false;
- Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
- this.expanded = attributes.expanded === true;
- this.isTarget = attributes.isTarget !== false;
- this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
- this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
-
- /**
- * Read-only. The text for this node. To change it use setText().
- * @type String
- */
- this.text = attributes.text;
- /**
- * True if this node is disabled.
- * @type Boolean
- */
- this.disabled = attributes.disabled === true;
- /**
- * True if this node is hidden.
- * @type Boolean
- */
- this.hidden = attributes.hidden === true;
-
- this.addEvents(
- /**
- * @event textchange
- * Fires when the text for this node is changed
- * @param {Node} this This node
- * @param {String} text The new text
- * @param {String} oldText The old text
- */
- "textchange",
- /**
- * @event beforeexpand
- * Fires before this node is expanded, return false to cancel.
- * @param {Node} this This node
- * @param {Boolean} deep
- * @param {Boolean} anim
- */
- "beforeexpand",
- /**
- * @event beforecollapse
- * Fires before this node is collapsed, return false to cancel.
- * @param {Node} this This node
- * @param {Boolean} deep
- * @param {Boolean} anim
- */
- "beforecollapse",
- /**
- * @event expand
- * Fires when this node is expanded
- * @param {Node} this This node
- */
- "expand",
- /**
- * @event disabledchange
- * Fires when the disabled status of this node changes
- * @param {Node} this This node
- * @param {Boolean} disabled
- */
- "disabledchange",
- /**
- * @event collapse
- * Fires when this node is collapsed
- * @param {Node} this This node
- */
- "collapse",
- /**
- * @event beforeclick
- * Fires before click processing. Return false to cancel the default action.
- * @param {Node} this This node
- * @param {Ext.EventObject} e The event object
- */
- "beforeclick",
- /**
- * @event click
- * Fires when this node is clicked
- * @param {Node} this This node
- * @param {Ext.EventObject} e The event object
- */
- "click",
- /**
- * @event checkchange
- * Fires when a node with a checkbox's checked property changes
- * @param {Node} this This node
- * @param {Boolean} checked
- */
- "checkchange",
- /**
- * @event dblclick
- * Fires when this node is double clicked
- * @param {Node} this This node
- * @param {Ext.EventObject} e The event object
- */
- "dblclick",
- /**
- * @event contextmenu
- * Fires when this node is right clicked
- * @param {Node} this This node
- * @param {Ext.EventObject} e The event object
- */
- "contextmenu",
- /**
- * @event beforechildrenrendered
- * Fires right before the child nodes for this node are rendered
- * @param {Node} this This node
- */
- "beforechildrenrendered"
- );
-
- var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
-
- /**
- * Read-only. The UI for this node
- * @type TreeNodeUI
- */
- this.ui = new uiClass(this);
-};
-Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
- preventHScroll: true,
- /**
- * Returns true if this node is expanded
- * @return {Boolean}
- */
- isExpanded : function(){
- return this.expanded;
- },
-
-/**
- * Returns the UI object for this node.
- * @return {TreeNodeUI} The object which is providing the user interface for this tree
- * node. Unless otherwise specified in the {@link #uiProvider}, this will be an instance
- * of {@link Ext.tree.TreeNodeUI}
- */
- getUI : function(){
- return this.ui;
- },
-
- getLoader : function(){
- var owner;
- return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : new Ext.tree.TreeLoader());
- },
-
- // private override
- setFirstChild : function(node){
- var of = this.firstChild;
- Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
- if(this.childrenRendered && of && node != of){
- of.renderIndent(true, true);
- }
- if(this.rendered){
- this.renderIndent(true, true);
- }
- },
-
- // private override
- setLastChild : function(node){
- var ol = this.lastChild;
- Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
- if(this.childrenRendered && ol && node != ol){
- ol.renderIndent(true, true);
- }
- if(this.rendered){
- this.renderIndent(true, true);
- }
- },
-
- // these methods are overridden to provide lazy rendering support
- // private override
- appendChild : function(n){
- if(!n.render && !Ext.isArray(n)){
- n = this.getLoader().createNode(n);
- }
- var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
- if(node && this.childrenRendered){
- node.render();
- }
- this.ui.updateExpandIcon();
- return node;
- },
-
- // private override
- removeChild : function(node){
- this.ownerTree.getSelectionModel().unselect(node);
- Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
- // if it's been rendered remove dom node
- if(this.childrenRendered){
- node.ui.remove();
- }
- if(this.childNodes.length < 1){
- this.collapse(false, false);
- }else{
- this.ui.updateExpandIcon();
- }
- if(!this.firstChild && !this.isHiddenRoot()) {
- this.childrenRendered = false;
- }
- return node;
- },
-
- // private override
- insertBefore : function(node, refNode){
- if(!node.render){
- node = this.getLoader().createNode(node);
- }
- var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
- if(newNode && refNode && this.childrenRendered){
- node.render();
- }
- this.ui.updateExpandIcon();
- return newNode;
- },
-
- /**
- * Sets the text for this node
- * @param {String} text
- */
- setText : function(text){
- var oldText = this.text;
- this.text = text;
- this.attributes.text = text;
- if(this.rendered){ // event without subscribing
- this.ui.onTextChange(this, text, oldText);
- }
- this.fireEvent("textchange", this, text, oldText);
- },
-
- /**
- * Triggers selection of this node
- */
- select : function(){
- this.getOwnerTree().getSelectionModel().select(this);
- },
-
- /**
- * Triggers deselection of this node
- */
- unselect : function(){
- this.getOwnerTree().getSelectionModel().unselect(this);
- },
-
- /**
- * Returns true if this node is selected
- * @return {Boolean}
- */
- isSelected : function(){
- return this.getOwnerTree().getSelectionModel().isSelected(this);
- },
-
- /**
- * Expand this node.
- * @param {Boolean} deep (optional) True to expand all children as well
- * @param {Boolean} anim (optional) false to cancel the default animation
- * @param {Function} callback (optional) A callback to be called when
- * expanding this node completes (does not wait for deep expand to complete).
- * Called with 1 parameter, this node.
- * @param {Object} scope (optional) The scope in which to execute the callback.
- */
- expand : function(deep, anim, callback, scope){
- if(!this.expanded){
- if(this.fireEvent("beforeexpand", this, deep, anim) === false){
- return;
- }
- if(!this.childrenRendered){
- this.renderChildren();
- }
- this.expanded = true;
- if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
- this.ui.animExpand(function(){
- this.fireEvent("expand", this);
- this.runCallback(callback, scope || this, [this]);
- if(deep === true){
- this.expandChildNodes(true);
- }
- }.createDelegate(this));
- return;
- }else{
- this.ui.expand();
- this.fireEvent("expand", this);
- this.runCallback(callback, scope || this, [this]);
- }
- }else{
- this.runCallback(callback, scope || this, [this]);
- }
- if(deep === true){
- this.expandChildNodes(true);
- }
- },
-
- runCallback: function(cb, scope, args){
- if(Ext.isFunction(cb)){
- cb.apply(scope, args);
- }
- },
-
- isHiddenRoot : function(){
- return this.isRoot && !this.getOwnerTree().rootVisible;
- },
-
- /**
- * Collapse this node.
- * @param {Boolean} deep (optional) True to collapse all children as well
- * @param {Boolean} anim (optional) false to cancel the default animation
- * @param {Function} callback (optional) A callback to be called when
- * expanding this node completes (does not wait for deep expand to complete).
- * Called with 1 parameter, this node.
- * @param {Object} scope (optional) The scope in which to execute the callback.
- */
- collapse : function(deep, anim, callback, scope){
- if(this.expanded && !this.isHiddenRoot()){
- if(this.fireEvent("beforecollapse", this, deep, anim) === false){
- return;
- }
- this.expanded = false;
- if((this.getOwnerTree().animate && anim !== false) || anim){
- this.ui.animCollapse(function(){
- this.fireEvent("collapse", this);
- this.runCallback(callback, scope || this, [this]);
- if(deep === true){
- this.collapseChildNodes(true);
- }
- }.createDelegate(this));
- return;
- }else{
- this.ui.collapse();
- this.fireEvent("collapse", this);
- this.runCallback(callback, scope || this, [this]);
- }
- }else if(!this.expanded){
- this.runCallback(callback, scope || this, [this]);
- }
- if(deep === true){
- var cs = this.childNodes;
- for(var i = 0, len = cs.length; i < len; i++) {
- cs[i].collapse(true, false);
- }
- }
- },
-
- // private
- delayedExpand : function(delay){
- if(!this.expandProcId){
- this.expandProcId = this.expand.defer(delay, this);
- }
- },
-
- // private
- cancelExpand : function(){
- if(this.expandProcId){
- clearTimeout(this.expandProcId);
- }
- this.expandProcId = false;
- },
-
- /**
- * Toggles expanded/collapsed state of the node
- */
- toggle : function(){
- if(this.expanded){
- this.collapse();
- }else{
- this.expand();
- }
- },
-
- /**
- * Ensures all parent nodes are expanded, and if necessary, scrolls
- * the node into view.
- * @param {Function} callback (optional) A function to call when the node has been made visible.
- * @param {Object} scope (optional) The scope in which to execute the callback.
- */
- ensureVisible : function(callback, scope){
- var tree = this.getOwnerTree();
- tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
- var node = tree.getNodeById(this.id); // Somehow if we don't do this, we lose changes that happened to node in the meantime
- tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
- this.runCallback(callback, scope || this, [this]);
- }.createDelegate(this));
- },
-
- /**
- * Expand all child nodes
- * @param {Boolean} deep (optional) true if the child nodes should also expand their child nodes
- */
- expandChildNodes : function(deep){
- var cs = this.childNodes;
- for(var i = 0, len = cs.length; i < len; i++) {
- cs[i].expand(deep);
- }
- },
-
- /**
- * Collapse all child nodes
- * @param {Boolean} deep (optional) true if the child nodes should also collapse their child nodes
- */
- collapseChildNodes : function(deep){
- var cs = this.childNodes;
- for(var i = 0, len = cs.length; i < len; i++) {
- cs[i].collapse(deep);
- }
- },
-
- /**
- * Disables this node
- */
- disable : function(){
- this.disabled = true;
- this.unselect();
- if(this.rendered && this.ui.onDisableChange){ // event without subscribing
- this.ui.onDisableChange(this, true);
- }
- this.fireEvent("disabledchange", this, true);
- },
-
- /**
- * Enables this node
- */
- enable : function(){
- this.disabled = false;
- if(this.rendered && this.ui.onDisableChange){ // event without subscribing
- this.ui.onDisableChange(this, false);
- }
- this.fireEvent("disabledchange", this, false);
- },
-
- // private
- renderChildren : function(suppressEvent){
- if(suppressEvent !== false){
- this.fireEvent("beforechildrenrendered", this);
- }
- var cs = this.childNodes;
- for(var i = 0, len = cs.length; i < len; i++){
- cs[i].render(true);
- }
- this.childrenRendered = true;
- },
-
- // private
- sort : function(fn, scope){
- Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
- if(this.childrenRendered){
- var cs = this.childNodes;
- for(var i = 0, len = cs.length; i < len; i++){
- cs[i].render(true);
- }
- }
- },
-
- // private
- render : function(bulkRender){
- this.ui.render(bulkRender);
- if(!this.rendered){
- // make sure it is registered
- this.getOwnerTree().registerNode(this);
- this.rendered = true;
- if(this.expanded){
- this.expanded = false;
- this.expand(false, false);
- }
- }
- },
-
- // private
- renderIndent : function(deep, refresh){
- if(refresh){
- this.ui.childIndent = null;
- }
- this.ui.renderIndent();
- if(deep === true && this.childrenRendered){
- var cs = this.childNodes;
- for(var i = 0, len = cs.length; i < len; i++){
- cs[i].renderIndent(true, refresh);
- }
- }
- },
-
- beginUpdate : function(){
- this.childrenRendered = false;
- },
-
- endUpdate : function(){
- if(this.expanded && this.rendered){
- this.renderChildren();
- }
- },
-
- destroy : function(){
- if(this.childNodes){
- for(var i = 0,l = this.childNodes.length; i < l; i++){
- this.childNodes[i].destroy();
- }
- this.childNodes = null;
- }
- if(this.ui.destroy){
- this.ui.destroy();
- }
- },
-
- // private
- onIdChange: function(id){
- this.ui.onIdChange(id);
- }
-});
-
+});/**
+ * @class Ext.tree.TreeNode
+ * @extends Ext.data.Node
+ * @cfg {String} text The text for this node
+ * @cfg {Boolean} expanded true to start the node expanded
+ * @cfg {Boolean} allowDrag False to make this node undraggable if {@link #draggable} = true (defaults to true)
+ * @cfg {Boolean} allowDrop False if this node cannot have child nodes dropped on it (defaults to true)
+ * @cfg {Boolean} disabled true to start the node disabled
+ * @cfg {String} icon The path to an icon for the node. The preferred way to do this
+ * is to use the cls or iconCls attributes and add the icon via a CSS background image.
+ * @cfg {String} cls A css class to be added to the node
+ * @cfg {String} iconCls A css class to be added to the nodes icon element for applying css background images
+ * @cfg {String} href URL of the link used for the node (defaults to #)
+ * @cfg {String} hrefTarget target frame for the link
+ * @cfg {Boolean} hidden True to render hidden. (Defaults to false).
+ * @cfg {String} qtip An Ext QuickTip for the node
+ * @cfg {Boolean} expandable If set to true, the node will always show a plus/minus icon, even when empty
+ * @cfg {String} qtipCfg An Ext QuickTip config for the node (used instead of qtip)
+ * @cfg {Boolean} singleClickExpand True for single click expand on this node
+ * @cfg {Function} uiProvider A UI class to use for this node (defaults to Ext.tree.TreeNodeUI)
+ * @cfg {Boolean} checked True to render a checked checkbox for this node, false to render an unchecked checkbox
+ * (defaults to undefined with no checkbox rendered)
+ * @cfg {Boolean} draggable True to make this node draggable (defaults to false)
+ * @cfg {Boolean} isTarget False to not allow this node to act as a drop target (defaults to true)
+ * @cfg {Boolean} allowChildren False to not allow this node to have child nodes (defaults to true)
+ * @cfg {Boolean} editable False to not allow this node to be edited by an {@link Ext.tree.TreeEditor} (defaults to true)
+ * @constructor
+ * @param {Object/String} attributes The attributes/config for the node or just a string with the text for the node
+ */
+Ext.tree.TreeNode = function(attributes){
+ attributes = attributes || {};
+ if(Ext.isString(attributes)){
+ attributes = {text: attributes};
+ }
+ this.childrenRendered = false;
+ this.rendered = false;
+ Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
+ this.expanded = attributes.expanded === true;
+ this.isTarget = attributes.isTarget !== false;
+ this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
+ this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
+
+ /**
+ * Read-only. The text for this node. To change it use {@link #setText}
.
+ * @type String
+ */
+ this.text = attributes.text;
+ /**
+ * True if this node is disabled.
+ * @type Boolean
+ */
+ this.disabled = attributes.disabled === true;
+ /**
+ * True if this node is hidden.
+ * @type Boolean
+ */
+ this.hidden = attributes.hidden === true;
+
+ this.addEvents(
+ /**
+ * @event textchange
+ * Fires when the text for this node is changed
+ * @param {Node} this This node
+ * @param {String} text The new text
+ * @param {String} oldText The old text
+ */
+ 'textchange',
+ /**
+ * @event beforeexpand
+ * Fires before this node is expanded, return false to cancel.
+ * @param {Node} this This node
+ * @param {Boolean} deep
+ * @param {Boolean} anim
+ */
+ 'beforeexpand',
+ /**
+ * @event beforecollapse
+ * Fires before this node is collapsed, return false to cancel.
+ * @param {Node} this This node
+ * @param {Boolean} deep
+ * @param {Boolean} anim
+ */
+ 'beforecollapse',
+ /**
+ * @event expand
+ * Fires when this node is expanded
+ * @param {Node} this This node
+ */
+ 'expand',
+ /**
+ * @event disabledchange
+ * Fires when the disabled status of this node changes
+ * @param {Node} this This node
+ * @param {Boolean} disabled
+ */
+ 'disabledchange',
+ /**
+ * @event collapse
+ * Fires when this node is collapsed
+ * @param {Node} this This node
+ */
+ 'collapse',
+ /**
+ * @event beforeclick
+ * Fires before click processing. Return false to cancel the default action.
+ * @param {Node} this This node
+ * @param {Ext.EventObject} e The event object
+ */
+ 'beforeclick',
+ /**
+ * @event click
+ * Fires when this node is clicked
+ * @param {Node} this This node
+ * @param {Ext.EventObject} e The event object
+ */
+ 'click',
+ /**
+ * @event checkchange
+ * Fires when a node with a checkbox's checked property changes
+ * @param {Node} this This node
+ * @param {Boolean} checked
+ */
+ 'checkchange',
+ /**
+ * @event beforedblclick
+ * Fires before double click processing. Return false to cancel the default action.
+ * @param {Node} this This node
+ * @param {Ext.EventObject} e The event object
+ */
+ 'beforedblclick',
+ /**
+ * @event dblclick
+ * Fires when this node is double clicked
+ * @param {Node} this This node
+ * @param {Ext.EventObject} e The event object
+ */
+ 'dblclick',
+ /**
+ * @event contextmenu
+ * Fires when this node is right clicked
+ * @param {Node} this This node
+ * @param {Ext.EventObject} e The event object
+ */
+ 'contextmenu',
+ /**
+ * @event beforechildrenrendered
+ * Fires right before the child nodes for this node are rendered
+ * @param {Node} this This node
+ */
+ 'beforechildrenrendered'
+ );
+
+ var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
+
+ /**
+ * Read-only. The UI for this node
+ * @type TreeNodeUI
+ */
+ this.ui = new uiClass(this);
+};
+Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
+ preventHScroll : true,
+ /**
+ * Returns true if this node is expanded
+ * @return {Boolean}
+ */
+ isExpanded : function(){
+ return this.expanded;
+ },
+
+/**
+ * Returns the UI object for this node.
+ * @return {TreeNodeUI} The object which is providing the user interface for this tree
+ * node. Unless otherwise specified in the {@link #uiProvider}, this will be an instance
+ * of {@link Ext.tree.TreeNodeUI}
+ */
+ getUI : function(){
+ return this.ui;
+ },
+
+ getLoader : function(){
+ var owner;
+ return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader()));
+ },
+
+ // private override
+ setFirstChild : function(node){
+ var of = this.firstChild;
+ Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
+ if(this.childrenRendered && of && node != of){
+ of.renderIndent(true, true);
+ }
+ if(this.rendered){
+ this.renderIndent(true, true);
+ }
+ },
+
+ // private override
+ setLastChild : function(node){
+ var ol = this.lastChild;
+ Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
+ if(this.childrenRendered && ol && node != ol){
+ ol.renderIndent(true, true);
+ }
+ if(this.rendered){
+ this.renderIndent(true, true);
+ }
+ },
+
+ // these methods are overridden to provide lazy rendering support
+ // private override
+ appendChild : function(n){
+ var node, exists;
+ if(!n.render && !Ext.isArray(n)){
+ n = this.getLoader().createNode(n);
+ }else{
+ exists = !n.parentNode;
+ }
+ node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
+ if(node){
+ this.afterAdd(node, exists);
+ }
+ this.ui.updateExpandIcon();
+ return node;
+ },
+
+ // private override
+ removeChild : function(node, destroy){
+ this.ownerTree.getSelectionModel().unselect(node);
+ Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
+ // if it's been rendered remove dom node
+ if(node.ui.rendered){
+ node.ui.remove();
+ }
+ if(this.childNodes.length < 1){
+ this.collapse(false, false);
+ }else{
+ this.ui.updateExpandIcon();
+ }
+ if(!this.firstChild && !this.isHiddenRoot()) {
+ this.childrenRendered = false;
+ }
+ return node;
+ },
+
+ // private override
+ insertBefore : function(node, refNode){
+ var newNode, exists;
+ if(!node.render){
+ node = this.getLoader().createNode(node);
+ } else {
+ exists = Ext.isObject(node.parentNode);
+ }
+ newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
+ if(newNode && refNode){
+ this.afterAdd(newNode, exists);
+ }
+ this.ui.updateExpandIcon();
+ return newNode;
+ },
+
+ // private
+ afterAdd : function(node, exists){
+ if(this.childrenRendered){
+ // bulk render if the node already exists
+ node.render(exists);
+ }else if(exists){
+ // make sure we update the indent
+ node.renderIndent(true, true);
+ }
+ },
+
+ /**
+ * Sets the text for this node
+ * @param {String} text
+ */
+ setText : function(text){
+ var oldText = this.text;
+ this.text = this.attributes.text = text;
+ if(this.rendered){ // event without subscribing
+ this.ui.onTextChange(this, text, oldText);
+ }
+ this.fireEvent('textchange', this, text, oldText);
+ },
+
+ /**
+ * Triggers selection of this node
+ */
+ select : function(){
+ var t = this.getOwnerTree();
+ if(t){
+ t.getSelectionModel().select(this);
+ }
+ },
+
+ /**
+ * Triggers deselection of this node
+ * @param {Boolean} silent (optional) True to stop selection change events from firing.
+ */
+ unselect : function(silent){
+ var t = this.getOwnerTree();
+ if(t){
+ t.getSelectionModel().unselect(this, silent);
+ }
+ },
+
+ /**
+ * Returns true if this node is selected
+ * @return {Boolean}
+ */
+ isSelected : function(){
+ var t = this.getOwnerTree();
+ return t ? t.getSelectionModel().isSelected(this) : false;
+ },
+
+ /**
+ * Expand this node.
+ * @param {Boolean} deep (optional) True to expand all children as well
+ * @param {Boolean} anim (optional) false to cancel the default animation
+ * @param {Function} callback (optional) A callback to be called when
+ * expanding this node completes (does not wait for deep expand to complete).
+ * Called with 1 parameter, this node.
+ * @param {Object} scope (optional) The scope (this
reference) in which the callback is executed. Defaults to this TreeNode.
+ */
+ expand : function(deep, anim, callback, scope){
+ if(!this.expanded){
+ if(this.fireEvent('beforeexpand', this, deep, anim) === false){
+ return;
+ }
+ if(!this.childrenRendered){
+ this.renderChildren();
+ }
+ this.expanded = true;
+ if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
+ this.ui.animExpand(function(){
+ this.fireEvent('expand', this);
+ this.runCallback(callback, scope || this, [this]);
+ if(deep === true){
+ this.expandChildNodes(true);
+ }
+ }.createDelegate(this));
+ return;
+ }else{
+ this.ui.expand();
+ this.fireEvent('expand', this);
+ this.runCallback(callback, scope || this, [this]);
+ }
+ }else{
+ this.runCallback(callback, scope || this, [this]);
+ }
+ if(deep === true){
+ this.expandChildNodes(true);
+ }
+ },
+
+ runCallback : function(cb, scope, args){
+ if(Ext.isFunction(cb)){
+ cb.apply(scope, args);
+ }
+ },
+
+ isHiddenRoot : function(){
+ return this.isRoot && !this.getOwnerTree().rootVisible;
+ },
+
+ /**
+ * Collapse this node.
+ * @param {Boolean} deep (optional) True to collapse all children as well
+ * @param {Boolean} anim (optional) false to cancel the default animation
+ * @param {Function} callback (optional) A callback to be called when
+ * expanding this node completes (does not wait for deep expand to complete).
+ * Called with 1 parameter, this node.
+ * @param {Object} scope (optional) The scope (this
reference) in which the callback is executed. Defaults to this TreeNode.
+ */
+ collapse : function(deep, anim, callback, scope){
+ if(this.expanded && !this.isHiddenRoot()){
+ if(this.fireEvent('beforecollapse', this, deep, anim) === false){
+ return;
+ }
+ this.expanded = false;
+ if((this.getOwnerTree().animate && anim !== false) || anim){
+ this.ui.animCollapse(function(){
+ this.fireEvent('collapse', this);
+ this.runCallback(callback, scope || this, [this]);
+ if(deep === true){
+ this.collapseChildNodes(true);
+ }
+ }.createDelegate(this));
+ return;
+ }else{
+ this.ui.collapse();
+ this.fireEvent('collapse', this);
+ this.runCallback(callback, scope || this, [this]);
+ }
+ }else if(!this.expanded){
+ this.runCallback(callback, scope || this, [this]);
+ }
+ if(deep === true){
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++) {
+ cs[i].collapse(true, false);
+ }
+ }
+ },
+
+ // private
+ delayedExpand : function(delay){
+ if(!this.expandProcId){
+ this.expandProcId = this.expand.defer(delay, this);
+ }
+ },
+
+ // private
+ cancelExpand : function(){
+ if(this.expandProcId){
+ clearTimeout(this.expandProcId);
+ }
+ this.expandProcId = false;
+ },
+
+ /**
+ * Toggles expanded/collapsed state of the node
+ */
+ toggle : function(){
+ if(this.expanded){
+ this.collapse();
+ }else{
+ this.expand();
+ }
+ },
+
+ /**
+ * Ensures all parent nodes are expanded, and if necessary, scrolls
+ * the node into view.
+ * @param {Function} callback (optional) A function to call when the node has been made visible.
+ * @param {Object} scope (optional) The scope (this
reference) in which the callback is executed. Defaults to this TreeNode.
+ */
+ ensureVisible : function(callback, scope){
+ var tree = this.getOwnerTree();
+ tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
+ var node = tree.getNodeById(this.id); // Somehow if we don't do this, we lose changes that happened to node in the meantime
+ tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
+ this.runCallback(callback, scope || this, [this]);
+ }.createDelegate(this));
+ },
+
+ /**
+ * Expand all child nodes
+ * @param {Boolean} deep (optional) true if the child nodes should also expand their child nodes
+ */
+ expandChildNodes : function(deep){
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++) {
+ cs[i].expand(deep);
+ }
+ },
+
+ /**
+ * Collapse all child nodes
+ * @param {Boolean} deep (optional) true if the child nodes should also collapse their child nodes
+ */
+ collapseChildNodes : function(deep){
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++) {
+ cs[i].collapse(deep);
+ }
+ },
+
+ /**
+ * Disables this node
+ */
+ disable : function(){
+ this.disabled = true;
+ this.unselect();
+ if(this.rendered && this.ui.onDisableChange){ // event without subscribing
+ this.ui.onDisableChange(this, true);
+ }
+ this.fireEvent('disabledchange', this, true);
+ },
+
+ /**
+ * Enables this node
+ */
+ enable : function(){
+ this.disabled = false;
+ if(this.rendered && this.ui.onDisableChange){ // event without subscribing
+ this.ui.onDisableChange(this, false);
+ }
+ this.fireEvent('disabledchange', this, false);
+ },
+
+ // private
+ renderChildren : function(suppressEvent){
+ if(suppressEvent !== false){
+ this.fireEvent('beforechildrenrendered', this);
+ }
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++){
+ cs[i].render(true);
+ }
+ this.childrenRendered = true;
+ },
+
+ // private
+ sort : function(fn, scope){
+ Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
+ if(this.childrenRendered){
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++){
+ cs[i].render(true);
+ }
+ }
+ },
+
+ // private
+ render : function(bulkRender){
+ this.ui.render(bulkRender);
+ if(!this.rendered){
+ // make sure it is registered
+ this.getOwnerTree().registerNode(this);
+ this.rendered = true;
+ if(this.expanded){
+ this.expanded = false;
+ this.expand(false, false);
+ }
+ }
+ },
+
+ // private
+ renderIndent : function(deep, refresh){
+ if(refresh){
+ this.ui.childIndent = null;
+ }
+ this.ui.renderIndent();
+ if(deep === true && this.childrenRendered){
+ var cs = this.childNodes;
+ for(var i = 0, len = cs.length; i < len; i++){
+ cs[i].renderIndent(true, refresh);
+ }
+ }
+ },
+
+ beginUpdate : function(){
+ this.childrenRendered = false;
+ },
+
+ endUpdate : function(){
+ if(this.expanded && this.rendered){
+ this.renderChildren();
+ }
+ },
+
+ destroy : function(){
+ this.unselect(true);
+ Ext.tree.TreeNode.superclass.destroy.call(this);
+ Ext.destroy(this.ui, this.loader);
+ this.ui = this.loader = null;
+ },
+
+ // private
+ onIdChange : function(id){
+ this.ui.onIdChange(id);
+ }
+});
+
Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode;/**
* @class Ext.tree.AsyncTreeNode
* @extends Ext.tree.TreeNode
@@ -2793,7 +2923,7 @@ Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
/**
* Trigger a reload for this node
* @param {Function} callback
- * @param {Object} scope (optional) The scope in which to execute the callback.
+ * @param {Object} scope (optional) The scope (this
reference) in which the callback is executed. Defaults to this Node.
*/
reload : function(callback, scope){
this.collapse(false, false);
@@ -2836,7 +2966,7 @@ Ext.tree.TreeNodeUI.prototype = {
removeChild : function(node){
if(this.rendered){
this.ctNode.removeChild(node.ui.getEl());
- }
+ }
},
// private
@@ -2859,14 +2989,14 @@ Ext.tree.TreeNodeUI.prototype = {
// private
onDisableChange : function(node, state){
this.disabled = state;
- if (this.checkbox) {
- this.checkbox.disabled = state;
- }
+ if (this.checkbox) {
+ this.checkbox.disabled = state;
+ }
if(state){
this.addClass("x-tree-node-disabled");
}else{
this.removeClass("x-tree-node-disabled");
- }
+ }
},
// private
@@ -2917,7 +3047,7 @@ Ext.tree.TreeNodeUI.prototype = {
*/
removeClass : function(cls){
if(this.elNode){
- Ext.fly(this.elNode).removeClass(cls);
+ Ext.fly(this.elNode).removeClass(cls);
}
},
@@ -2926,12 +3056,12 @@ Ext.tree.TreeNodeUI.prototype = {
if(this.rendered){
this.holder = document.createElement("div");
this.holder.appendChild(this.wrap);
- }
+ }
},
// private
fireEvent : function(){
- return this.node.fireEvent.apply(this.node, arguments);
+ return this.node.fireEvent.apply(this.node, arguments);
},
// private
@@ -2939,10 +3069,7 @@ Ext.tree.TreeNodeUI.prototype = {
this.node.on("move", this.onMove, this);
if(this.node.disabled){
- this.addClass("x-tree-node-disabled");
- if (this.checkbox) {
- this.checkbox.disabled = true;
- }
+ this.onDisableChange(this.node, true);
}
if(this.node.hidden){
this.hide();
@@ -2980,7 +3107,7 @@ Ext.tree.TreeNodeUI.prototype = {
this.node.hidden = false;
if(this.wrap){
this.wrap.style.display = "";
- }
+ }
},
// private
@@ -3027,13 +3154,15 @@ Ext.tree.TreeNodeUI.prototype = {
if(this.disabled){
return;
}
- if(this.checkbox){
- this.toggleCheck();
- }
- if(!this.animating && this.node.isExpandable()){
- this.node.toggle();
+ if(this.fireEvent("beforedblclick", this.node, e) !== false){
+ if(this.checkbox){
+ this.toggleCheck();
+ }
+ if(!this.animating && this.node.isExpandable()){
+ this.node.toggle();
+ }
+ this.fireEvent("dblclick", this.node, e);
}
- this.fireEvent("dblclick", this.node, e);
},
onOver : function(e){
@@ -3047,8 +3176,8 @@ Ext.tree.TreeNodeUI.prototype = {
// private
onCheckChange : function(){
var checked = this.checkbox.checked;
- // fix for IE6
- this.checkbox.defaultChecked = checked;
+ // fix for IE6
+ this.checkbox.defaultChecked = checked;
this.node.attributes.checked = checked;
this.fireEvent('checkchange', this.node, checked);
},
@@ -3064,12 +3193,12 @@ Ext.tree.TreeNodeUI.prototype = {
startDrop : function(){
this.dropping = true;
},
-
+
// delayed drop so the click event doesn't get fired on a drop
- endDrop : function(){
+ endDrop : function(){
setTimeout(function(){
this.dropping = false;
- }.createDelegate(this), 50);
+ }.createDelegate(this), 50);
},
// private
@@ -3110,7 +3239,7 @@ Ext.tree.TreeNodeUI.prototype = {
blur : function(){
try{
this.anchor.blur();
- }catch(e){}
+ }catch(e){}
},
// private
@@ -3125,7 +3254,7 @@ Ext.tree.TreeNodeUI.prototype = {
}
this.animating = true;
this.updateExpandIcon();
-
+
ct.slideIn('t', {
callback : function(){
this.animating = false;
@@ -3172,12 +3301,15 @@ Ext.tree.TreeNodeUI.prototype = {
// private
getContainer : function(){
- return this.ctNode;
+ return this.ctNode;
},
- // private
+/**
+ * Returns the element which encapsulates this node.
+ * @return {HtmlElement} The DOM element. The default implementation uses a <li>
.
+ */
getEl : function(){
- return this.wrap;
+ return this.wrap;
},
// private
@@ -3192,15 +3324,15 @@ Ext.tree.TreeNodeUI.prototype = {
// private
onRender : function(){
- this.render();
+ this.render();
},
// private
render : function(bulkRender){
var n = this.node, a = n.attributes;
- var targetNode = n.parentNode ?
+ var targetNode = n.parentNode ?
n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
-
+
if(!this.rendered){
this.rendered = true;
@@ -3217,7 +3349,7 @@ Ext.tree.TreeNodeUI.prototype = {
if(a.qtipTitle){
this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
}
- }
+ }
}else if(a.qtipCfg){
a.qtipCfg.target = Ext.id(this.textNode);
Ext.QuickTips.register(a.qtipCfg);
@@ -3238,10 +3370,10 @@ Ext.tree.TreeNodeUI.prototype = {
// add some indent caching, this helps performance when rendering a large tree
this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
- var cb = typeof a.checked == 'boolean';
-
- var href = a.href ? a.href : Ext.isGecko ? "" : "#";
- var buf = ['
+nodeParameter: 'node',
paramOrder: ['param1','param2','param3']
-paramOrder: 'param1 param2 param3'
-paramOrder: 'param1,param2,param3'
-paramOrder: 'param1|param2|param'
+paramOrder: 'node param1 param2 param3'
+paramOrder: 'param1,node,param2,param3'
+paramOrder: 'param1|param2|param|node'
*/
paramOrder: undefined,
@@ -3571,6 +3695,12 @@ paramOrder: 'param1|param2|param'
*/
paramsAsHash: false,
+ /**
+ * @cfg {String} nodeParameter The name of the parameter sent to the server which contains
+ * the identifier of the node. Defaults to 'node'.
+ */
+ nodeParameter: 'node',
+
/**
* @cfg {Function} directFn
* Function to call when executing a request.
@@ -3582,8 +3712,10 @@ paramOrder: 'param1|param2|param'
* This is called automatically when a node is expanded, but may be used to reload
* a node (or append new children if the {@link #clearOnLoad} option is false.)
* @param {Ext.tree.TreeNode} node
- * @param {Function} callback
- * @param (Object) scope
+ * @param {Function} callback Function to call after the node has been loaded. The
+ * function is passed the TreeNode which was requested to be loaded.
+ * @param (Object) scope The cope (this
reference) in which the callback is executed.
+ * defaults to the loaded TreeNode.
*/
load : function(node, callback, scope){
if(this.clearOnLoad){
@@ -3592,7 +3724,7 @@ paramOrder: 'param1|param2|param'
}
}
if(this.doPreload(node)){ // preloaded json children
- this.runCallback(callback, scope || node, []);
+ this.runCallback(callback, scope || node, [node]);
}else if(this.directFn || this.dataUrl || this.url){
this.requestData(node, callback, scope || node);
}
@@ -3617,27 +3749,29 @@ paramOrder: 'param1|param2|param'
},
getParams: function(node){
- var buf = [], bp = this.baseParams;
+ var bp = Ext.apply({}, this.baseParams),
+ np = this.nodeParameter,
+ po = this.paramOrder;
+
+ np && (bp[ np ] = node.id);
+
if(this.directFn){
- buf.push(node.id);
- if(bp){
- if(this.paramOrder){
- for(var i = 0, len = this.paramOrder.length; i < len; i++){
- buf.push(bp[this.paramOrder[i]]);
- }
- }else if(this.paramsAsHash){
- buf.push(bp);
+ var buf = [node.id];
+ if(po){
+ // reset 'buf' if the nodeParameter was included in paramOrder
+ if(np && po.indexOf(np) > -1){
+ buf = [];
}
+
+ for(var i = 0, len = po.length; i < len; i++){
+ buf.push(bp[ po[i] ]);
+ }
+ }else if(this.paramsAsHash){
+ buf = [bp];
}
return buf;
}else{
- for(var key in bp){
- if(!Ext.isFunction(bp[key])){
- buf.push(encodeURIComponent(key), "=", encodeURIComponent(bp[key]), "&");
- }
- }
- buf.push("node=", encodeURIComponent(node.id));
- return buf.join("");
+ return bp;
}
},
@@ -3702,7 +3836,7 @@ paramOrder: 'param1|param2|param'
* Example:
new Ext.tree.TreePanel({
...
- new Ext.tree.TreeLoader({
+ loader: new Ext.tree.TreeLoader({
url: 'dataUrl',
createNode: function(attr) {
// Allow consolidation consignments to have
@@ -3711,7 +3845,7 @@ new Ext.tree.TreePanel({
attr.iconCls = 'x-consol',
attr.allowDrop = true;
}
- return Ext.tree.TreeLoader.prototype.call(this, attr);
+ return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);
}
}),
...
@@ -3724,10 +3858,10 @@ new Ext.tree.TreePanel({
if(this.baseAttrs){
Ext.applyIf(attr, this.baseAttrs);
}
- if(this.applyLoader !== false){
+ if(this.applyLoader !== false && !attr.loader){
attr.loader = this;
}
- if(typeof attr.uiProvider == 'string'){
+ if(Ext.isString(attr.uiProvider)){
attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
}
if(attr.nodeType){
@@ -3769,6 +3903,11 @@ new Ext.tree.TreePanel({
var a = response.argument;
this.fireEvent("loadexception", this, a.node, response);
this.runCallback(a.callback, a.scope || a.node, [a.node]);
+ },
+
+ destroy : function(){
+ this.abort();
+ this.purgeListeners();
}
});/**
* @class Ext.tree.TreeFilter
@@ -3824,7 +3963,7 @@ Ext.tree.TreeFilter.prototype = {
* node in the tree (or from the startNode). If the function returns true, the node is kept
* otherwise it is filtered. If a node is filtered, its children are also filtered.
* @param {Function} fn The filter function
- * @param {Object} scope (optional) The scope of the function (defaults to the current node)
+ * @param {Object} scope (optional) The scope (this
reference) in which the function is executed. Defaults to the current Node.
*/
filterBy : function(fn, scope, startNode){
startNode = startNode || this.tree.root;
@@ -3880,7 +4019,7 @@ Ext.tree.TreeFilter.prototype = {
};
/**
* @class Ext.tree.TreeSorter
- * Provides sorting of nodes in a {@link Ext.tree.TreePanel}. The TreeSorter automatically monitors events on the
+ * Provides sorting of nodes in a {@link Ext.tree.TreePanel}. The TreeSorter automatically monitors events on the
* associated TreePanel that might affect the tree's sort order (beforechildrenrendered, append, insert and textchange).
* Example usage:
*
@@ -3901,33 +4040,33 @@ Ext.tree.TreeSorter = function(tree, config){
/**
* @cfg {Boolean} folderSort True to sort leaf nodes under non-leaf nodes (defaults to false)
*/
- /**
- * @cfg {String} property The named attribute on the node to sort by (defaults to "text"). Note that this
+ /**
+ * @cfg {String} property The named attribute on the node to sort by (defaults to "text"). Note that this
* property is only used if no {@link #sortType} function is specified, otherwise it is ignored.
*/
- /**
+ /**
* @cfg {String} dir The direction to sort ("asc" or "desc," case-insensitive, defaults to "asc")
*/
- /**
+ /**
* @cfg {String} leafAttr The attribute used to determine leaf nodes when {@link #folderSort} = true (defaults to "leaf")
*/
- /**
+ /**
* @cfg {Boolean} caseSensitive true for case-sensitive sort (defaults to false)
*/
- /**
+ /**
* @cfg {Function} sortType A custom "casting" function used to convert node values before sorting. The function
* will be called with a single parameter (the {@link Ext.tree.TreeNode} being evaluated) and is expected to return
* the node's sort value cast to the specific data type required for sorting. This could be used, for example, when
- * a node's text (or other attribute) should be sorted as a date or numeric value. See the class description for
+ * a node's text (or other attribute) should be sorted as a date or numeric value. See the class description for
* example usage. Note that if a sortType is specified, any {@link #property} config will be ignored.
*/
-
+
Ext.apply(this, config);
tree.on("beforechildrenrendered", this.doSort, this);
tree.on("append", this.updateSort, this);
tree.on("insert", this.updateSort, this);
tree.on("textchange", this.updateSortParent, this);
-
+
var dsc = this.dir && this.dir.toLowerCase() == "desc";
var p = this.property || "text";
var sortType = this.sortType;
@@ -3944,14 +4083,14 @@ Ext.tree.TreeSorter = function(tree, config){
return -1;
}
}
- var v1 = sortType ? sortType(n1) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
- var v2 = sortType ? sortType(n2) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
- if(v1 < v2){
- return dsc ? +1 : -1;
- }else if(v1 > v2){
- return dsc ? -1 : +1;
+ var v1 = sortType ? sortType(n1) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
+ var v2 = sortType ? sortType(n2) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
+ if(v1 < v2){
+ return dsc ? +1 : -1;
+ }else if(v1 > v2){
+ return dsc ? -1 : +1;
}else{
- return 0;
+ return 0;
}
};
};
@@ -3960,20 +4099,20 @@ Ext.tree.TreeSorter.prototype = {
doSort : function(node){
node.sort(this.sortFn);
},
-
+
compareNodes : function(n1, n2){
return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);
},
-
+
updateSort : function(tree, node){
if(node.childrenRendered){
this.doSort.defer(1, this, [node]);
}
},
-
+
updateSortParent : function(node){
- var p = node.parentNode;
- if(p && p.childrenRendered){
+ var p = node.parentNode;
+ if(p && p.childrenRendered){
this.doSort.defer(1, this, [p]);
}
}
@@ -4380,6 +4519,7 @@ Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
Ext.tree.TreeEditor = function(tree, fc, config){
fc = fc || {};
var field = fc.events ? fc : new Ext.form.TextField(fc);
+
Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);
this.tree = tree;
@@ -4431,12 +4571,20 @@ Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
editDelay : 350,
initEditor : function(tree){
- tree.on('beforeclick', this.beforeNodeClick, this);
- tree.on('dblclick', this.onNodeDblClick, this);
- this.on('complete', this.updateNode, this);
- this.on('beforestartedit', this.fitToTree, this);
+ tree.on({
+ scope : this,
+ beforeclick: this.beforeNodeClick,
+ dblclick : this.onNodeDblClick
+ });
+
+ this.on({
+ scope : this,
+ complete : this.updateNode,
+ beforestartedit: this.fitToTree,
+ specialkey : this.onSpecialKey
+ });
+
this.on('startedit', this.bindScroll, this, {delay:10});
- this.on('specialkey', this.onSpecialKey, this);
},
// private
@@ -4518,5 +4666,13 @@ Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
e.stopEvent();
this.completeEdit();
}
+ },
+
+ onDestroy : function(){
+ clearTimeout(this.autoEditTimer);
+ Ext.tree.TreeEditor.superclass.onDestroy.call(this);
+ var tree = this.tree;
+ tree.un('beforeclick', this.beforeNodeClick, this);
+ tree.un('dblclick', this.onNodeDblClick, this);
}
});
\ No newline at end of file