1 <!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-tree.View'>/**
2 </span> * @class Ext.tree.View
3 * @extends Ext.view.Table
5 Ext.define('Ext.tree.View', {
6 extend: 'Ext.view.Table',
7 alias: 'widget.treeview',
9 loadingCls: Ext.baseCSSPrefix + 'grid-tree-loading',
10 expandedCls: Ext.baseCSSPrefix + 'grid-tree-node-expanded',
12 expanderSelector: '.' + Ext.baseCSSPrefix + 'tree-expander',
13 checkboxSelector: '.' + Ext.baseCSSPrefix + 'tree-checkbox',
14 expanderIconOverCls: Ext.baseCSSPrefix + 'tree-expander-over',
18 <span id='Ext-tree.View-cfg-rootVisible'> /**
19 </span> * @cfg {Boolean} rootVisible <tt>false</tt> to hide the root node (defaults to <tt>true</tt>)
23 <span id='Ext-tree.View-cfg-animate'> /**
24 </span> * @cfg {Boolean} animate <tt>true</tt> to enable animated expand/collapse (defaults to the value of {@link Ext#enableFx Ext.enableFx})
28 collapseDuration: 250,
30 toggleOnDblClick: true,
32 initComponent: function() {
35 if (me.initialConfig.animate === undefined) {
36 me.animate = Ext.enableFx;
39 me.store = Ext.create('Ext.data.NodeStore', {
41 rootVisible: me.rootVisible,
43 beforeexpand: me.onBeforeExpand,
45 beforecollapse: me.onBeforeCollapse,
46 collapse: me.onCollapse,
52 me.setRootNode(me.node);
55 me.callParent(arguments);
59 this.store.removeAll();
62 setRootNode: function(node) {
64 me.store.setNode(node);
66 if (!me.rootVisible) {
71 onRender: function() {
73 opts = {delegate: me.expanderSelector},
76 me.callParent(arguments);
81 delegate: me.expanderSelector,
82 mouseover: me.onExpanderMouseOver,
83 mouseout: me.onExpanderMouseOut
87 delegate: me.checkboxSelector,
88 click: me.onCheckboxChange
92 onCheckboxChange: function(e, t) {
93 var item = e.getTarget(this.getItemSelector(), this.getTargetEl()),
97 record = this.getRecord(item);
98 value = !record.get('checked');
99 record.set('checked', value);
100 this.fireEvent('checkchange', record, value);
104 getChecked: function() {
106 this.node.cascadeBy(function(rec){
107 if (rec.get('checked')) {
114 isItemChecked: function(rec){
115 return rec.get('checked');
118 createAnimWrap: function(record, index) {
120 headerCt = this.panel.headerCt,
121 headers = headerCt.getGridColumns(),
122 i = 0, len = headers.length, item,
123 node = this.getNode(record),
126 for (; i < len; i++) {
128 thHtml += '<th style="width: ' + (item.hidden ? 0 : item.getDesiredWidth()) + 'px; height: 0px;"></th>';
131 nodeEl = Ext.get(node);
132 tmpEl = nodeEl.insertSibling({
135 '<td colspan="' + headerCt.getColumnCount() + '">',
136 '<div class="' + Ext.baseCSSPrefix + 'tree-animator-wrap' + '">',
137 '<table class="' + Ext.baseCSSPrefix + 'grid-table" style="width: ' + headerCt.getFullWidth() + 'px;"><tbody>',
139 '</tbody></table>',
152 animateEl: tmpEl.down('div'),
153 targetEl: tmpEl.down('tbody')
157 getAnimWrap: function(parent) {
162 // We are checking to see which parent is having the animation wrap
164 if (parent.animWrap) {
165 return parent.animWrap;
167 parent = parent.parentNode;
172 doAdd: function(nodes, records, index) {
173 // If we are adding records which have a parent that is currently expanding
174 // lets add them to the animation wrap
177 parent = record.parentNode,
180 animWrap = me.getAnimWrap(parent),
181 targetEl, children, len;
183 if (!animWrap || !animWrap.expanding) {
185 return me.callParent(arguments);
188 // We need the parent that has the animWrap, not the nodes parent
189 parent = animWrap.record;
191 // If there is an anim wrap we do our special magic logic
192 targetEl = animWrap.targetEl;
193 children = targetEl.dom.childNodes;
195 // We subtract 1 from the childrens length because we have a tr in there with the th'es
196 len = children.length - 1;
198 // The relative index is the index in the full flat collection minus the index of the wraps parent
199 relativeIndex = index - me.indexOf(parent) - 1;
201 // If we are adding records to the wrap that have a higher relative index then there are currently children
202 // it means we have to append the nodes to the wrap
203 if (!len || relativeIndex >= len) {
204 targetEl.appendChild(nodes);
206 // If there are already more children then the relative index it means we are adding child nodes of
207 // some expanded node in the anim wrap. In this case we have to insert the nodes in the right location
209 // +1 because of the tr with th'es that is already there
210 Ext.fly(children[relativeIndex + 1]).insertSibling(nodes, 'before', true);
213 // We also have to update the CompositeElementLite collection of the DataView
214 if (index < a.length) {
215 a.splice.apply(a, [index, 0].concat(nodes));
218 a.push.apply(a, nodes);
221 // If we were in an animation we need to now change the animation
222 // because the targetEl just got higher.
223 if (animWrap.isAnimating) {
228 doRemove: function(record, index) {
229 // If we are adding records which have a parent that is currently expanding
230 // lets add them to the animation wrap
232 parent = record.parentNode,
234 animWrap = me.getAnimWrap(record),
235 node = all.item(index).dom;
237 if (!animWrap || !animWrap.collapsing) {
239 return me.callParent(arguments);
242 animWrap.targetEl.appendChild(node);
243 all.removeElement(index);
246 onBeforeExpand: function(parent, records, index) {
254 if (me.getNode(parent)) {
255 animWrap = me.getAnimWrap(parent);
257 animWrap = parent.animWrap = me.createAnimWrap(parent);
258 animWrap.animateEl.setHeight(0);
260 else if (animWrap.collapsing) {
261 // If we expand this node while it is still expanding then we
262 // have to remove the nodes from the animWrap.
263 animWrap.targetEl.select(me.itemSelector).remove();
265 animWrap.expanding = true;
266 animWrap.collapsing = false;
270 onExpand: function(parent) {
272 queue = me.animQueue,
279 if (me.singleExpand) {
280 me.ensureSingleExpand(parent);
283 animWrap = me.getAnimWrap(parent);
290 animateEl = animWrap.animateEl;
291 targetEl = animWrap.targetEl;
293 animateEl.stopAnimation();
294 // @TODO: we are setting it to 1 because quirks mode on IE seems to have issues with 0
296 animateEl.slideIn('t', {
297 duration: me.expandDuration,
300 lastframe: function() {
301 // Move all the nodes out of the anim wrap to their proper location
302 animWrap.el.insertSibling(targetEl.query(me.itemSelector), 'before');
303 animWrap.el.remove();
305 delete animWrap.record.animWrap;
311 animWrap.isAnimating = true;
314 resetScrollers: function(){
315 var panel = this.panel;
317 panel.determineScrollbars();
318 panel.invalidateScroller();
321 onBeforeCollapse: function(parent, records, index) {
329 if (me.getNode(parent)) {
330 animWrap = me.getAnimWrap(parent);
332 animWrap = parent.animWrap = me.createAnimWrap(parent, index);
334 else if (animWrap.expanding) {
335 // If we collapse this node while it is still expanding then we
336 // have to remove the nodes from the animWrap.
337 animWrap.targetEl.select(this.itemSelector).remove();
339 animWrap.expanding = false;
340 animWrap.collapsing = true;
344 onCollapse: function(parent) {
346 queue = me.animQueue,
348 animWrap = me.getAnimWrap(parent),
356 animateEl = animWrap.animateEl;
357 targetEl = animWrap.targetEl;
361 // @TODO: we are setting it to 1 because quirks mode on IE seems to have issues with 0
362 animateEl.stopAnimation();
363 animateEl.slideOut('t', {
364 duration: me.collapseDuration,
367 lastframe: function() {
368 animWrap.el.remove();
369 delete animWrap.record.animWrap;
375 animWrap.isAnimating = true;
378 <span id='Ext-tree.View-method-isAnimating'> /**
379 </span> * Checks if a node is currently undergoing animation
381 * @param {Ext.data.Model} node The node
382 * @return {Boolean} True if the node is animating
384 isAnimating: function(node) {
385 return !!this.animQueue[node.getId()];
388 collectData: function(records) {
389 var data = this.callParent(arguments),
395 for (; i < len; i++) {
398 if (record.get('qtip')) {
399 row.rowAttr = 'data-qtip="' + record.get('qtip') + '"';
400 if (record.get('qtitle')) {
401 row.rowAttr += ' ' + 'data-qtitle="' + record.get('qtitle') + '"';
404 if (record.isExpanded()) {
405 row.rowCls = (row.rowCls || '') + ' ' + this.expandedCls;
407 if (record.isLoading()) {
408 row.rowCls = (row.rowCls || '') + ' ' + this.loadingCls;
415 <span id='Ext-tree.View-method-expand'> /**
416 </span> * Expand a record that is loaded in the view.
417 * @param {Ext.data.Model} record The record to expand
418 * @param {Boolean} deep (optional) True to expand nodes all the way down the tree hierarchy.
419 * @param {Function} callback (optional) The function to run after the expand is completed
420 * @param {Object} scope (optional) The scope of the callback function.
422 expand: function(record, deep, callback, scope) {
423 return record.expand(deep, callback, scope);
426 <span id='Ext-tree.View-method-collapse'> /**
427 </span> * Collapse a record that is loaded in the view.
428 * @param {Ext.data.Model} record The record to collapse
429 * @param {Boolean} deep (optional) True to collapse nodes all the way up the tree hierarchy.
430 * @param {Function} callback (optional) The function to run after the collapse is completed
431 * @param {Object} scope (optional) The scope of the callback function.
433 collapse: function(record, deep, callback, scope) {
434 return record.collapse(deep, callback, scope);
437 <span id='Ext-tree.View-method-toggle'> /**
438 </span> * Toggle a record between expanded and collapsed.
439 * @param {Ext.data.Record} recordInstance
441 toggle: function(record) {
442 this[record.isExpanded() ? 'collapse' : 'expand'](record);
445 onItemDblClick: function(record, item, index) {
446 this.callParent(arguments);
447 if (this.toggleOnDblClick) {
452 onBeforeItemMouseDown: function(record, item, index, e) {
453 if (e.getTarget(this.expanderSelector, item)) {
456 return this.callParent(arguments);
459 onItemClick: function(record, item, index, e) {
460 if (e.getTarget(this.expanderSelector, item)) {
464 return this.callParent(arguments);
467 onExpanderMouseOver: function(e, t) {
468 e.getTarget(this.cellSelector, 10, true).addCls(this.expanderIconOverCls);
471 onExpanderMouseOut: function(e, t) {
472 e.getTarget(this.cellSelector, 10, true).removeCls(this.expanderIconOverCls);
475 <span id='Ext-tree.View-method-getTreeStore'> /**
476 </span> * Gets the base TreeStore from the bound TreePanel.
478 getTreeStore: function() {
479 return this.panel.store;
482 ensureSingleExpand: function(node) {
483 var parent = node.parentNode;
485 parent.eachChild(function(child) {
486 if (child !== node && child.isExpanded()) {
492 });</pre></pre></body></html>