[76] | 1 | /*! |
---|
| 2 | * Ext JS Library 3.4.0 |
---|
| 3 | * Copyright(c) 2006-2011 Sencha Inc. |
---|
| 4 | * licensing@sencha.com |
---|
| 5 | * http://www.sencha.com/license |
---|
| 6 | */ |
---|
| 7 | /** |
---|
| 8 | * @class Ext.tree.TreePanel |
---|
| 9 | * @extends Ext.Panel |
---|
| 10 | * <p>The TreePanel provides tree-structured UI representation of tree-structured data.</p> |
---|
| 11 | * <p>{@link Ext.tree.TreeNode TreeNode}s added to the TreePanel may each contain metadata |
---|
| 12 | * used by your application in their {@link Ext.tree.TreeNode#attributes attributes} property.</p> |
---|
| 13 | * <p><b>A TreePanel must have a {@link #root} node before it is rendered.</b> This may either be |
---|
| 14 | * specified using the {@link #root} config option, or using the {@link #setRootNode} method. |
---|
| 15 | * <p>An example of tree rendered to an existing div:</p><pre><code> |
---|
| 16 | var tree = new Ext.tree.TreePanel({ |
---|
| 17 | renderTo: 'tree-div', |
---|
| 18 | useArrows: true, |
---|
| 19 | autoScroll: true, |
---|
| 20 | animate: true, |
---|
| 21 | enableDD: true, |
---|
| 22 | containerScroll: true, |
---|
| 23 | border: false, |
---|
| 24 | // auto create TreeLoader |
---|
| 25 | dataUrl: 'get-nodes.php', |
---|
| 26 | |
---|
| 27 | root: { |
---|
| 28 | nodeType: 'async', |
---|
| 29 | text: 'Ext JS', |
---|
| 30 | draggable: false, |
---|
| 31 | id: 'source' |
---|
| 32 | } |
---|
| 33 | }); |
---|
| 34 | |
---|
| 35 | tree.getRootNode().expand(); |
---|
| 36 | * </code></pre> |
---|
| 37 | * <p>The example above would work with a data packet similar to this:</p><pre><code> |
---|
| 38 | [{ |
---|
| 39 | "text": "adapter", |
---|
| 40 | "id": "source\/adapter", |
---|
| 41 | "cls": "folder" |
---|
| 42 | }, { |
---|
| 43 | "text": "dd", |
---|
| 44 | "id": "source\/dd", |
---|
| 45 | "cls": "folder" |
---|
| 46 | }, { |
---|
| 47 | "text": "debug.js", |
---|
| 48 | "id": "source\/debug.js", |
---|
| 49 | "leaf": true, |
---|
| 50 | "cls": "file" |
---|
| 51 | }] |
---|
| 52 | * </code></pre> |
---|
| 53 | * <p>An example of tree within a Viewport:</p><pre><code> |
---|
| 54 | new Ext.Viewport({ |
---|
| 55 | layout: 'border', |
---|
| 56 | items: [{ |
---|
| 57 | region: 'west', |
---|
| 58 | collapsible: true, |
---|
| 59 | title: 'Navigation', |
---|
| 60 | xtype: 'treepanel', |
---|
| 61 | width: 200, |
---|
| 62 | autoScroll: true, |
---|
| 63 | split: true, |
---|
| 64 | loader: new Ext.tree.TreeLoader(), |
---|
| 65 | root: new Ext.tree.AsyncTreeNode({ |
---|
| 66 | expanded: true, |
---|
| 67 | children: [{ |
---|
| 68 | text: 'Menu Option 1', |
---|
| 69 | leaf: true |
---|
| 70 | }, { |
---|
| 71 | text: 'Menu Option 2', |
---|
| 72 | leaf: true |
---|
| 73 | }, { |
---|
| 74 | text: 'Menu Option 3', |
---|
| 75 | leaf: true |
---|
| 76 | }] |
---|
| 77 | }), |
---|
| 78 | rootVisible: false, |
---|
| 79 | listeners: { |
---|
| 80 | click: function(n) { |
---|
| 81 | Ext.Msg.alert('Navigation Tree Click', 'You clicked: "' + n.attributes.text + '"'); |
---|
| 82 | } |
---|
| 83 | } |
---|
| 84 | }, { |
---|
| 85 | region: 'center', |
---|
| 86 | xtype: 'tabpanel', |
---|
| 87 | // remaining code not shown ... |
---|
| 88 | }] |
---|
| 89 | }); |
---|
| 90 | </code></pre> |
---|
| 91 | * |
---|
| 92 | * @cfg {Ext.tree.TreeNode} root The root node for the tree. |
---|
| 93 | * @cfg {Boolean} rootVisible <tt>false</tt> to hide the root node (defaults to <tt>true</tt>) |
---|
| 94 | * @cfg {Boolean} lines <tt>false</tt> to disable tree lines (defaults to <tt>true</tt>) |
---|
| 95 | * @cfg {Boolean} enableDD <tt>true</tt> to enable drag and drop |
---|
| 96 | * @cfg {Boolean} enableDrag <tt>true</tt> to enable just drag |
---|
| 97 | * @cfg {Boolean} enableDrop <tt>true</tt> to enable just drop |
---|
| 98 | * @cfg {Object} dragConfig Custom config to pass to the {@link Ext.tree.TreeDragZone} instance |
---|
| 99 | * @cfg {Object} dropConfig Custom config to pass to the {@link Ext.tree.TreeDropZone} instance |
---|
| 100 | * @cfg {String} ddGroup The DD group this TreePanel belongs to |
---|
| 101 | * @cfg {Boolean} ddAppendOnly <tt>true</tt> if the tree should only allow append drops (use for trees which are sorted) |
---|
| 102 | * @cfg {Boolean} ddScroll <tt>true</tt> to enable body scrolling |
---|
| 103 | * @cfg {Boolean} containerScroll <tt>true</tt> to register this container with ScrollManager |
---|
| 104 | * @cfg {Boolean} hlDrop <tt>false</tt> to disable node highlight on drop (defaults to the value of {@link Ext#enableFx}) |
---|
| 105 | * @cfg {String} hlColor The color of the node highlight (defaults to <tt>'C3DAF9'</tt>) |
---|
| 106 | * @cfg {Boolean} animate <tt>true</tt> to enable animated expand/collapse (defaults to the value of {@link Ext#enableFx}) |
---|
| 107 | * @cfg {Boolean} singleExpand <tt>true</tt> if only 1 node per branch may be expanded |
---|
| 108 | * @cfg {Object} selModel A tree selection model to use with this TreePanel (defaults to an {@link Ext.tree.DefaultSelectionModel}) |
---|
| 109 | * @cfg {Boolean} trackMouseOver <tt>false</tt> to disable mouse over highlighting |
---|
| 110 | * @cfg {Ext.tree.TreeLoader} loader A {@link Ext.tree.TreeLoader} for use with this TreePanel |
---|
| 111 | * @cfg {String} pathSeparator The token used to separate sub-paths in path strings (defaults to <tt>'/'</tt>) |
---|
| 112 | * @cfg {Boolean} useArrows <tt>true</tt> to use Vista-style arrows in the tree (defaults to <tt>false</tt>) |
---|
| 113 | * @cfg {String} requestMethod The HTTP request method for loading data (defaults to the value of {@link Ext.Ajax#method}). |
---|
| 114 | * |
---|
| 115 | * @constructor |
---|
| 116 | * @param {Object} config |
---|
| 117 | * @xtype treepanel |
---|
| 118 | */ |
---|
| 119 | Ext.tree.TreePanel = Ext.extend(Ext.Panel, { |
---|
| 120 | rootVisible : true, |
---|
| 121 | animate : Ext.enableFx, |
---|
| 122 | lines : true, |
---|
| 123 | enableDD : false, |
---|
| 124 | hlDrop : Ext.enableFx, |
---|
| 125 | pathSeparator : '/', |
---|
| 126 | |
---|
| 127 | /** |
---|
| 128 | * @cfg {Array} bubbleEvents |
---|
| 129 | * <p>An array of events that, when fired, should be bubbled to any parent container. |
---|
| 130 | * See {@link Ext.util.Observable#enableBubble}. |
---|
| 131 | * Defaults to <tt>[]</tt>. |
---|
| 132 | */ |
---|
| 133 | bubbleEvents : [], |
---|
| 134 | |
---|
| 135 | initComponent : function(){ |
---|
| 136 | Ext.tree.TreePanel.superclass.initComponent.call(this); |
---|
| 137 | |
---|
| 138 | if(!this.eventModel){ |
---|
| 139 | this.eventModel = new Ext.tree.TreeEventModel(this); |
---|
| 140 | } |
---|
| 141 | |
---|
| 142 | // initialize the loader |
---|
| 143 | var l = this.loader; |
---|
| 144 | if(!l){ |
---|
| 145 | l = new Ext.tree.TreeLoader({ |
---|
| 146 | dataUrl: this.dataUrl, |
---|
| 147 | requestMethod: this.requestMethod |
---|
| 148 | }); |
---|
| 149 | }else if(Ext.isObject(l) && !l.load){ |
---|
| 150 | l = new Ext.tree.TreeLoader(l); |
---|
| 151 | } |
---|
| 152 | this.loader = l; |
---|
| 153 | |
---|
| 154 | this.nodeHash = {}; |
---|
| 155 | |
---|
| 156 | /** |
---|
| 157 | * The root node of this tree. |
---|
| 158 | * @type Ext.tree.TreeNode |
---|
| 159 | * @property root |
---|
| 160 | */ |
---|
| 161 | if(this.root){ |
---|
| 162 | var r = this.root; |
---|
| 163 | delete this.root; |
---|
| 164 | this.setRootNode(r); |
---|
| 165 | } |
---|
| 166 | |
---|
| 167 | |
---|
| 168 | this.addEvents( |
---|
| 169 | |
---|
| 170 | /** |
---|
| 171 | * @event append |
---|
| 172 | * Fires when a new child node is appended to a node in this tree. |
---|
| 173 | * @param {Tree} tree The owner tree |
---|
| 174 | * @param {Node} parent The parent node |
---|
| 175 | * @param {Node} node The newly appended node |
---|
| 176 | * @param {Number} index The index of the newly appended node |
---|
| 177 | */ |
---|
| 178 | 'append', |
---|
| 179 | /** |
---|
| 180 | * @event remove |
---|
| 181 | * Fires when a child node is removed from a node in this tree. |
---|
| 182 | * @param {Tree} tree The owner tree |
---|
| 183 | * @param {Node} parent The parent node |
---|
| 184 | * @param {Node} node The child node removed |
---|
| 185 | */ |
---|
| 186 | 'remove', |
---|
| 187 | /** |
---|
| 188 | * @event movenode |
---|
| 189 | * Fires when a node is moved to a new location in the tree |
---|
| 190 | * @param {Tree} tree The owner tree |
---|
| 191 | * @param {Node} node The node moved |
---|
| 192 | * @param {Node} oldParent The old parent of this node |
---|
| 193 | * @param {Node} newParent The new parent of this node |
---|
| 194 | * @param {Number} index The index it was moved to |
---|
| 195 | */ |
---|
| 196 | 'movenode', |
---|
| 197 | /** |
---|
| 198 | * @event insert |
---|
| 199 | * Fires when a new child node is inserted in a node in this tree. |
---|
| 200 | * @param {Tree} tree The owner tree |
---|
| 201 | * @param {Node} parent The parent node |
---|
| 202 | * @param {Node} node The child node inserted |
---|
| 203 | * @param {Node} refNode The child node the node was inserted before |
---|
| 204 | */ |
---|
| 205 | 'insert', |
---|
| 206 | /** |
---|
| 207 | * @event beforeappend |
---|
| 208 | * Fires before a new child is appended to a node in this tree, return false to cancel the append. |
---|
| 209 | * @param {Tree} tree The owner tree |
---|
| 210 | * @param {Node} parent The parent node |
---|
| 211 | * @param {Node} node The child node to be appended |
---|
| 212 | */ |
---|
| 213 | 'beforeappend', |
---|
| 214 | /** |
---|
| 215 | * @event beforeremove |
---|
| 216 | * Fires before a child is removed from a node in this tree, return false to cancel the remove. |
---|
| 217 | * @param {Tree} tree The owner tree |
---|
| 218 | * @param {Node} parent The parent node |
---|
| 219 | * @param {Node} node The child node to be removed |
---|
| 220 | */ |
---|
| 221 | 'beforeremove', |
---|
| 222 | /** |
---|
| 223 | * @event beforemovenode |
---|
| 224 | * Fires before a node is moved to a new location in the tree. Return false to cancel the move. |
---|
| 225 | * @param {Tree} tree The owner tree |
---|
| 226 | * @param {Node} node The node being moved |
---|
| 227 | * @param {Node} oldParent The parent of the node |
---|
| 228 | * @param {Node} newParent The new parent the node is moving to |
---|
| 229 | * @param {Number} index The index it is being moved to |
---|
| 230 | */ |
---|
| 231 | 'beforemovenode', |
---|
| 232 | /** |
---|
| 233 | * @event beforeinsert |
---|
| 234 | * Fires before a new child is inserted in a node in this tree, return false to cancel the insert. |
---|
| 235 | * @param {Tree} tree The owner tree |
---|
| 236 | * @param {Node} parent The parent node |
---|
| 237 | * @param {Node} node The child node to be inserted |
---|
| 238 | * @param {Node} refNode The child node the node is being inserted before |
---|
| 239 | */ |
---|
| 240 | 'beforeinsert', |
---|
| 241 | |
---|
| 242 | /** |
---|
| 243 | * @event beforeload |
---|
| 244 | * Fires before a node is loaded, return false to cancel |
---|
| 245 | * @param {Node} node The node being loaded |
---|
| 246 | */ |
---|
| 247 | 'beforeload', |
---|
| 248 | /** |
---|
| 249 | * @event load |
---|
| 250 | * Fires when a node is loaded |
---|
| 251 | * @param {Node} node The node that was loaded |
---|
| 252 | */ |
---|
| 253 | 'load', |
---|
| 254 | /** |
---|
| 255 | * @event textchange |
---|
| 256 | * Fires when the text for a node is changed |
---|
| 257 | * @param {Node} node The node |
---|
| 258 | * @param {String} text The new text |
---|
| 259 | * @param {String} oldText The old text |
---|
| 260 | */ |
---|
| 261 | 'textchange', |
---|
| 262 | /** |
---|
| 263 | * @event beforeexpandnode |
---|
| 264 | * Fires before a node is expanded, return false to cancel. |
---|
| 265 | * @param {Node} node The node |
---|
| 266 | * @param {Boolean} deep |
---|
| 267 | * @param {Boolean} anim |
---|
| 268 | */ |
---|
| 269 | 'beforeexpandnode', |
---|
| 270 | /** |
---|
| 271 | * @event beforecollapsenode |
---|
| 272 | * Fires before a node is collapsed, return false to cancel. |
---|
| 273 | * @param {Node} node The node |
---|
| 274 | * @param {Boolean} deep |
---|
| 275 | * @param {Boolean} anim |
---|
| 276 | */ |
---|
| 277 | 'beforecollapsenode', |
---|
| 278 | /** |
---|
| 279 | * @event expandnode |
---|
| 280 | * Fires when a node is expanded |
---|
| 281 | * @param {Node} node The node |
---|
| 282 | */ |
---|
| 283 | 'expandnode', |
---|
| 284 | /** |
---|
| 285 | * @event disabledchange |
---|
| 286 | * Fires when the disabled status of a node changes |
---|
| 287 | * @param {Node} node The node |
---|
| 288 | * @param {Boolean} disabled |
---|
| 289 | */ |
---|
| 290 | 'disabledchange', |
---|
| 291 | /** |
---|
| 292 | * @event collapsenode |
---|
| 293 | * Fires when a node is collapsed |
---|
| 294 | * @param {Node} node The node |
---|
| 295 | */ |
---|
| 296 | 'collapsenode', |
---|
| 297 | /** |
---|
| 298 | * @event beforeclick |
---|
| 299 | * Fires before click processing on a node. Return false to cancel the default action. |
---|
| 300 | * @param {Node} node The node |
---|
| 301 | * @param {Ext.EventObject} e The event object |
---|
| 302 | */ |
---|
| 303 | 'beforeclick', |
---|
| 304 | /** |
---|
| 305 | * @event click |
---|
| 306 | * Fires when a node is clicked |
---|
| 307 | * @param {Node} node The node |
---|
| 308 | * @param {Ext.EventObject} e The event object |
---|
| 309 | */ |
---|
| 310 | 'click', |
---|
| 311 | /** |
---|
| 312 | * @event containerclick |
---|
| 313 | * Fires when the tree container is clicked |
---|
| 314 | * @param {Tree} this |
---|
| 315 | * @param {Ext.EventObject} e The event object |
---|
| 316 | */ |
---|
| 317 | 'containerclick', |
---|
| 318 | /** |
---|
| 319 | * @event checkchange |
---|
| 320 | * Fires when a node with a checkbox's checked property changes |
---|
| 321 | * @param {Node} this This node |
---|
| 322 | * @param {Boolean} checked |
---|
| 323 | */ |
---|
| 324 | 'checkchange', |
---|
| 325 | /** |
---|
| 326 | * @event beforedblclick |
---|
| 327 | * Fires before double click processing on a node. Return false to cancel the default action. |
---|
| 328 | * @param {Node} node The node |
---|
| 329 | * @param {Ext.EventObject} e The event object |
---|
| 330 | */ |
---|
| 331 | 'beforedblclick', |
---|
| 332 | /** |
---|
| 333 | * @event dblclick |
---|
| 334 | * Fires when a node is double clicked |
---|
| 335 | * @param {Node} node The node |
---|
| 336 | * @param {Ext.EventObject} e The event object |
---|
| 337 | */ |
---|
| 338 | 'dblclick', |
---|
| 339 | /** |
---|
| 340 | * @event containerdblclick |
---|
| 341 | * Fires when the tree container is double clicked |
---|
| 342 | * @param {Tree} this |
---|
| 343 | * @param {Ext.EventObject} e The event object |
---|
| 344 | */ |
---|
| 345 | 'containerdblclick', |
---|
| 346 | /** |
---|
| 347 | * @event contextmenu |
---|
| 348 | * Fires when a node is right clicked. To display a context menu in response to this |
---|
| 349 | * event, first create a Menu object (see {@link Ext.menu.Menu} for details), then add |
---|
| 350 | * a handler for this event:<pre><code> |
---|
| 351 | new Ext.tree.TreePanel({ |
---|
| 352 | title: 'My TreePanel', |
---|
| 353 | root: new Ext.tree.AsyncTreeNode({ |
---|
| 354 | text: 'The Root', |
---|
| 355 | children: [ |
---|
| 356 | { text: 'Child node 1', leaf: true }, |
---|
| 357 | { text: 'Child node 2', leaf: true } |
---|
| 358 | ] |
---|
| 359 | }), |
---|
| 360 | contextMenu: new Ext.menu.Menu({ |
---|
| 361 | items: [{ |
---|
| 362 | id: 'delete-node', |
---|
| 363 | text: 'Delete Node' |
---|
| 364 | }], |
---|
| 365 | listeners: { |
---|
| 366 | itemclick: function(item) { |
---|
| 367 | switch (item.id) { |
---|
| 368 | case 'delete-node': |
---|
| 369 | var n = item.parentMenu.contextNode; |
---|
| 370 | if (n.parentNode) { |
---|
| 371 | n.remove(); |
---|
| 372 | } |
---|
| 373 | break; |
---|
| 374 | } |
---|
| 375 | } |
---|
| 376 | } |
---|
| 377 | }), |
---|
| 378 | listeners: { |
---|
| 379 | contextmenu: function(node, e) { |
---|
| 380 | // Register the context node with the menu so that a Menu Item's handler function can access |
---|
| 381 | // it via its {@link Ext.menu.BaseItem#parentMenu parentMenu} property. |
---|
| 382 | node.select(); |
---|
| 383 | var c = node.getOwnerTree().contextMenu; |
---|
| 384 | c.contextNode = node; |
---|
| 385 | c.showAt(e.getXY()); |
---|
| 386 | } |
---|
| 387 | } |
---|
| 388 | }); |
---|
| 389 | </code></pre> |
---|
| 390 | * @param {Node} node The node |
---|
| 391 | * @param {Ext.EventObject} e The event object |
---|
| 392 | */ |
---|
| 393 | 'contextmenu', |
---|
| 394 | /** |
---|
| 395 | * @event containercontextmenu |
---|
| 396 | * Fires when the tree container is right clicked |
---|
| 397 | * @param {Tree} this |
---|
| 398 | * @param {Ext.EventObject} e The event object |
---|
| 399 | */ |
---|
| 400 | 'containercontextmenu', |
---|
| 401 | /** |
---|
| 402 | * @event beforechildrenrendered |
---|
| 403 | * Fires right before the child nodes for a node are rendered |
---|
| 404 | * @param {Node} node The node |
---|
| 405 | */ |
---|
| 406 | 'beforechildrenrendered', |
---|
| 407 | /** |
---|
| 408 | * @event startdrag |
---|
| 409 | * Fires when a node starts being dragged |
---|
| 410 | * @param {Ext.tree.TreePanel} this |
---|
| 411 | * @param {Ext.tree.TreeNode} node |
---|
| 412 | * @param {event} e The raw browser event |
---|
| 413 | */ |
---|
| 414 | 'startdrag', |
---|
| 415 | /** |
---|
| 416 | * @event enddrag |
---|
| 417 | * Fires when a drag operation is complete |
---|
| 418 | * @param {Ext.tree.TreePanel} this |
---|
| 419 | * @param {Ext.tree.TreeNode} node |
---|
| 420 | * @param {event} e The raw browser event |
---|
| 421 | */ |
---|
| 422 | 'enddrag', |
---|
| 423 | /** |
---|
| 424 | * @event dragdrop |
---|
| 425 | * Fires when a dragged node is dropped on a valid DD target |
---|
| 426 | * @param {Ext.tree.TreePanel} this |
---|
| 427 | * @param {Ext.tree.TreeNode} node |
---|
| 428 | * @param {DD} dd The dd it was dropped on |
---|
| 429 | * @param {event} e The raw browser event |
---|
| 430 | */ |
---|
| 431 | 'dragdrop', |
---|
| 432 | /** |
---|
| 433 | * @event beforenodedrop |
---|
| 434 | * Fires when a DD object is dropped on a node in this tree for preprocessing. Return false to cancel the drop. The dropEvent |
---|
| 435 | * passed to handlers has the following properties:<br /> |
---|
| 436 | * <ul style="padding:5px;padding-left:16px;"> |
---|
| 437 | * <li>tree - The TreePanel</li> |
---|
| 438 | * <li>target - The node being targeted for the drop</li> |
---|
| 439 | * <li>data - The drag data from the drag source</li> |
---|
| 440 | * <li>point - The point of the drop - append, above or below</li> |
---|
| 441 | * <li>source - The drag source</li> |
---|
| 442 | * <li>rawEvent - Raw mouse event</li> |
---|
| 443 | * <li>dropNode - Drop node(s) provided by the source <b>OR</b> you can supply node(s) |
---|
| 444 | * to be inserted by setting them on this object.</li> |
---|
| 445 | * <li>cancel - Set this to true to cancel the drop.</li> |
---|
| 446 | * <li>dropStatus - If the default drop action is cancelled but the drop is valid, setting this to true |
---|
| 447 | * will prevent the animated 'repair' from appearing.</li> |
---|
| 448 | * </ul> |
---|
| 449 | * @param {Object} dropEvent |
---|
| 450 | */ |
---|
| 451 | 'beforenodedrop', |
---|
| 452 | /** |
---|
| 453 | * @event nodedrop |
---|
| 454 | * Fires after a DD object is dropped on a node in this tree. The dropEvent |
---|
| 455 | * passed to handlers has the following properties:<br /> |
---|
| 456 | * <ul style="padding:5px;padding-left:16px;"> |
---|
| 457 | * <li>tree - The TreePanel</li> |
---|
| 458 | * <li>target - The node being targeted for the drop</li> |
---|
| 459 | * <li>data - The drag data from the drag source</li> |
---|
| 460 | * <li>point - The point of the drop - append, above or below</li> |
---|
| 461 | * <li>source - The drag source</li> |
---|
| 462 | * <li>rawEvent - Raw mouse event</li> |
---|
| 463 | * <li>dropNode - Dropped node(s).</li> |
---|
| 464 | * </ul> |
---|
| 465 | * @param {Object} dropEvent |
---|
| 466 | */ |
---|
| 467 | 'nodedrop', |
---|
| 468 | /** |
---|
| 469 | * @event nodedragover |
---|
| 470 | * Fires when a tree node is being targeted for a drag drop, return false to signal drop not allowed. The dragOverEvent |
---|
| 471 | * passed to handlers has the following properties:<br /> |
---|
| 472 | * <ul style="padding:5px;padding-left:16px;"> |
---|
| 473 | * <li>tree - The TreePanel</li> |
---|
| 474 | * <li>target - The node being targeted for the drop</li> |
---|
| 475 | * <li>data - The drag data from the drag source</li> |
---|
| 476 | * <li>point - The point of the drop - append, above or below</li> |
---|
| 477 | * <li>source - The drag source</li> |
---|
| 478 | * <li>rawEvent - Raw mouse event</li> |
---|
| 479 | * <li>dropNode - Drop node(s) provided by the source.</li> |
---|
| 480 | * <li>cancel - Set this to true to signal drop not allowed.</li> |
---|
| 481 | * </ul> |
---|
| 482 | * @param {Object} dragOverEvent |
---|
| 483 | */ |
---|
| 484 | 'nodedragover' |
---|
| 485 | ); |
---|
| 486 | if(this.singleExpand){ |
---|
| 487 | this.on('beforeexpandnode', this.restrictExpand, this); |
---|
| 488 | } |
---|
| 489 | }, |
---|
| 490 | |
---|
| 491 | // private |
---|
| 492 | proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){ |
---|
| 493 | if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){ |
---|
| 494 | ename = ename+'node'; |
---|
| 495 | } |
---|
| 496 | // args inline for performance while bubbling events |
---|
| 497 | return this.fireEvent(ename, a1, a2, a3, a4, a5, a6); |
---|
| 498 | }, |
---|
| 499 | |
---|
| 500 | |
---|
| 501 | /** |
---|
| 502 | * Returns this root node for this tree |
---|
| 503 | * @return {Node} |
---|
| 504 | */ |
---|
| 505 | getRootNode : function(){ |
---|
| 506 | return this.root; |
---|
| 507 | }, |
---|
| 508 | |
---|
| 509 | /** |
---|
| 510 | * Sets the root node for this tree. If the TreePanel has already rendered a root node, the |
---|
| 511 | * previous root node (and all of its descendants) are destroyed before the new root node is rendered. |
---|
| 512 | * @param {Node} node |
---|
| 513 | * @return {Node} |
---|
| 514 | */ |
---|
| 515 | setRootNode : function(node){ |
---|
| 516 | this.destroyRoot(); |
---|
| 517 | if(!node.render){ // attributes passed |
---|
| 518 | node = this.loader.createNode(node); |
---|
| 519 | } |
---|
| 520 | this.root = node; |
---|
| 521 | node.ownerTree = this; |
---|
| 522 | node.isRoot = true; |
---|
| 523 | this.registerNode(node); |
---|
| 524 | if(!this.rootVisible){ |
---|
| 525 | var uiP = node.attributes.uiProvider; |
---|
| 526 | node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node); |
---|
| 527 | } |
---|
| 528 | if(this.innerCt){ |
---|
| 529 | this.clearInnerCt(); |
---|
| 530 | this.renderRoot(); |
---|
| 531 | } |
---|
| 532 | return node; |
---|
| 533 | }, |
---|
| 534 | |
---|
| 535 | clearInnerCt : function(){ |
---|
| 536 | this.innerCt.update(''); |
---|
| 537 | }, |
---|
| 538 | |
---|
| 539 | // private |
---|
| 540 | renderRoot : function(){ |
---|
| 541 | this.root.render(); |
---|
| 542 | if(!this.rootVisible){ |
---|
| 543 | this.root.renderChildren(); |
---|
| 544 | } |
---|
| 545 | }, |
---|
| 546 | |
---|
| 547 | /** |
---|
| 548 | * Gets a node in this tree by its id |
---|
| 549 | * @param {String} id |
---|
| 550 | * @return {Node} |
---|
| 551 | */ |
---|
| 552 | getNodeById : function(id){ |
---|
| 553 | return this.nodeHash[id]; |
---|
| 554 | }, |
---|
| 555 | |
---|
| 556 | // private |
---|
| 557 | registerNode : function(node){ |
---|
| 558 | this.nodeHash[node.id] = node; |
---|
| 559 | }, |
---|
| 560 | |
---|
| 561 | // private |
---|
| 562 | unregisterNode : function(node){ |
---|
| 563 | delete this.nodeHash[node.id]; |
---|
| 564 | }, |
---|
| 565 | |
---|
| 566 | // private |
---|
| 567 | toString : function(){ |
---|
| 568 | return '[Tree'+(this.id?' '+this.id:'')+']'; |
---|
| 569 | }, |
---|
| 570 | |
---|
| 571 | // private |
---|
| 572 | restrictExpand : function(node){ |
---|
| 573 | var p = node.parentNode; |
---|
| 574 | if(p){ |
---|
| 575 | if(p.expandedChild && p.expandedChild.parentNode == p){ |
---|
| 576 | p.expandedChild.collapse(); |
---|
| 577 | } |
---|
| 578 | p.expandedChild = node; |
---|
| 579 | } |
---|
| 580 | }, |
---|
| 581 | |
---|
| 582 | /** |
---|
| 583 | * Retrieve an array of checked nodes, or an array of a specific attribute of checked nodes (e.g. 'id') |
---|
| 584 | * @param {String} attribute (optional) Defaults to null (return the actual nodes) |
---|
| 585 | * @param {TreeNode} startNode (optional) The node to start from, defaults to the root |
---|
| 586 | * @return {Array} |
---|
| 587 | */ |
---|
| 588 | getChecked : function(a, startNode){ |
---|
| 589 | startNode = startNode || this.root; |
---|
| 590 | var r = []; |
---|
| 591 | var f = function(){ |
---|
| 592 | if(this.attributes.checked){ |
---|
| 593 | r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a])); |
---|
| 594 | } |
---|
| 595 | }; |
---|
| 596 | startNode.cascade(f); |
---|
| 597 | return r; |
---|
| 598 | }, |
---|
| 599 | |
---|
| 600 | /** |
---|
| 601 | * Returns the default {@link Ext.tree.TreeLoader} for this TreePanel. |
---|
| 602 | * @return {Ext.tree.TreeLoader} The TreeLoader for this TreePanel. |
---|
| 603 | */ |
---|
| 604 | getLoader : function(){ |
---|
| 605 | return this.loader; |
---|
| 606 | }, |
---|
| 607 | |
---|
| 608 | /** |
---|
| 609 | * Expand all nodes |
---|
| 610 | */ |
---|
| 611 | expandAll : function(){ |
---|
| 612 | this.root.expand(true); |
---|
| 613 | }, |
---|
| 614 | |
---|
| 615 | /** |
---|
| 616 | * Collapse all nodes |
---|
| 617 | */ |
---|
| 618 | collapseAll : function(){ |
---|
| 619 | this.root.collapse(true); |
---|
| 620 | }, |
---|
| 621 | |
---|
| 622 | /** |
---|
| 623 | * Returns the selection model used by this TreePanel. |
---|
| 624 | * @return {TreeSelectionModel} The selection model used by this TreePanel |
---|
| 625 | */ |
---|
| 626 | getSelectionModel : function(){ |
---|
| 627 | if(!this.selModel){ |
---|
| 628 | this.selModel = new Ext.tree.DefaultSelectionModel(); |
---|
| 629 | } |
---|
| 630 | return this.selModel; |
---|
| 631 | }, |
---|
| 632 | |
---|
| 633 | /** |
---|
| 634 | * Expands a specified path in this TreePanel. A path can be retrieved from a node with {@link Ext.data.Node#getPath} |
---|
| 635 | * @param {String} path |
---|
| 636 | * @param {String} attr (optional) The attribute used in the path (see {@link Ext.data.Node#getPath} for more info) |
---|
| 637 | * @param {Function} callback (optional) The callback to call when the expand is complete. The callback will be called with |
---|
| 638 | * (bSuccess, oLastNode) where bSuccess is if the expand was successful and oLastNode is the last node that was expanded. |
---|
| 639 | */ |
---|
| 640 | expandPath : function(path, attr, callback){ |
---|
| 641 | if(Ext.isEmpty(path)){ |
---|
| 642 | if(callback){ |
---|
| 643 | callback(false, undefined); |
---|
| 644 | } |
---|
| 645 | return; |
---|
| 646 | } |
---|
| 647 | attr = attr || 'id'; |
---|
| 648 | var keys = path.split(this.pathSeparator); |
---|
| 649 | var curNode = this.root; |
---|
| 650 | if(curNode.attributes[attr] != keys[1]){ // invalid root |
---|
| 651 | if(callback){ |
---|
| 652 | callback(false, null); |
---|
| 653 | } |
---|
| 654 | return; |
---|
| 655 | } |
---|
| 656 | var index = 1; |
---|
| 657 | var f = function(){ |
---|
| 658 | if(++index == keys.length){ |
---|
| 659 | if(callback){ |
---|
| 660 | callback(true, curNode); |
---|
| 661 | } |
---|
| 662 | return; |
---|
| 663 | } |
---|
| 664 | var c = curNode.findChild(attr, keys[index]); |
---|
| 665 | if(!c){ |
---|
| 666 | if(callback){ |
---|
| 667 | callback(false, curNode); |
---|
| 668 | } |
---|
| 669 | return; |
---|
| 670 | } |
---|
| 671 | curNode = c; |
---|
| 672 | c.expand(false, false, f); |
---|
| 673 | }; |
---|
| 674 | curNode.expand(false, false, f); |
---|
| 675 | }, |
---|
| 676 | |
---|
| 677 | /** |
---|
| 678 | * Selects the node in this tree at the specified path. A path can be retrieved from a node with {@link Ext.data.Node#getPath} |
---|
| 679 | * @param {String} path |
---|
| 680 | * @param {String} attr (optional) The attribute used in the path (see {@link Ext.data.Node#getPath} for more info) |
---|
| 681 | * @param {Function} callback (optional) The callback to call when the selection is complete. The callback will be called with |
---|
| 682 | * (bSuccess, oSelNode) where bSuccess is if the selection was successful and oSelNode is the selected node. |
---|
| 683 | */ |
---|
| 684 | selectPath : function(path, attr, callback){ |
---|
| 685 | if(Ext.isEmpty(path)){ |
---|
| 686 | if(callback){ |
---|
| 687 | callback(false, undefined); |
---|
| 688 | } |
---|
| 689 | return; |
---|
| 690 | } |
---|
| 691 | attr = attr || 'id'; |
---|
| 692 | var keys = path.split(this.pathSeparator), |
---|
| 693 | v = keys.pop(); |
---|
| 694 | if(keys.length > 1){ |
---|
| 695 | var f = function(success, node){ |
---|
| 696 | if(success && node){ |
---|
| 697 | var n = node.findChild(attr, v); |
---|
| 698 | if(n){ |
---|
| 699 | n.select(); |
---|
| 700 | if(callback){ |
---|
| 701 | callback(true, n); |
---|
| 702 | } |
---|
| 703 | }else if(callback){ |
---|
| 704 | callback(false, n); |
---|
| 705 | } |
---|
| 706 | }else{ |
---|
| 707 | if(callback){ |
---|
| 708 | callback(false, n); |
---|
| 709 | } |
---|
| 710 | } |
---|
| 711 | }; |
---|
| 712 | this.expandPath(keys.join(this.pathSeparator), attr, f); |
---|
| 713 | }else{ |
---|
| 714 | this.root.select(); |
---|
| 715 | if(callback){ |
---|
| 716 | callback(true, this.root); |
---|
| 717 | } |
---|
| 718 | } |
---|
| 719 | }, |
---|
| 720 | |
---|
| 721 | /** |
---|
| 722 | * Returns the underlying Element for this tree |
---|
| 723 | * @return {Ext.Element} The Element |
---|
| 724 | */ |
---|
| 725 | getTreeEl : function(){ |
---|
| 726 | return this.body; |
---|
| 727 | }, |
---|
| 728 | |
---|
| 729 | // private |
---|
| 730 | onRender : function(ct, position){ |
---|
| 731 | Ext.tree.TreePanel.superclass.onRender.call(this, ct, position); |
---|
| 732 | this.el.addClass('x-tree'); |
---|
| 733 | this.innerCt = this.body.createChild({tag:'ul', |
---|
| 734 | cls:'x-tree-root-ct ' + |
---|
| 735 | (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')}); |
---|
| 736 | }, |
---|
| 737 | |
---|
| 738 | // private |
---|
| 739 | initEvents : function(){ |
---|
| 740 | Ext.tree.TreePanel.superclass.initEvents.call(this); |
---|
| 741 | |
---|
| 742 | if(this.containerScroll){ |
---|
| 743 | Ext.dd.ScrollManager.register(this.body); |
---|
| 744 | } |
---|
| 745 | if((this.enableDD || this.enableDrop) && !this.dropZone){ |
---|
| 746 | /** |
---|
| 747 | * The dropZone used by this tree if drop is enabled (see {@link #enableDD} or {@link #enableDrop}) |
---|
| 748 | * @property dropZone |
---|
| 749 | * @type Ext.tree.TreeDropZone |
---|
| 750 | */ |
---|
| 751 | this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || { |
---|
| 752 | ddGroup: this.ddGroup || 'TreeDD', appendOnly: this.ddAppendOnly === true |
---|
| 753 | }); |
---|
| 754 | } |
---|
| 755 | if((this.enableDD || this.enableDrag) && !this.dragZone){ |
---|
| 756 | /** |
---|
| 757 | * The dragZone used by this tree if drag is enabled (see {@link #enableDD} or {@link #enableDrag}) |
---|
| 758 | * @property dragZone |
---|
| 759 | * @type Ext.tree.TreeDragZone |
---|
| 760 | */ |
---|
| 761 | this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || { |
---|
| 762 | ddGroup: this.ddGroup || 'TreeDD', |
---|
| 763 | scroll: this.ddScroll |
---|
| 764 | }); |
---|
| 765 | } |
---|
| 766 | this.getSelectionModel().init(this); |
---|
| 767 | }, |
---|
| 768 | |
---|
| 769 | // private |
---|
| 770 | afterRender : function(){ |
---|
| 771 | Ext.tree.TreePanel.superclass.afterRender.call(this); |
---|
| 772 | this.renderRoot(); |
---|
| 773 | }, |
---|
| 774 | |
---|
| 775 | beforeDestroy : function(){ |
---|
| 776 | if(this.rendered){ |
---|
| 777 | Ext.dd.ScrollManager.unregister(this.body); |
---|
| 778 | Ext.destroy(this.dropZone, this.dragZone); |
---|
| 779 | } |
---|
| 780 | this.destroyRoot(); |
---|
| 781 | Ext.destroy(this.loader); |
---|
| 782 | this.nodeHash = this.root = this.loader = null; |
---|
| 783 | Ext.tree.TreePanel.superclass.beforeDestroy.call(this); |
---|
| 784 | }, |
---|
| 785 | |
---|
| 786 | /** |
---|
| 787 | * Destroy the root node. Not included by itself because we need to pass the silent parameter. |
---|
| 788 | * @private |
---|
| 789 | */ |
---|
| 790 | destroyRoot : function(){ |
---|
| 791 | if(this.root && this.root.destroy){ |
---|
| 792 | this.root.destroy(true); |
---|
| 793 | } |
---|
| 794 | } |
---|
| 795 | |
---|
| 796 | /** |
---|
| 797 | * @cfg {String/Number} activeItem |
---|
| 798 | * @hide |
---|
| 799 | */ |
---|
| 800 | /** |
---|
| 801 | * @cfg {Boolean} autoDestroy |
---|
| 802 | * @hide |
---|
| 803 | */ |
---|
| 804 | /** |
---|
| 805 | * @cfg {Object/String/Function} autoLoad |
---|
| 806 | * @hide |
---|
| 807 | */ |
---|
| 808 | /** |
---|
| 809 | * @cfg {Boolean} autoWidth |
---|
| 810 | * @hide |
---|
| 811 | */ |
---|
| 812 | /** |
---|
| 813 | * @cfg {Boolean/Number} bufferResize |
---|
| 814 | * @hide |
---|
| 815 | */ |
---|
| 816 | /** |
---|
| 817 | * @cfg {String} defaultType |
---|
| 818 | * @hide |
---|
| 819 | */ |
---|
| 820 | /** |
---|
| 821 | * @cfg {Object} defaults |
---|
| 822 | * @hide |
---|
| 823 | */ |
---|
| 824 | /** |
---|
| 825 | * @cfg {Boolean} hideBorders |
---|
| 826 | * @hide |
---|
| 827 | */ |
---|
| 828 | /** |
---|
| 829 | * @cfg {Mixed} items |
---|
| 830 | * @hide |
---|
| 831 | */ |
---|
| 832 | /** |
---|
| 833 | * @cfg {String} layout |
---|
| 834 | * @hide |
---|
| 835 | */ |
---|
| 836 | /** |
---|
| 837 | * @cfg {Object} layoutConfig |
---|
| 838 | * @hide |
---|
| 839 | */ |
---|
| 840 | /** |
---|
| 841 | * @cfg {Boolean} monitorResize |
---|
| 842 | * @hide |
---|
| 843 | */ |
---|
| 844 | /** |
---|
| 845 | * @property items |
---|
| 846 | * @hide |
---|
| 847 | */ |
---|
| 848 | /** |
---|
| 849 | * @method cascade |
---|
| 850 | * @hide |
---|
| 851 | */ |
---|
| 852 | /** |
---|
| 853 | * @method doLayout |
---|
| 854 | * @hide |
---|
| 855 | */ |
---|
| 856 | /** |
---|
| 857 | * @method find |
---|
| 858 | * @hide |
---|
| 859 | */ |
---|
| 860 | /** |
---|
| 861 | * @method findBy |
---|
| 862 | * @hide |
---|
| 863 | */ |
---|
| 864 | /** |
---|
| 865 | * @method findById |
---|
| 866 | * @hide |
---|
| 867 | */ |
---|
| 868 | /** |
---|
| 869 | * @method findByType |
---|
| 870 | * @hide |
---|
| 871 | */ |
---|
| 872 | /** |
---|
| 873 | * @method getComponent |
---|
| 874 | * @hide |
---|
| 875 | */ |
---|
| 876 | /** |
---|
| 877 | * @method getLayout |
---|
| 878 | * @hide |
---|
| 879 | */ |
---|
| 880 | /** |
---|
| 881 | * @method getUpdater |
---|
| 882 | * @hide |
---|
| 883 | */ |
---|
| 884 | /** |
---|
| 885 | * @method insert |
---|
| 886 | * @hide |
---|
| 887 | */ |
---|
| 888 | /** |
---|
| 889 | * @method load |
---|
| 890 | * @hide |
---|
| 891 | */ |
---|
| 892 | /** |
---|
| 893 | * @method remove |
---|
| 894 | * @hide |
---|
| 895 | */ |
---|
| 896 | /** |
---|
| 897 | * @event add |
---|
| 898 | * @hide |
---|
| 899 | */ |
---|
| 900 | /** |
---|
| 901 | * @method removeAll |
---|
| 902 | * @hide |
---|
| 903 | */ |
---|
| 904 | /** |
---|
| 905 | * @event afterLayout |
---|
| 906 | * @hide |
---|
| 907 | */ |
---|
| 908 | /** |
---|
| 909 | * @event beforeadd |
---|
| 910 | * @hide |
---|
| 911 | */ |
---|
| 912 | /** |
---|
| 913 | * @event beforeremove |
---|
| 914 | * @hide |
---|
| 915 | */ |
---|
| 916 | /** |
---|
| 917 | * @event remove |
---|
| 918 | * @hide |
---|
| 919 | */ |
---|
| 920 | |
---|
| 921 | |
---|
| 922 | |
---|
| 923 | /** |
---|
| 924 | * @cfg {String} allowDomMove @hide |
---|
| 925 | */ |
---|
| 926 | /** |
---|
| 927 | * @cfg {String} autoEl @hide |
---|
| 928 | */ |
---|
| 929 | /** |
---|
| 930 | * @cfg {String} applyTo @hide |
---|
| 931 | */ |
---|
| 932 | /** |
---|
| 933 | * @cfg {String} contentEl @hide |
---|
| 934 | */ |
---|
| 935 | /** |
---|
| 936 | * @cfg {Mixed} data @hide |
---|
| 937 | */ |
---|
| 938 | /** |
---|
| 939 | * @cfg {Mixed} tpl @hide |
---|
| 940 | */ |
---|
| 941 | /** |
---|
| 942 | * @cfg {String} tplWriteMode @hide |
---|
| 943 | */ |
---|
| 944 | /** |
---|
| 945 | * @cfg {String} disabledClass @hide |
---|
| 946 | */ |
---|
| 947 | /** |
---|
| 948 | * @cfg {String} elements @hide |
---|
| 949 | */ |
---|
| 950 | /** |
---|
| 951 | * @cfg {String} html @hide |
---|
| 952 | */ |
---|
| 953 | /** |
---|
| 954 | * @cfg {Boolean} preventBodyReset |
---|
| 955 | * @hide |
---|
| 956 | */ |
---|
| 957 | /** |
---|
| 958 | * @property disabled |
---|
| 959 | * @hide |
---|
| 960 | */ |
---|
| 961 | /** |
---|
| 962 | * @method applyToMarkup |
---|
| 963 | * @hide |
---|
| 964 | */ |
---|
| 965 | /** |
---|
| 966 | * @method enable |
---|
| 967 | * @hide |
---|
| 968 | */ |
---|
| 969 | /** |
---|
| 970 | * @method disable |
---|
| 971 | * @hide |
---|
| 972 | */ |
---|
| 973 | /** |
---|
| 974 | * @method setDisabled |
---|
| 975 | * @hide |
---|
| 976 | */ |
---|
| 977 | }); |
---|
| 978 | |
---|
| 979 | Ext.tree.TreePanel.nodeTypes = {}; |
---|
| 980 | |
---|
| 981 | Ext.reg('treepanel', Ext.tree.TreePanel); |
---|