Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / View3.html
index a9d033f..91c04c5 100644 (file)
   </script>
 </head>
 <body onload="prettyPrint(); highlight();">
-  <pre class="prettyprint lang-js"><span id='Ext-view-View'>/**
-</span> * @class Ext.view.View
- * @extends Ext.view.AbstractView
- *
- * A mechanism for displaying data using custom layout templates and formatting. DataView uses an {@link Ext.XTemplate}
- * as its internal templating mechanism, and is bound to an {@link Ext.data.Store}
- * so that as the data in the store changes the view is automatically updated to reflect the changes.  The view also
- * provides built-in behavior for many common events that can occur for its contained items including click, doubleclick,
- * mouseover, mouseout, etc. as well as a built-in selection model. &lt;b&gt;In order to use these features, an {@link #itemSelector}
- * config must be provided for the DataView to determine what nodes it will be working with.&lt;/b&gt;
- *
- * The example below binds a DataView to a {@link Ext.data.Store} and renders it into an {@link Ext.panel.Panel}.
- *
- * {@img Ext.DataView/Ext.DataView.png Ext.DataView component}
- *
- *     Ext.regModel('Image', {
- *         Fields: [
- *             {name:'src', type:'string'},
- *             {name:'caption', type:'string'}
- *         ]
- *     });
- *     
- *     Ext.create('Ext.data.Store', {
- *         id:'imagesStore',
- *         model: 'Image',
- *         data: [
- *             {src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing &amp; Charts'},
- *             {src:'http://www.sencha.com/img/20110215-feat-data.png', caption:'Advanced Data'},
- *             {src:'http://www.sencha.com/img/20110215-feat-html5.png', caption:'Overhauled Theme'},
- *             {src:'http://www.sencha.com/img/20110215-feat-perf.png', caption:'Performance Tuned'}            
- *         ]
- *     });
- *     
- *     var imageTpl = new Ext.XTemplate(
- *         '&amp;lt;tpl for=&quot;.&quot;&amp;gt;',
- *             '&amp;lt;div style=&quot;thumb-wrap&quot;&amp;gt;',
- *               '&amp;lt;img src=&quot;{src}&quot; /&amp;gt;',
- *               '&amp;lt;br/&amp;gt;&amp;lt;span&amp;gt;{caption}&amp;lt;/span&amp;gt;',
- *             '&amp;lt;/div&amp;gt;',
- *         '&amp;lt;/tpl&amp;gt;'
- *     );
- *     
- *     Ext.create('Ext.DataView', {
- *         store: Ext.data.StoreManager.lookup('imagesStore'),
- *         tpl: imageTpl,
- *         itemSelector: 'div.thumb-wrap',
- *         emptyText: 'No images available',
- *         renderTo: Ext.getBody()
- *     });
- *
- * @xtype dataview
+  <pre class="prettyprint lang-js"><span id='Ext-tree-View'>/**
+</span> * @class Ext.tree.View
+ * @extends Ext.view.Table
  */
