X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/6e39d509471fe9b4e2660e0d1631b350d0c66f40..2e847cf21b8ab9d15fa167b315ca5b2fa92638fc:/pkgs/pkg-tree-debug.js
diff --git a/pkgs/pkg-tree-debug.js b/pkgs/pkg-tree-debug.js
index 2553a85a..639fb788 100644
--- a/pkgs/pkg-tree-debug.js
+++ b/pkgs/pkg-tree-debug.js
@@ -1,6 +1,6 @@
/*!
- * Ext JS Library 3.1.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
*/
@@ -525,12 +525,24 @@ new Ext.tree.TreePanel({
var uiP = node.attributes.uiProvider;
node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
}
- if (this.innerCt) {
- this.innerCt.update('');
- this.afterRender();
+ if(this.innerCt){
+ this.clearInnerCt();
+ this.renderRoot();
}
return node;
},
+
+ clearInnerCt : function(){
+ this.innerCt.update('');
+ },
+
+ // private
+ renderRoot : function(){
+ this.root.render();
+ if(!this.rootVisible){
+ this.root.renderChildren();
+ }
+ },
/**
* Gets a node in this tree by its id
@@ -745,10 +757,7 @@ new Ext.tree.TreePanel({
// private
afterRender : function(){
Ext.tree.TreePanel.superclass.afterRender.call(this);
- this.root.render();
- if(!this.rootVisible){
- this.root.renderChildren();
- }
+ this.renderRoot();
},
beforeDestroy : function(){
@@ -900,6 +909,15 @@ new Ext.tree.TreePanel({
/**
* @cfg {String} contentEl @hide
*/
+ /**
+ * @cfg {Mixed} data @hide
+ */
+ /**
+ * @cfg {Mixed} tpl @hide
+ */
+ /**
+ * @cfg {String} tplWriteMode @hide
+ */
/**
* @cfg {String} disabledClass @hide
*/
@@ -945,7 +963,7 @@ Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree
Ext.tree.TreeEventModel.prototype = {
initEvents : function(){
var t = this.tree;
-
+
if(t.trackMouseOver !== false){
t.mon(t.innerCt, {
scope: this,
@@ -1018,12 +1036,15 @@ Ext.tree.TreeEventModel.prototype = {
},
trackExit : function(e){
- if(this.lastOverNode && !e.within(this.lastOverNode.ui.getEl())){
- this.onNodeOut(e, this.lastOverNode);
+ if(this.lastOverNode){
+ if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){
+ this.onNodeOut(e, this.lastOverNode);
+ }
delete this.lastOverNode;
Ext.getBody().un('mouseover', this.trackExit, this);
this.trackingDoc = false;
}
+
},
delegateClick : function(e, t){
@@ -1045,7 +1066,7 @@ Ext.tree.TreeEventModel.prototype = {
if(this.getNodeTarget(e)){
this.onNodeDblClick(e, this.getNode(e));
}else{
- this.onContainerEvent(e, 'dblclick');
+ this.onContainerEvent(e, 'dblclick');
}
}
},
@@ -1055,13 +1076,13 @@ Ext.tree.TreeEventModel.prototype = {
if(this.getNodeTarget(e)){
this.onNodeContextMenu(e, this.getNode(e));
}else{
- this.onContainerEvent(e, 'contextmenu');
+ this.onContainerEvent(e, 'contextmenu');
}
}
},
-
+
onContainerEvent: function(e, type){
- this.tree.fireEvent('container' + type, this.tree, e);
+ this.tree.fireEvent('container' + type, this.tree, e);
},
onNodeClick : function(e, node){
@@ -1102,7 +1123,8 @@ Ext.tree.TreeEventModel.prototype = {
},
beforeEvent : function(e){
- if(this.disabled){
+ var node = this.getNode(e);
+ if(this.disabled || !node || !node.ui){
e.stopEvent();
return false;
}
@@ -1971,6 +1993,20 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
this.parentNode.removeChild(this, destroy);
return this;
},
+
+ /**
+ * Removes all child nodes from this node.
+ * @param {Boolean} destroy true to destroy the node upon removal. Defaults to false.
+ * @return {Node} this
+ */
+ removeAll : function(destroy){
+ var cn = this.childNodes,
+ n;
+ while((n = cn[0])){
+ this.removeChild(n, destroy);
+ }
+ return this;
+ },
/**
* Returns the child node at the specified index.
@@ -2231,554 +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(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){
- 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, 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){
- 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 = 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);
- }
-});
-
+});/**
+ * @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
@@ -2913,7 +2966,7 @@ Ext.tree.TreeNodeUI.prototype = {
removeChild : function(node){
if(this.rendered){
this.ctNode.removeChild(node.ui.getEl());
- }
+ }
},
// private
@@ -2938,12 +2991,12 @@ Ext.tree.TreeNodeUI.prototype = {
this.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
@@ -2994,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);
}
},
@@ -3003,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
@@ -3016,7 +3069,7 @@ Ext.tree.TreeNodeUI.prototype = {
this.node.on("move", this.onMove, this);
if(this.node.disabled){
- this.onDisableChange(this.node, true);
+ this.onDisableChange(this.node, true);
}
if(this.node.hidden){
this.hide();
@@ -3054,7 +3107,7 @@ Ext.tree.TreeNodeUI.prototype = {
this.node.hidden = false;
if(this.wrap){
this.wrap.style.display = "";
- }
+ }
},
// private
@@ -3124,7 +3177,7 @@ Ext.tree.TreeNodeUI.prototype = {
onCheckChange : function(){
var checked = this.checkbox.checked;
// fix for IE6
- this.checkbox.defaultChecked = checked;
+ this.checkbox.defaultChecked = checked;
this.node.attributes.checked = checked;
this.fireEvent('checkchange', this.node, checked);
},
@@ -3140,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
@@ -3186,7 +3239,7 @@ Ext.tree.TreeNodeUI.prototype = {
blur : function(){
try{
this.anchor.blur();
- }catch(e){}
+ }catch(e){}
},
// private
@@ -3201,7 +3254,7 @@ Ext.tree.TreeNodeUI.prototype = {
}
this.animating = true;
this.updateExpandIcon();
-
+
ct.slideIn('t', {
callback : function(){
this.animating = false;
@@ -3248,7 +3301,7 @@ Ext.tree.TreeNodeUI.prototype = {
// private
getContainer : function(){
- return this.ctNode;
+ return this.ctNode;
},
/**
@@ -3256,7 +3309,7 @@ Ext.tree.TreeNodeUI.prototype = {
* @return {HtmlElement} The DOM element. The default implementation uses a <li>
.
*/
getEl : function(){
- return this.wrap;
+ return this.wrap;
},
// private
@@ -3271,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;
@@ -3296,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);
@@ -3335,7 +3388,7 @@ Ext.tree.TreeNodeUI.prototype = {
}else{
this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
}
-
+
this.elNode = this.wrap.childNodes[0];
this.ctNode = this.wrap.childNodes[1];
var cs = this.elNode.childNodes;
@@ -3360,7 +3413,7 @@ Ext.tree.TreeNodeUI.prototype = {
getAnchor : function(){
return this.anchor;
},
-
+
/**
* Returns the text node.
* @return {HtmlNode} The DOM text node.
@@ -3368,7 +3421,7 @@ Ext.tree.TreeNodeUI.prototype = {
getTextEl : function(){
return this.textNode;
},
-
+
/**
* Returns the icon <img> element.
* @return {HtmlElement} The DOM image element.
@@ -3383,14 +3436,14 @@ Ext.tree.TreeNodeUI.prototype = {
* @return {Boolean} The checked flag.
*/
isChecked : function(){
- return this.checkbox ? this.checkbox.checked : false;
+ return this.checkbox ? this.checkbox.checked : false;
},
// private
updateExpandIcon : function(){
if(this.rendered){
- var n = this.node,
- c1,
+ var n = this.node,
+ c1,
c2,
cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow",
hasChild = n.hasChildNodes();
@@ -3414,7 +3467,7 @@ Ext.tree.TreeNodeUI.prototype = {
}
}else{
if(!this.wasLeaf){
- Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");
+ Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-collapsed");
delete this.c1;
delete this.c2;
this.wasLeaf = true;
@@ -3427,7 +3480,7 @@ Ext.tree.TreeNodeUI.prototype = {
}
}
},
-
+
// private
onIdChange: function(id){
if(this.rendered){
@@ -3475,7 +3528,7 @@ Ext.tree.TreeNodeUI.prototype = {
if(this.elNode){
Ext.dd.Registry.unregister(this.elNode.id);
}
-
+
Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){
if(this[el]){
Ext.fly(this[el]).remove();
@@ -3622,15 +3675,15 @@ Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
/**
* @cfg {Array/String} paramOrder Defaults to undefined. Only used when using directFn.
- * A list of params to be executed
- * server side. Specify the params in the order in which they must be executed on the server-side
+ * Specifies the params in the order in which they must be passed to the server-side Direct method
* as either (1) an Array of String values, or (2) a String of params delimited by either whitespace,
* comma, or pipe. For example,
* any of the following would be acceptable:
+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,
@@ -3641,7 +3694,7 @@ paramOrder: 'param1|param2|param'
* {@link #paramOrder} nullifies this configuration.
*/
paramsAsHash: false,
-
+
/**
* @cfg {String} nodeParameter The name of the parameter sent to the server which contains
* the identifier of the node. Defaults to 'node'.
@@ -3659,7 +3712,7 @@ 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 Function to call after the node has been loaded. The
+ * @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.
@@ -3696,23 +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{
- var o = Ext.apply({}, bp);
- o[this.nodeParameter] = node.id;
- return o;
+ return bp;
}
},
@@ -3845,8 +3904,9 @@ new Ext.tree.TreePanel({
this.fireEvent("loadexception", this, a.node, response);
this.runCallback(a.callback, a.scope || a.node, [a.node]);
},
-
+
destroy : function(){
+ this.abort();
this.purgeListeners();
}
});/**
@@ -3959,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:
@@ -3980,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;
@@ -4023,14 +4083,14 @@ Ext.tree.TreeSorter = function(tree, config){
return -1;
}
}
- var v1 = sortType ? sortType(n1.attributes[p]) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
- var v2 = sortType ? sortType(n2.attributes[p]) : (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;
}
};
};
@@ -4039,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]);
}
}
@@ -4459,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;
@@ -4511,16 +4572,18 @@ Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
initEditor : function(tree){
tree.on({
- scope: this,
+ scope : this,
beforeclick: this.beforeNodeClick,
- dblclick: this.onNodeDblClick
+ dblclick : this.onNodeDblClick
});
+
this.on({
- scope: this,
- complete: this.updateNode,
+ scope : this,
+ complete : this.updateNode,
beforestartedit: this.fitToTree,
- specialkey: this.onSpecialKey
+ specialkey : this.onSpecialKey
});
+
this.on('startedit', this.bindScroll, this, {delay:10});
},