-Ext.define('Ext.view.View', {
-    extend: 'Ext.view.AbstractView',
-    alternateClassName: 'Ext.view.View',
-    alias: 'widget.dataview',
-
-    inheritableStatics: {
-        EventMap: {
-            mousedown: 'MouseDown',
-            mouseup: 'MouseUp',
-            click: 'Click',
-            dblclick: 'DblClick',
-            contextmenu: 'ContextMenu',
-            mouseover: 'MouseOver',
-            mouseout: 'MouseOut',
-            mouseenter: 'MouseEnter',
-            mouseleave: 'MouseLeave',
-            keydown: 'KeyDown'
-        }
-    },
+Ext.define('Ext.tree.View', {
+    extend: 'Ext.view.Table',
+    alias: 'widget.treeview',
 
-    addCmpEvents: function() {
-        this.addEvents(
-<span id='Ext-view-View-event-beforeitemmousedown'>            /**
-</span>             * @event beforeitemmousedown
-             * Fires before the mousedown event on an item is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforeitemmousedown',
-<span id='Ext-view-View-event-beforeitemmouseup'>            /**
-</span>             * @event beforeitemmouseup
-             * Fires before the mouseup event on an item is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforeitemmouseup',
-<span id='Ext-view-View-event-beforeitemmouseenter'>            /**
-</span>             * @event beforeitemmouseenter
-             * Fires before the mouseenter event on an item is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforeitemmouseenter',
-<span id='Ext-view-View-event-beforeitemmouseleave'>            /**
-</span>             * @event beforeitemmouseleave
-             * Fires before the mouseleave event on an item is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforeitemmouseleave',
-<span id='Ext-view-View-event-beforeitemclick'>            /**
-</span>             * @event beforeitemclick
-             * Fires before the click event on an item is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforeitemclick',
-<span id='Ext-view-View-event-beforeitemdblclick'>            /**
-</span>             * @event beforeitemdblclick
-             * Fires before the dblclick event on an item is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforeitemdblclick',
-<span id='Ext-view-View-event-beforeitemcontextmenu'>            /**
-</span>             * @event beforeitemcontextmenu
-             * Fires before the contextmenu event on an item is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforeitemcontextmenu',
-<span id='Ext-view-View-event-beforeitemkeydown'>            /**
-</span>             * @event beforeitemkeydown
-             * Fires before the keydown event on an item is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
-             */
-            'beforeitemkeydown',
-<span id='Ext-view-View-event-itemmousedown'>            /**
-</span>             * @event itemmousedown
-             * Fires when there is a mouse down on an item
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'itemmousedown',
-<span id='Ext-view-View-event-itemmouseup'>            /**
-</span>             * @event itemmouseup
-             * Fires when there is a mouse up on an item
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'itemmouseup',
-<span id='Ext-view-View-event-itemmouseenter'>            /**
-</span>             * @event itemmouseenter
-             * Fires when the mouse enters an item.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'itemmouseenter',
-<span id='Ext-view-View-event-itemmouseleave'>            /**
-</span>             * @event itemmouseleave
-             * Fires when the mouse leaves an item.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'itemmouseleave',
-<span id='Ext-view-View-event-itemclick'>            /**
-</span>             * @event itemclick
-             * Fires when an item is clicked.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'itemclick',
-<span id='Ext-view-View-event-itemdblclick'>            /**
-</span>             * @event itemdblclick
-             * Fires when an item is double clicked.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'itemdblclick',
-<span id='Ext-view-View-event-itemcontextmenu'>            /**
-</span>             * @event itemcontextmenu
-             * Fires when an item is right clicked.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'itemcontextmenu',
-<span id='Ext-view-View-event-itemkeydown'>            /**
-</span>             * @event itemkeydown
-             * Fires when a key is pressed while an item is currently selected.
-             * @param {Ext.view.View} this
-             * @param {Ext.data.Model} record The record that belongs to the item
-             * @param {HTMLElement} item The item's element
-             * @param {Number} index The item's index
-             * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
-             */
-            'itemkeydown',
-<span id='Ext-view-View-event-beforecontainermousedown'>            /**
-</span>             * @event beforecontainermousedown
-             * Fires before the mousedown event on the container is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforecontainermousedown',
-<span id='Ext-view-View-event-beforecontainermouseup'>            /**
-</span>             * @event beforecontainermouseup
-             * Fires before the mouseup event on the container is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforecontainermouseup',
-<span id='Ext-view-View-event-beforecontainermouseover'>            /**
-</span>             * @event beforecontainermouseover
-             * Fires before the mouseover event on the container is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforecontainermouseover',
-<span id='Ext-view-View-event-beforecontainermouseout'>            /**
-</span>             * @event beforecontainermouseout
-             * Fires before the mouseout event on the container is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforecontainermouseout',
-<span id='Ext-view-View-event-beforecontainerclick'>            /**
-</span>             * @event beforecontainerclick
-             * Fires before the click event on the container is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforecontainerclick',
-<span id='Ext-view-View-event-beforecontainerdblclick'>            /**
-</span>             * @event beforecontainerdblclick
-             * Fires before the dblclick event on the container is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforecontainerdblclick',
-<span id='Ext-view-View-event-beforecontainercontextmenu'>            /**
-</span>             * @event beforecontainercontextmenu
-             * Fires before the contextmenu event on the container is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'beforecontainercontextmenu',
-<span id='Ext-view-View-event-beforecontainerkeydown'>            /**
-</span>             * @event beforecontainerkeydown
-             * Fires before the keydown event on the container is processed. Returns false to cancel the default action.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
-             */
-            'beforecontainerkeydown',
-<span id='Ext-view-View-event-containermouseup'>            /**
-</span>             * @event containermouseup
-             * Fires when there is a mouse up on the container
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'containermouseup',
-<span id='Ext-view-View-event-containermouseover'>            /**
-</span>             * @event containermouseover
-             * Fires when you move the mouse over the container.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'containermouseover',
-<span id='Ext-view-View-event-containermouseout'>            /**
-</span>             * @event containermouseout
-             * Fires when you move the mouse out of the container.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'containermouseout',
-<span id='Ext-view-View-event-containerclick'>            /**
-</span>             * @event containerclick
-             * Fires when the container is clicked.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'containerclick',
-<span id='Ext-view-View-event-containerdblclick'>            /**
-</span>             * @event containerdblclick
-             * Fires when the container is double clicked.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'containerdblclick',
-<span id='Ext-view-View-event-containercontextmenu'>            /**
-</span>             * @event containercontextmenu
-             * Fires when the container is right clicked.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object
-             */
-            'containercontextmenu',
-<span id='Ext-view-View-event-containerkeydown'>            /**
-</span>             * @event containerkeydown
-             * Fires when a key is pressed while the container is focused, and no item is currently selected.
-             * @param {Ext.view.View} this
-             * @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
-             */
-            'containerkeydown',
-
-<span id='Ext-view-View-event-selectionchange'>            /**
-</span>             * @event selectionchange
-             * Fires when the selected nodes change. Relayed event from the underlying selection model.
-             * @param {Ext.view.View} this
-             * @param {Array} selections Array of the selected nodes
-             */
-            'selectionchange',
-<span id='Ext-view-View-event-beforeselect'>            /**
-</span>             * @event beforeselect
-             * Fires before a selection is made. If any handlers return false, the selection is cancelled.
-             * @param {Ext.view.View} this
-             * @param {HTMLElement} node The node to be selected
-             * @param {Array} selections Array of currently selected nodes
-             */
-            'beforeselect'
-        );
-    },
-    // private
-    afterRender: function(){
-        var me = this,
-            listeners;
+    loadingCls: Ext.baseCSSPrefix + 'grid-tree-loading',
+    expandedCls: Ext.baseCSSPrefix + 'grid-tree-node-expanded',
 
-        me.callParent();
+    expanderSelector: '.' + Ext.baseCSSPrefix + 'tree-expander',
+    checkboxSelector: '.' + Ext.baseCSSPrefix + 'tree-checkbox',
+    expanderIconOverCls: Ext.baseCSSPrefix + 'tree-expander-over',
 
-        listeners = {
-            scope: me,
-            click: me.handleEvent,
-            mousedown: me.handleEvent,
-            mouseup: me.handleEvent,
-            dblclick: me.handleEvent,
-            contextmenu: me.handleEvent,
-            mouseover: me.handleEvent,
-            mouseout: me.handleEvent,
-            keydown: me.handleEvent
-        };
+    blockRefresh: true,
 
-        me.mon(me.getTargetEl(), listeners);
+<span id='Ext-tree-View-cfg-rootVisible'>    /** 
+</span>     * @cfg {Boolean} rootVisible &lt;tt&gt;false&lt;/tt&gt; to hide the root node (defaults to &lt;tt&gt;true&lt;/tt&gt;)
+     */
+    rootVisible: true,
+
+<span id='Ext-tree-View-cfg-animate'>    /** 
+</span>     * @cfg {Boolean} animate &lt;tt&gt;true&lt;/tt&gt; to enable animated expand/collapse (defaults to the value of {@link Ext#enableFx Ext.enableFx})
+     */
 
-        if (me.store) {
-            me.bindStore(me.store, true);
+    expandDuration: 250,
+    collapseDuration: 250,
+    
+    toggleOnDblClick: true,
+
+    initComponent: function() {
+        var me = this;
+        
+        if (me.initialConfig.animate === undefined) {
+            me.animate = Ext.enableFx;
         }
+        
+        me.store = Ext.create('Ext.data.NodeStore', {
+            recursive: true,
+            rootVisible: me.rootVisible,
+            listeners: {
+                beforeexpand: me.onBeforeExpand,
+                expand: me.onExpand,
+                beforecollapse: me.onBeforeCollapse,
+                collapse: me.onCollapse,
+                scope: me
+            }
+        });
+        
+        if (me.node) {
+            me.setRootNode(me.node);
+        }
+        me.animQueue = {};
+        me.callParent(arguments);
+    },
+    
+    onClear: function(){
+        this.store.removeAll();    
     },
 
-    handleEvent: function(e) {
-        if (this.processUIEvent(e) !== false) {
-            this.processSpecialEvent(e);
+    setRootNode: function(node) {
+        var me = this;        
+        me.store.setNode(node);
+        me.node = node;
+        if (!me.rootVisible) {
+            node.expand();
         }
     },
+    
+    onRender: function() {
+        var me = this,
+            opts = {delegate: me.expanderSelector},
+            el;
 
-    // Private template method
-    processItemEvent: Ext.emptyFn,
-    processContainerEvent: Ext.emptyFn,
-    processSpecialEvent: Ext.emptyFn,
+        me.callParent(arguments);
 
-    /*
-     * Returns true if this mouseover/out event is still over the overItem.
-     */
-    stillOverItem: function (event, overItem) {
-        var nowOver;
-
-        // There is this weird bug when you hover over the border of a cell it is saying
-        // the target is the table.
-        // BrowserBug: IE6 &amp; 7. If me.mouseOverItem has been removed and is no longer
-        // in the DOM then accessing .offsetParent will throw an &quot;Unspecified error.&quot; exception.
-        // typeof'ng and checking to make sure the offsetParent is an object will NOT throw
-        // this hard exception.
-        if (overItem &amp;&amp; typeof(overItem.offsetParent) === &quot;object&quot;) {
-            // mouseout : relatedTarget == nowOver, target == wasOver
-            // mouseover: relatedTarget == wasOver, target == nowOver
-            nowOver = (event.type == 'mouseout') ? event.getRelatedTarget() : event.getTarget();
-            return Ext.fly(overItem).contains(nowOver);
-        }
+        el = me.el;
+        el.on({
+            scope: me,
+            delegate: me.expanderSelector,
+            mouseover: me.onExpanderMouseOver,
+            mouseout: me.onExpanderMouseOut
+        });
+        el.on({
+            scope: me,
+            delegate: me.checkboxSelector,
+            click: me.onCheckboxChange
+        });
+    },
 
-        return false;
+    onCheckboxChange: function(e, t) {
+        var item = e.getTarget(this.getItemSelector(), this.getTargetEl()),
+            record, value;
+            
+        if (item) {
+            record = this.getRecord(item);
+            value = !record.get('checked');
+            record.set('checked', value);
+            this.fireEvent('checkchange', record, value);
+        }
     },
 
-    processUIEvent: function(e) {
-        var me = this,
-            item = e.getTarget(me.getItemSelector(), me.getTargetEl()),
-            map = this.statics().EventMap,
-            index, record,
-            type = e.type,
-            overItem = me.mouseOverItem,
-            newType;
-
-        if (!item) {
-            if (type == 'mouseover' &amp;&amp; me.stillOverItem(e, overItem)) {
-                item = overItem;
+    getChecked: function() {
+        var checked = [];
+        this.node.cascadeBy(function(rec){
+            if (rec.get('checked')) {
+                checked.push(rec);
             }
+        });
+        return checked;
+    },
+    
+    isItemChecked: function(rec){
+        return rec.get('checked');
+    },
 
-            // Try to get the selected item to handle the keydown event, otherwise we'll just fire a container keydown event
-            if (type == 'keydown') {
-                record = me.getSelectionModel().getLastSelected();
-                if (record) {
-                    item = me.getNode(record);
-                }
-            }
+    createAnimWrap: function(record, index) {
+        var thHtml = '',
+            headerCt = this.panel.headerCt,
+            headers = headerCt.getGridColumns(),
+            i = 0, len = headers.length, item,
+            node = this.getNode(record),
+            tmpEl, nodeEl;
+
+        for (; i &lt; len; i++) {
+            item = headers[i];
+            thHtml += '&lt;th style=&quot;width: ' + (item.hidden ? 0 : item.getDesiredWidth()) + 'px; height: 0px;&quot;&gt;&lt;/th&gt;';
         }
 
-        if (item) {
-            index = me.indexOf(item);
-            if (!record) {
-                record = me.getRecord(item);
-            }
+        nodeEl = Ext.get(node);        
+        tmpEl = nodeEl.insertSibling({
+            tag: 'tr',
+            html: [
+                '&lt;td colspan=&quot;' + headerCt.getColumnCount() + '&quot;&gt;',
+                    '&lt;div class=&quot;' + Ext.baseCSSPrefix + 'tree-animator-wrap' + '&quot;&gt;',
+                        '&lt;table class=&quot;' + Ext.baseCSSPrefix + 'grid-table&quot; style=&quot;width: ' + headerCt.getFullWidth() + 'px;&quot;&gt;&lt;tbody&gt;',
+                            thHtml,
+                        '&lt;/tbody&gt;&lt;/table&gt;',
+                    '&lt;/div&gt;',
+                '&lt;/td&gt;'
+            ].join('')
+        }, 'after');
+
+        return {
+            record: record,
+            node: node,
+            el: tmpEl,
+            expanding: false,
+            collapsing: false,
+            animating: false,
+            animateEl: tmpEl.down('div'),
+            targetEl: tmpEl.down('tbody')
+        };
+    },
 
-            if (me.processItemEvent(record, item, index, e) === false) {
-                return false;
-            }
+    getAnimWrap: function(parent) {
+        if (!this.animate) {
+            return null;
+        }
 
-            newType = me.isNewItemEvent(item, e);
-            if (newType === false) {
-                return false;
+        // We are checking to see which parent is having the animation wrap
+        while (parent) {
+            if (parent.animWrap) {
+                return parent.animWrap;
             }
+            parent = parent.parentNode;
+        }
+        return null;
+    },
 
-            if (
-                (me['onBeforeItem' + map[newType]](record, item, index, e) === false) ||
-                (me.fireEvent('beforeitem' + newType, me, record, item, index, e) === false) ||
-                (me['onItem' + map[newType]](record, item, index, e) === false)
-            ) {
-                return false;
-            }
+    doAdd: function(nodes, records, index) {
+        // If we are adding records which have a parent that is currently expanding
+        // lets add them to the animation wrap
+        var me = this,
+            record = records[0],
+            parent = record.parentNode,
+            a = me.all.elements,
+            relativeIndex = 0,
+            animWrap = me.getAnimWrap(parent),
+            targetEl, children, len;
+
+        if (!animWrap || !animWrap.expanding) {
+            me.resetScrollers();
+            return me.callParent(arguments);
+        }
 
-            me.fireEvent('item' + newType, me, record, item, index, e);
+        // We need the parent that has the animWrap, not the nodes parent
+        parent = animWrap.record;
+        
+        // If there is an anim wrap we do our special magic logic
+        targetEl = animWrap.targetEl;
+        children = targetEl.dom.childNodes;
+        
+        // We subtract 1 from the childrens length because we have a tr in there with the th'es
+        len = children.length - 1;
+        
+        // The relative index is the index in the full flat collection minus the index of the wraps parent
+        relativeIndex = index - me.indexOf(parent) - 1;
+        
+        // If we are adding records to the wrap that have a higher relative index then there are currently children
+        // it means we have to append the nodes to the wrap
+        if (!len || relativeIndex &gt;= len) {
+            targetEl.appendChild(nodes);
         }
+        // If there are already more children then the relative index it means we are adding child nodes of
+        // some expanded node in the anim wrap. In this case we have to insert the nodes in the right location
         else {
-            if (
-                (me.processContainerEvent(e) === false) ||
-                (me['onBeforeContainer' + map[type]](e) === false) ||
-                (me.fireEvent('beforecontainer' + type, me, e) === false) ||
-                (me['onContainer' + map[type]](e) === false)
-            ) {
-                return false;
-            }
+            // +1 because of the tr with th'es that is already there
+            Ext.fly(children[relativeIndex + 1]).insertSibling(nodes, 'before', true);
+        }
 
-            me.fireEvent('container' + type, me, e);
+        // We also have to update the CompositeElementLite collection of the DataView
+        Ext.Array.insert(a, index, nodes);
+        
+        // If we were in an animation we need to now change the animation
+        // because the targetEl just got higher.
+        if (animWrap.isAnimating) {
+            me.onExpand(parent);
+        }
+    },
+    
+    doRemove: function(record, index) {
+        // If we are adding records which have a parent that is currently expanding
+        // lets add them to the animation wrap
+        var me = this,
+            parent = record.parentNode,
+            all = me.all,
+            animWrap = me.getAnimWrap(record),
+            node = all.item(index).dom;
+
+        if (!animWrap || !animWrap.collapsing) {
+            me.resetScrollers();
+            return me.callParent(arguments);
         }
 
-        return true;
+        animWrap.targetEl.appendChild(node);
+        all.removeElement(index);
     },
 
-    isNewItemEvent: function (item, e) {
+    onBeforeExpand: function(parent, records, index) {
         var me = this,
-            overItem = me.mouseOverItem,
-            type = e.type;
-
-        switch (type) {
-            case 'mouseover':
-                if (item === overItem) {
-                    return false;
-                }
-                me.mouseOverItem = item;
-                return 'mouseenter';
+            animWrap;
+            
+        if (!me.rendered || !me.animate) {
+            return;
+        }
 
-            case 'mouseout':
-                // If the currently mouseovered item contains the mouseover target, it's *NOT* a mouseleave
-                if (me.stillOverItem(e, overItem)) {
-                    return false;
-                }
-                me.mouseOverItem = null;
-                return 'mouseleave';
+        if (me.getNode(parent)) {
+            animWrap = me.getAnimWrap(parent);
+            if (!animWrap) {
+                animWrap = parent.animWrap = me.createAnimWrap(parent);
+                animWrap.animateEl.setHeight(0);
+            }
+            else if (animWrap.collapsing) {
+                // If we expand this node while it is still expanding then we
+                // have to remove the nodes from the animWrap.
+                animWrap.targetEl.select(me.itemSelector).remove();
+            } 
+            animWrap.expanding = true;
+            animWrap.collapsing = false;
         }
-        return type;
     },
 
-    // private
-    onItemMouseEnter: function(record, item, index, e) {
-        if (this.trackOver) {
-            this.highlightItem(item);
+    onExpand: function(parent) {
+        var me = this,
+            queue = me.animQueue,
+            id = parent.getId(),
+            animWrap,
+            animateEl, 
+            targetEl,
+            queueItem;        
+        
+        if (me.singleExpand) {
+            me.ensureSingleExpand(parent);
         }
-    },
+        
+        animWrap = me.getAnimWrap(parent);
 
-    // private
-    onItemMouseLeave : function(record, item, index, e) {
-        if (this.trackOver) {
-            this.clearHighlight();
+        if (!animWrap) {
+            me.resetScrollers();
+            return;
         }
+        
+        animateEl = animWrap.animateEl;
+        targetEl = animWrap.targetEl;
+
+        animateEl.stopAnimation();
+        // @TODO: we are setting it to 1 because quirks mode on IE seems to have issues with 0
+        queue[id] = true;
+        animateEl.slideIn('t', {
+            duration: me.expandDuration,
+            listeners: {
+                scope: me,
+                lastframe: function() {
+                    // Move all the nodes out of the anim wrap to their proper location
+                    animWrap.el.insertSibling(targetEl.query(me.itemSelector), 'before');
+                    animWrap.el.remove();
+                    me.resetScrollers();
+                    delete animWrap.record.animWrap;
+                    delete queue[id];
+                }
+            }
+        });
+        
+        animWrap.isAnimating = true;
     },
-
-    // @private, template methods
-    onItemMouseDown: Ext.emptyFn,
-    onItemMouseUp: Ext.emptyFn,
-    onItemClick: Ext.emptyFn,
-    onItemDblClick: Ext.emptyFn,
-    onItemContextMenu: Ext.emptyFn,
-    onItemKeyDown: Ext.emptyFn,
-    onBeforeItemMouseDown: Ext.emptyFn,
-    onBeforeItemMouseUp: Ext.emptyFn,
-    onBeforeItemMouseEnter: Ext.emptyFn,
-    onBeforeItemMouseLeave: Ext.emptyFn,
-    onBeforeItemClick: Ext.emptyFn,
-    onBeforeItemDblClick: Ext.emptyFn,
-    onBeforeItemContextMenu: Ext.emptyFn,
-    onBeforeItemKeyDown: Ext.emptyFn,
-
-    // @private, template methods
-    onContainerMouseDown: Ext.emptyFn,
-    onContainerMouseUp: Ext.emptyFn,
-    onContainerMouseOver: Ext.emptyFn,
-    onContainerMouseOut: Ext.emptyFn,
-    onContainerClick: Ext.emptyFn,
-    onContainerDblClick: Ext.emptyFn,
-    onContainerContextMenu: Ext.emptyFn,
-    onContainerKeyDown: Ext.emptyFn,
-    onBeforeContainerMouseDown: Ext.emptyFn,
-    onBeforeContainerMouseUp: Ext.emptyFn,
-    onBeforeContainerMouseOver: Ext.emptyFn,
-    onBeforeContainerMouseOut: Ext.emptyFn,
-    onBeforeContainerClick: Ext.emptyFn,
-    onBeforeContainerDblClick: Ext.emptyFn,
-    onBeforeContainerContextMenu: Ext.emptyFn,
-    onBeforeContainerKeyDown: Ext.emptyFn,
-
-<span id='Ext-view-View-method-highlightItem'>    /**
-</span>     * Highlight a given item in the DataView. This is called by the mouseover handler if {@link #overItemCls}
-     * and {@link #trackOver} are configured, but can also be called manually by other code, for instance to
-     * handle stepping through the list via keyboard navigation.
-     * @param {HTMLElement} item The item to highlight
-     */
-    highlightItem: function(item) {
-        var me = this;
-        me.clearHighlight();
-        me.highlightedItem = item;
-        Ext.fly(item).addCls(me.overItemCls);
+    
+    resetScrollers: function(){
+        var panel = this.panel;
+        
+        panel.determineScrollbars();
+        panel.invalidateScroller();
     },
 
-<span id='Ext-view-View-method-clearHighlight'>    /**
-</span>     * Un-highlight the currently highlighted item, if any.
-     */
-    clearHighlight: function() {
+    onBeforeCollapse: function(parent, records, index) {
         var me = this,
-            highlighted = me.highlightedItem;
+            animWrap;
+            
+        if (!me.rendered || !me.animate) {
+            return;
+        }
 
-        if (highlighted) {
-            Ext.fly(highlighted).removeCls(me.overItemCls);
-            delete me.highlightedItem;
+        if (me.getNode(parent)) {
+            animWrap = me.getAnimWrap(parent);
+            if (!animWrap) {
+                animWrap = parent.animWrap = me.createAnimWrap(parent, index);
+            }
+            else if (animWrap.expanding) {
+                // If we collapse this node while it is still expanding then we
+                // have to remove the nodes from the animWrap.
+                animWrap.targetEl.select(this.itemSelector).remove();
+            }
+            animWrap.expanding = false;
+            animWrap.collapsing = true;
         }
     },
-
-    refresh: function() {
-        this.clearHighlight();
+    
+    onCollapse: function(parent) {
+        var me = this,
+            queue = me.animQueue,
+            id = parent.getId(),
+            animWrap = me.getAnimWrap(parent),
+            animateEl, targetEl;
+
+        if (!animWrap) {
+            me.resetScrollers();
+            return;
+        }
+        
+        animateEl = animWrap.animateEl;
+        targetEl = animWrap.targetEl;
+
+        queue[id] = true;
+        
+        // @TODO: we are setting it to 1 because quirks mode on IE seems to have issues with 0
+        animateEl.stopAnimation();
+        animateEl.slideOut('t', {
+            duration: me.collapseDuration,
+            listeners: {
+                scope: me,
+                lastframe: function() {
+                    animWrap.el.remove();
+                    delete animWrap.record.animWrap;
+                    me.resetScrollers();
+                    delete queue[id];
+                }             
+            }
+        });
+        animWrap.isAnimating = true;
+    },
+    
+<span id='Ext-tree-View-method-isAnimating'>    /**
+</span>     * Checks if a node is currently undergoing animation
+     * @private
+     * @param {Ext.data.Model} node The node
+     * @return {Boolean} True if the node is animating
+     */
+    isAnimating: function(node) {
+        return !!this.animQueue[node.getId()];    
+    },
+    
+    collectData: function(records) {
+        var data = this.callParent(arguments),
+            rows = data.rows,
+            len = rows.length,
+            i = 0,
+            row, record;
+            
+        for (; i &lt; len; i++) {
+            row = rows[i];
+            record = records[i];
+            if (record.get('qtip')) {
+                row.rowAttr = 'data-qtip=&quot;' + record.get('qtip') + '&quot;';
+                if (record.get('qtitle')) {
+                    row.rowAttr += ' ' + 'data-qtitle=&quot;' + record.get('qtitle') + '&quot;';
+                }
+            }
+            if (record.isExpanded()) {
+                row.rowCls = (row.rowCls || '') + ' ' + this.expandedCls;
+            }
+            if (record.isLoading()) {
+                row.rowCls = (row.rowCls || '') + ' ' + this.loadingCls;
+            }
+        }
+        
+        return data;
+    },
+    
+<span id='Ext-tree-View-method-expand'>    /**
+</span>     * Expand a record that is loaded in the view.
+     * @param {Ext.data.Model} record The record to expand
+     * @param {Boolean} deep (optional) True to expand nodes all the way down the tree hierarchy.
+     * @param {Function} callback (optional) The function to run after the expand is completed
+     * @param {Object} scope (optional) The scope of the callback function.
+     */
+    expand: function(record, deep, callback, scope) {
+        return record.expand(deep, callback, scope);
+    },
+    
+<span id='Ext-tree-View-method-collapse'>    /**
+</span>     * Collapse a record that is loaded in the view.
+     * @param {Ext.data.Model} record The record to collapse
+     * @param {Boolean} deep (optional) True to collapse nodes all the way up the tree hierarchy.
+     * @param {Function} callback (optional) The function to run after the collapse is completed
+     * @param {Object} scope (optional) The scope of the callback function.
+     */
+    collapse: function(record, deep, callback, scope) {
+        return record.collapse(deep, callback, scope);
+    },
+    
+<span id='Ext-tree-View-method-toggle'>    /**
+</span>     * Toggle a record between expanded and collapsed.
+     * @param {Ext.data.Record} recordInstance
+     */
+    toggle: function(record) {
+        this[record.isExpanded() ? 'collapse' : 'expand'](record);
+    },
+    
+    onItemDblClick: function(record, item, index) {
         this.callParent(arguments);
+        if (this.toggleOnDblClick) {
+            this.toggle(record);
+        }
+    },
+    
+    onBeforeItemMouseDown: function(record, item, index, e) {
+        if (e.getTarget(this.expanderSelector, item)) {
+            return false;
+        }
+        return this.callParent(arguments);
+    },
+    
+    onItemClick: function(record, item, index, e) {
+        if (e.getTarget(this.expanderSelector, item)) {
+            this.toggle(record);
+            return false;
+        }
+        return this.callParent(arguments);
+    },
+    
+    onExpanderMouseOver: function(e, t) {
+        e.getTarget(this.cellSelector, 10, true).addCls(this.expanderIconOverCls);
+    },
+    
+    onExpanderMouseOut: function(e, t) {
+        e.getTarget(this.cellSelector, 10, true).removeCls(this.expanderIconOverCls);
+    },
+    
+<span id='Ext-tree-View-method-getTreeStore'>    /**
+</span>     * Gets the base TreeStore from the bound TreePanel.
+     */
+    getTreeStore: function() {
+        return this.panel.store;
+    },    
+    
+    ensureSingleExpand: function(node) {
+        var parent = node.parentNode;
+        if (parent) {
+            parent.eachChild(function(child) {
+                if (child !== node &amp;&amp; child.isExpanded()) {
+                    child.collapse();
+                }
+            });
+        }
     }
 });</pre>
 </body>