X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/3789b528d8dd8aad4558e38e22d775bcab1cbd36..6746dc89c47ed01b165cc1152533605f97eb8e8d:/docs/source/Panel4.html diff --git a/docs/source/Panel4.html b/docs/source/Panel4.html index d028d623..bc462c42 100644 --- a/docs/source/Panel4.html +++ b/docs/source/Panel4.html @@ -15,586 +15,371 @@ -
/**
- * @author Ed Spencer, Tommy Maintz, Brian Moeskau
- * @class Ext.tab.Panel
- * @extends Ext.panel.Panel
-
-A basic tab container. TabPanels can be used exactly like a standard {@link Ext.panel.Panel} for layout purposes, but also 
-have special support for containing child Components (`{@link Ext.container.Container#items items}`) that are managed 
-using a {@link Ext.layout.container.Card CardLayout layout manager}, and displayed as separate tabs.
-
-__Note:__
-
-By default, a tab's close tool _destroys_ the child tab Component and all its descendants. This makes the child tab 
-Component, and all its descendants __unusable__. To enable re-use of a tab, configure the TabPanel with `{@link #autoDestroy autoDestroy: false}`.
-
-__TabPanel's layout:__
-
-TabPanels use a Dock layout to position the {@link Ext.tab.Bar TabBar} at the top of the widget. Panels added to the TabPanel will have their 
-header hidden by default because the Tab will automatically take the Panel's configured title and icon.
-
-TabPanels use their {@link Ext.panel.Panel#header header} or {@link Ext.panel.Panel#footer footer} element (depending on the {@link #tabPosition} 
-configuration) to accommodate the tab selector buttons. This means that a TabPanel will not display any configured title, and will not display any 
-configured header {@link Ext.panel.Panel#tools tools}.
-
-To display a header, embed the TabPanel in a {@link Ext.panel.Panel Panel} which uses `{@link Ext.container.Container#layout layout:'fit'}`.
-
-__Examples:__
-
-Here is a basic TabPanel rendered to the body. This also shows the useful configuration {@link #activeTab}, which allows you to set the active tab on render. 
-If you do not set an {@link #activeTab}, no tabs will be active by default.
-{@img Ext.tab.Panel/Ext.tab.Panel1.png TabPanel component}
-Example usage:
-
-    Ext.create('Ext.tab.Panel', {
-        width: 300,
-        height: 200,
-        activeTab: 0,
-        items: [
-            {
-                title: 'Tab 1',
-                bodyPadding: 10,
-                html : 'A simple tab'
-            },
-            {
-                title: 'Tab 2',
-                html : 'Another one'
-            }
-        ],
-        renderTo : Ext.getBody()
-    }); 
-    
-It is easy to control the visibility of items in the tab bar. Specify hidden: true to have the
-tab button hidden initially. Items can be subsequently hidden and show by accessing the
-tab property on the child item.
-
-Example usage:
-    
-    var tabs = Ext.create('Ext.tab.Panel', {
-        width: 400,
-        height: 400,
-        renderTo: document.body,
-        items: [{
-            title: 'Home',
-            html: 'Home',
-            itemId: 'home'
-        }, {
-            title: 'Users',
-            html: 'Users',
-            itemId: 'users',
-            hidden: true
-        }, {
-            title: 'Tickets',
-            html: 'Tickets',
-            itemId: 'tickets'
-        }]    
-    });
-    
-    setTimeout(function(){
-        tabs.child('#home').tab.hide();
-        var users = tabs.child('#users');
-        users.tab.show();
-        tabs.setActiveTab(users);
-    }, 1000);
-
-You can remove the background of the TabBar by setting the {@link #plain} property to `false`.
-
-Example usage:
-
-    Ext.create('Ext.tab.Panel', {
-        width: 300,
-        height: 200,
-        activeTab: 0,
-        plain: true,
-        items: [
-            {
-                title: 'Tab 1',
-                bodyPadding: 10,
-                html : 'A simple tab'
-            },
-            {
-                title: 'Tab 2',
-                html : 'Another one'
-            }
-        ],
-        renderTo : Ext.getBody()
-    }); 
-
-Another useful configuration of TabPanel is {@link #tabPosition}. This allows you to change the position where the tabs are displayed. The available 
-options for this are `'top'` (default) and `'bottom'`.
-{@img Ext.tab.Panel/Ext.tab.Panel2.png TabPanel component}
-Example usage:
-
-    Ext.create('Ext.tab.Panel', {
-        width: 300,
-        height: 200,
-        activeTab: 0,
-        bodyPadding: 10,        
-        tabPosition: 'bottom',
-        items: [
-            {
-                title: 'Tab 1',
-                html : 'A simple tab'
-            },
-            {
-                title: 'Tab 2',
-                html : 'Another one'
-            }
-        ],
-        renderTo : Ext.getBody()
-    }); 
-
-The {@link #setActiveTab} is a very useful method in TabPanel which will allow you to change the current active tab. You can either give it an index or 
-an instance of a tab.
-
-Example usage:
-
-    var tabs = Ext.create('Ext.tab.Panel', {
-        items: [
-            {
-                id   : 'my-tab',
-                title: 'Tab 1',
-                html : 'A simple tab'
-            },
-            {
-                title: 'Tab 2',
-                html : 'Another one'
-            }
-        ],
-        renderTo : Ext.getBody()
-    });
-    
-    var tab = Ext.getCmp('my-tab');
-    
-    Ext.create('Ext.button.Button', {
-        renderTo: Ext.getBody(),
-        text    : 'Select the first tab',
-        scope   : this,
-        handler : function() {
-            tabs.setActiveTab(tab);
-        }
-    });
-    
-    Ext.create('Ext.button.Button', {
-        text    : 'Select the second tab',
-        scope   : this,
-        handler : function() {
-            tabs.setActiveTab(1);
-        },
-        renderTo : Ext.getBody()        
-    });
-
-The {@link #getActiveTab} is a another useful method in TabPanel which will return the current active tab.
-
-Example usage:
-
-    var tabs = Ext.create('Ext.tab.Panel', {
-        items: [
-            {
-                title: 'Tab 1',
-                html : 'A simple tab'
-            },
-            {
-                title: 'Tab 2',
-                html : 'Another one'
-            }
-        ],
-        renderTo : Ext.getBody()        
-    });
+  
/**
+ * @author Aaron Conran
+ * @class Ext.grid.Panel
+ * @extends Ext.panel.Table
+ *
+ * Grids are an excellent way of showing large amounts of tabular data on the client side. Essentially a supercharged 
+ * `<table>`, GridPanel makes it easy to fetch, sort and filter large amounts of data.
+ * 
+ * Grids are composed of 2 main pieces - a {@link Ext.data.Store Store} full of data and a set of columns to render.
+ *
+ * {@img Ext.grid.Panel/Ext.grid.Panel1.png Ext.grid.Panel component}
+ *
+ * ## Basic GridPanel
+ *
+ *     Ext.create('Ext.data.Store', {
+ *         storeId:'simpsonsStore',
+ *         fields:['name', 'email', 'phone'],
+ *         data:{'items':[
+ *             {"name":"Lisa", "email":"lisa@simpsons.com", "phone":"555-111-1224"},
+ *             {"name":"Bart", "email":"bart@simpsons.com", "phone":"555--222-1234"},
+ *             {"name":"Homer", "email":"home@simpsons.com", "phone":"555-222-1244"},                        
+ *             {"name":"Marge", "email":"marge@simpsons.com", "phone":"555-222-1254"}            
+ *         ]},
+ *         proxy: {
+ *             type: 'memory',
+ *             reader: {
+ *                 type: 'json',
+ *                 root: 'items'
+ *             }
+ *         }
+ *     });
+ *     
+ *     Ext.create('Ext.grid.Panel', {
+ *         title: 'Simpsons',
+ *         store: Ext.data.StoreManager.lookup('simpsonsStore'),
+ *         columns: [
+ *             {header: 'Name',  dataIndex: 'name'},
+ *             {header: 'Email', dataIndex: 'email', flex:1},
+ *             {header: 'Phone', dataIndex: 'phone'}
+ *         ],
+ *         height: 200,
+ *         width: 400,
+ *         renderTo: Ext.getBody()
+ *     });
+ * 
+ * The code above produces a simple grid with three columns. We specified a Store which will load JSON data inline. 
+ * In most apps we would be placing the grid inside another container and wouldn't need to use the
+ * {@link #height}, {@link #width} and {@link #renderTo} configurations but they are included here to make it easy to get
+ * up and running.
+ * 
+ * The grid we created above will contain a header bar with a title ('Simpsons'), a row of column headers directly underneath
+ * and finally the grid rows under the headers.
+ * 
+ * ## Configuring columns
+ * 
+ * By default, each column is sortable and will toggle between ASC and DESC sorting when you click on its header. Each
+ * column header is also reorderable by default, and each gains a drop-down menu with options to hide and show columns.
+ * It's easy to configure each column - here we use the same example as above and just modify the columns config:
+ * 
+ *     columns: [
+ *         {
+ *             header: 'Name',
+ *             dataIndex: 'name',
+ *             sortable: false,
+ *             hideable: false,
+ *             flex: 1
+ *         },
+ *         {
+ *             header: 'Email',
+ *             dataIndex: 'email',
+ *             hidden: true
+ *         },
+ *         {
+ *             header: 'Phone',
+ *             dataIndex: 'phone',
+ *             width: 100
+ *         }
+ *     ]
+ * 
+ * We turned off sorting and hiding on the 'Name' column so clicking its header now has no effect. We also made the Email
+ * column hidden by default (it can be shown again by using the menu on any other column). We also set the Phone column to
+ * a fixed with of 100px and flexed the Name column, which means it takes up all remaining width after the other columns 
+ * have been accounted for. See the {@link Ext.grid.column.Column column docs} for more details.
+ * 
+ * ## Renderers
+ * 
+ * As well as customizing columns, it's easy to alter the rendering of individual cells using renderers. A renderer is 
+ * tied to a particular column and is passed the value that would be rendered into each cell in that column. For example,
+ * we could define a renderer function for the email column to turn each email address into a mailto link:
+ * 
+ *     columns: [
+ *         {
+ *             header: 'Email',
+ *             dataIndex: 'email',
+ *             renderer: function(value) {
+ *                 return Ext.String.format('<a href="mailto:{0}">{1}</a>', value, value);
+ *             }
+ *         }
+ *     ]
+ * 
+ * See the {@link Ext.grid.column.Column column docs} for more information on renderers.
+ * 
+ * ## Selection Models
+ * 
+ * Sometimes all you want is to render data onto the screen for viewing, but usually it's necessary to interact with or 
+ * update that data. Grids use a concept called a Selection Model, which is simply a mechanism for selecting some part of
+ * the data in the grid. The two main types of Selection Model are RowSelectionModel, where entire rows are selected, and
+ * CellSelectionModel, where individual cells are selected.
+ * 
+ * Grids use a Row Selection Model by default, but this is easy to customise like so:
+ * 
+ *     Ext.create('Ext.grid.Panel', {
+ *         selType: 'cellmodel',
+ *         store: ...
+ *     });
+ * 
+ * Specifying the `cellmodel` changes a couple of things. Firstly, clicking on a cell now
+ * selects just that cell (using a {@link Ext.selection.RowModel rowmodel} will select the entire row), and secondly the
+ * keyboard navigation will walk from cell to cell instead of row to row. Cell-based selection models are usually used in
+ * conjunction with editing.
+ * 
+ * {@img Ext.grid.Panel/Ext.grid.Panel2.png Ext.grid.Panel cell editing}
+ *
+ * ## Editing
+ * 
+ * Grid has built-in support for in-line editing. There are two chief editing modes - cell editing and row editing. Cell
+ * editing is easy to add to your existing column setup - here we'll just modify the example above to include an editor
+ * on both the name and the email columns:
+ * 
+ *     Ext.create('Ext.grid.Panel', {
+ *         title: 'Simpsons',
+ *         store: Ext.data.StoreManager.lookup('simpsonsStore'),
+ *         columns: [
+ *             {header: 'Name',  dataIndex: 'name', field: 'textfield'},
+ *             {header: 'Email', dataIndex: 'email', flex:1, 
+ *                 field:{
+ *                     xtype:'textfield',
+ *                     allowBlank:false
+ *                 }
+ *             },
+ *             {header: 'Phone', dataIndex: 'phone'}
+ *         ],
+ *         selType: 'cellmodel',
+ *         plugins: [
+ *             Ext.create('Ext.grid.plugin.CellEditing', {
+ *                 clicksToEdit: 1
+ *             })
+ *         ],
+ *         height: 200,
+ *         width: 400,
+ *         renderTo: Ext.getBody()
+ *     });
+ * 
+ * This requires a little explanation. We're passing in {@link #store store} and {@link #columns columns} as normal, but 
+ * this time we've also specified a {@link #field field} on two of our columns. For the Name column we just want a default
+ * textfield to edit the value, so we specify 'textfield'. For the Email column we customized the editor slightly by 
+ * passing allowBlank: false, which will provide inline validation.
+ * 
+ * To support cell editing, we also specified that the grid should use the 'cellmodel' {@link #selType}, and created an
+ * instance of the {@link Ext.grid.plugin.CellEditing CellEditing plugin}, which we configured to activate each editor after a
+ * single click.
+ * 
+ * {@img Ext.grid.Panel/Ext.grid.Panel3.png Ext.grid.Panel row editing}
+ *
+ * ## Row Editing
+ * 
+ * The other type of editing is row-based editing, using the RowEditor component. This enables you to edit an entire row
+ * at a time, rather than editing cell by cell. Row Editing works in exactly the same way as cell editing, all we need to
+ * do is change the plugin type to {@link Ext.grid.plugin.RowEditing}, and set the selType to 'rowmodel':
+ * 
+ *     Ext.create('Ext.grid.Panel', {
+ *         title: 'Simpsons',
+ *         store: Ext.data.StoreManager.lookup('simpsonsStore'),
+ *         columns: [
+ *             {header: 'Name',  dataIndex: 'name', field: 'textfield'},
+ *             {header: 'Email', dataIndex: 'email', flex:1, 
+ *                 field:{
+ *                     xtype:'textfield',
+ *                     allowBlank:false
+ *                 }
+ *             },
+ *             {header: 'Phone', dataIndex: 'phone'}
+ *         ],
+ *         selType: 'rowmodel',
+ *         plugins: [
+ *             Ext.create('Ext.grid.plugin.RowEditing', {
+ *                 clicksToEdit: 1
+ *             })
+ *         ],
+ *         height: 200,
+ *         width: 400,
+ *         renderTo: Ext.getBody()
+ *     });
+ * 
+ * Again we passed some configuration to our {@link Ext.grid.plugin.RowEditing} plugin, and now when we click each row a row
+ * editor will appear and enable us to edit each of the columns we have specified an editor for.
+ * 
+ * ## Sorting & Filtering
+ * 
+ * Every grid is attached to a {@link Ext.data.Store Store}, which provides multi-sort and filtering capabilities. It's
+ * easy to set up a grid to be sorted from the start:
+ * 
+ *     var myGrid = Ext.create('Ext.grid.Panel', {
+ *         store: {
+ *             fields: ['name', 'email', 'phone'],
+ *             sorters: ['name', 'phone']
+ *         },
+ *         columns: [
+ *             {text: 'Name',  dataIndex: 'name'},
+ *             {text: 'Email', dataIndex: 'email'}
+ *         ]
+ *     });
+ * 
+ * Sorting at run time is easily accomplished by simply clicking each column header. If you need to perform sorting on 
+ * more than one field at run time it's easy to do so by adding new sorters to the store:
+ * 
+ *     myGrid.store.sort([
+ *         {property: 'name',  direction: 'ASC'},
+ *         {property: 'email', direction: 'DESC'},
+ *     ]);
+ * 
+ * {@img Ext.grid.Panel/Ext.grid.Panel4.png Ext.grid.Panel grouping}
+ * 
+ * ## Grouping
+ * 
+ * Grid supports the grouping of rows by any field. For example if we had a set of employee records, we might want to 
+ * group by the department that each employee works in. Here's how we might set that up:
+ * 
+ *     var store = Ext.create('Ext.data.Store', {
+ *         storeId:'employeeStore',
+ *         fields:['name', 'senority', 'department'],
+ *         groupField: 'department',
+ *         data:{'employees':[
+ *             {"name":"Michael Scott", "senority":7, "department":"Manangement"},
+ *             {"name":"Dwight Schrute", "senority":2, "department":"Sales"},
+ *             {"name":"Jim Halpert", "senority":3, "department":"Sales"},
+ *             {"name":"Kevin Malone", "senority":4, "department":"Accounting"},
+ *             {"name":"Angela Martin", "senority":5, "department":"Accounting"}                        
+ *         ]},
+ *         proxy: {
+ *             type: 'memory',
+ *             reader: {
+ *                 type: 'json',
+ *                 root: 'employees'
+ *             }
+ *         }
+ *     });
+ *     
+ *     Ext.create('Ext.grid.Panel', {
+ *         title: 'Employees',
+ *         store: Ext.data.StoreManager.lookup('employeeStore'),
+ *         columns: [
+ *             {header: 'Name',  dataIndex: 'name'},
+ *             {header: 'Senority', dataIndex: 'senority'}
+ *         ],        
+ *         features: [{ftype:'grouping'}],
+ *         width: 200,
+ *         height: 275,
+ *         renderTo: Ext.getBody()
+ *     });
+ * 
+ * ## Infinite Scrolling
+ *
+ * Grid supports infinite scrolling as an alternative to using a paging toolbar. Your users can scroll through thousands
+ * of records without the performance penalties of renderering all the records on screen at once. The grid should be bound
+ * to a store with a pageSize specified.
+ *
+ *     var grid = Ext.create('Ext.grid.Panel', {
+ *         // Use a PagingGridScroller (this is interchangeable with a PagingToolbar)
+ *         verticalScrollerType: 'paginggridscroller',
+ *         // do not reset the scrollbar when the view refreshs
+ *         invalidateScrollerOnRefresh: false,
+ *         // infinite scrolling does not support selection
+ *         disableSelection: true,
+ *         // ...
+ *     });
+ * 
+ * ## Paging
+ *
+ * Grid supports paging through large sets of data via a PagingToolbar or PagingGridScroller (see the Infinite Scrolling section above).
+ * To leverage paging via a toolbar or scroller, you need to set a pageSize configuration on the Store.
+ *
+ *     var itemsPerPage = 2;   // set the number of items you want per page
+ *     
+ *     var store = Ext.create('Ext.data.Store', {
+ *         id:'simpsonsStore',
+ *         autoLoad: false,
+ *         fields:['name', 'email', 'phone'],
+ *         pageSize: itemsPerPage, // items per page
+ *         proxy: {
+ *             type: 'ajax',
+ *             url: 'pagingstore.js',  // url that will load data with respect to start and limit params
+ *             reader: {
+ *                 type: 'json',
+ *                 root: 'items',
+ *                 totalProperty: 'total'
+ *             }
+ *         }
+ *     });
+ *     
+ *     // specify segment of data you want to load using params
+ *     store.load({
+ *         params:{
+ *             start:0,    
+ *             limit: itemsPerPage
+ *         }
+ *     });
+ *     
+ *     Ext.create('Ext.grid.Panel', {
+ *         title: 'Simpsons',
+ *         store: store,
+ *         columns: [
+ *             {header: 'Name',  dataIndex: 'name'},
+ *             {header: 'Email', dataIndex: 'email', flex:1},
+ *             {header: 'Phone', dataIndex: 'phone'}
+ *         ],
+ *         width: 400,
+ *         height: 125,
+ *         dockedItems: [{
+ *             xtype: 'pagingtoolbar',
+ *             store: store,   // same store GridPanel is using
+ *             dock: 'bottom',
+ *             displayInfo: true
+ *         }],
+ *         renderTo: Ext.getBody()
+ *     }); 
+ * 
+ * {@img Ext.grid.Panel/Ext.grid.Panel5.png Ext.grid.Panel grouping}
+ * 
+ * @docauthor Ed Spencer
+ */
+Ext.define('Ext.grid.Panel', {
+    extend: 'Ext.panel.Table',
+    requires: ['Ext.grid.View'],
+    alias: ['widget.gridpanel', 'widget.grid'],
+    alternateClassName: ['Ext.list.ListView', 'Ext.ListView', 'Ext.grid.GridPanel'],
+    viewType: 'gridview',
     
-    Ext.create('Ext.button.Button', {
-        text    : 'Get active tab',
-        scope   : this,
-        handler : function() {
-            var tab = tabs.getActiveTab();
-            alert('Current tab: ' + tab.title);
-        },
-        renderTo : Ext.getBody()        
-    });
-
-Adding a new tab is very simple with a TabPanel. You simple call the {@link #add} method with an config object for a panel.
-
-Example usage:
-
-    var tabs = Ext.Create('Ext.tab.Panel', {
-        items: [
-            {
-                title: 'Tab 1',
-                html : 'A simple tab'
-            },
-            {
-                title: 'Tab 2',
-                html : 'Another one'
-            }
-        ],
-        renderTo : Ext.getBody()        
-    });
+    lockable: false,
     
-    Ext.create('Ext.button.Button', {
-        text    : 'New tab',
-        scope   : this,
-        handler : function() {
-            var tab = tabs.add({
-                title: 'Tab ' + (tabs.items.length + 1), //we use the tabs.items property to get the length of current items/tabs
-                html : 'Another one'
-            });
-            
-            tabs.setActiveTab(tab);
-        },
-        renderTo : Ext.getBody()
-    });
-
-Additionally, removing a tab is very also simple with a TabPanel. You simple call the {@link #remove} method with an config object for a panel.
-
-Example usage:
-
-    var tabs = Ext.Create('Ext.tab.Panel', {        
-        items: [
-            {
-                title: 'Tab 1',
-                html : 'A simple tab'
-            },
-            {
-                id   : 'remove-this-tab',
-                title: 'Tab 2',
-                html : 'Another one'
-            }
-        ],
-        renderTo : Ext.getBody()
-    });
+    // Required for the Lockable Mixin. These are the configurations which will be copied to the
+    // normal and locked sub tablepanels
+    normalCfgCopy: ['invalidateScrollerOnRefresh', 'verticalScroller', 'verticalScrollDock', 'verticalScrollerType', 'scroll'],
+    lockedCfgCopy: ['invalidateScrollerOnRefresh'],
     
-    Ext.Create('Ext.button.Button', {
-        text    : 'Remove tab',
-        scope   : this,
-        handler : function() {
-            var tab = Ext.getCmp('remove-this-tab');
-            tabs.remove(tab);
-        },
-        renderTo : Ext.getBody()
-    });
-
- * @extends Ext.Panel
- * @constructor
- * @param {Object} config The configuration options
- * @xtype tabpanel
- * @markdown
- */
-Ext.define('Ext.tab.Panel', {
-    extend: 'Ext.panel.Panel',
-    alias: 'widget.tabpanel',
-    alternateClassName: ['Ext.TabPanel'],
-
-    requires: ['Ext.layout.container.Card', 'Ext.tab.Bar'],
-
-    /**
-     * @cfg {String} tabPosition The position where the tab strip should be rendered (defaults to <code>'top'</code>).
-     * In 4.0, The only other supported value is <code>'bottom'</code>.
+    /**
+     * @cfg {Boolean} columnLines Adds column line styling
      */
-    tabPosition : 'top',
     
-    /**
-     * @cfg {Object} tabBar Optional configuration object for the internal {@link Ext.tab.Bar}. If present, this is 
-     * passed straight through to the TabBar's constructor
-     */
-
-    /**
-     * @cfg {Object} layout Optional configuration object for the internal {@link Ext.layout.container.Card card layout}.
-     * If present, this is passed straight through to the layout's constructor
-     */
-
-    /**
-     * @cfg {Boolean} removePanelHeader True to instruct each Panel added to the TabContainer to not render its header 
-     * element. This is to ensure that the title of the panel does not appear twice. Defaults to true.
-     */
-    removePanelHeader: true,
-
-    /**
-     * @cfg Boolean plain
-     * True to not show the full background on the TabBar
-     */
-    plain: false,
-
-    /**
-     * @cfg {String} itemCls The class added to each child item of this TabPanel. Defaults to 'x-tabpanel-child'.
-     */
-    itemCls: 'x-tabpanel-child',
-
-    /**
-     * @cfg {Number} minTabWidth The minimum width for a tab in the {@link #tabBar}. Defaults to <code>30</code>.
-     */
-
-    /**
-     * @cfg {Boolean} deferredRender
-     * <p><tt>true</tt> by default to defer the rendering of child <tt>{@link Ext.container.Container#items items}</tt>
-     * to the browsers DOM until a tab is activated. <tt>false</tt> will render all contained
-     * <tt>{@link Ext.container.Container#items items}</tt> as soon as the {@link Ext.layout.container.Card layout}
-     * is rendered. If there is a significant amount of content or a lot of heavy controls being
-     * rendered into panels that are not displayed by default, setting this to <tt>true</tt> might
-     * improve performance.</p>
-     * <br><p>The <tt>deferredRender</tt> property is internally passed to the layout manager for
-     * TabPanels ({@link Ext.layout.container.Card}) as its {@link Ext.layout.container.Card#deferredRender}
-     * configuration value.</p>
-     * <br><p><b>Note</b>: leaving <tt>deferredRender</tt> as <tt>true</tt> means that the content
-     * within an unactivated tab will not be available</p>
-     */
-    deferredRender : true,
-
-    //inherit docs
     initComponent: function() {
-        var me = this,
-            dockedItems = me.dockedItems || [],
-            activeTab = me.activeTab || 0;
-
-        me.layout = Ext.create('Ext.layout.container.Card', Ext.apply({
-            owner: me,
-            deferredRender: me.deferredRender,
-            itemCls: me.itemCls
-        }, me.layout));
-
-        /**
-         * @property tabBar
-         * @type Ext.TabBar
-         * Internal reference to the docked TabBar
-         */
-        me.tabBar = Ext.create('Ext.tab.Bar', Ext.apply({}, me.tabBar, {
-            dock: me.tabPosition,
-            plain: me.plain,
-            border: me.border,
-            cardLayout: me.layout,
-            tabPanel: me
-        }));
-
-        if (dockedItems && !Ext.isArray(dockedItems)) {
-            dockedItems = [dockedItems];
-        }
-
-        dockedItems.push(me.tabBar);
-        me.dockedItems = dockedItems;
-
-        me.addEvents(
-            /**
-             * @event beforetabchange
-             * Fires before a tab change (activated by {@link #setActiveTab}). Return false in any listener to cancel
-             * the tabchange
-             * @param {Ext.tab.Panel} tabPanel The TabPanel
-             * @param {Ext.Component} newCard The card that is about to be activated
-             * @param {Ext.Component} oldCard The card that is currently active
-             */
-            'beforetabchange',
-
-            /**
-             * @event tabchange
-             * Fires when a new tab has been activated (activated by {@link #setActiveTab}).
-             * @param {Ext.tab.Panel} tabPanel The TabPanel
-             * @param {Ext.Component} newCard The newly activated item
-             * @param {Ext.Component} oldCard The previously active item
-             */
-            'tabchange'
-        );
-        me.callParent(arguments);
-
-        //set the active tab
-        me.setActiveTab(activeTab);
-        //set the active tab after initial layout
-        me.on('afterlayout', me.afterInitialLayout, me, {single: true});
-    },
-
-    /**
-     * @private
-     * We have to wait until after the initial layout to visually activate the activeTab (if set).
-     * The active tab has different margins than normal tabs, so if the initial layout happens with
-     * a tab active, its layout will be offset improperly due to the active margin style. Waiting
-     * until after the initial layout avoids this issue.
-     */
-    afterInitialLayout: function() {
-        var me = this,
-            card = me.getComponent(me.activeTab);
-            
-        if (card) {
-            me.layout.setActiveItem(card);
-        }
-    },
-
-    /**
-     * Makes the given card active (makes it the visible card in the TabPanel's CardLayout and highlights the Tab)
-     * @param {Ext.Component} card The card to make active
-     */
-    setActiveTab: function(card) {
-        var me = this,
-            previous;
-
-        card = me.getComponent(card);
-        if (card) {
-            previous = me.getActiveTab();
-            
-            if (previous && previous !== card && me.fireEvent('beforetabchange', me, card, previous) === false) {
-                return false;
-            }
-            
-            me.tabBar.setActiveTab(card.tab);
-            me.activeTab = card;
-            if (me.rendered) {
-                me.layout.setActiveItem(card);
-            }
-            
-            if (previous && previous !== card) {
-                me.fireEvent('tabchange', me, card, previous);
-            }
-        }
-    },
-
-    /**
-     * Returns the item that is currently active inside this TabPanel. Note that before the TabPanel first activates a
-     * child component this will return whatever was configured in the {@link #activeTab} config option 
-     * @return {Ext.Component/Integer} The currently active item
-     */
-    getActiveTab: function() {
-        return this.activeTab;
-    },
-
-    /**
-     * Returns the {@link Ext.tab.Bar} currently used in this TabPanel
-     * @return {Ext.TabBar} The TabBar
-     */
-    getTabBar: function() {
-        return this.tabBar;
-    },
-
-    /**
-     * @ignore
-     * Makes sure we have a Tab for each item added to the TabPanel
-     */
-    onAdd: function(item, index) {
         var me = this;
 
-        item.tab = me.tabBar.insert(index, {
-            xtype: 'tab',
-            card: item,
-            disabled: item.disabled,
-            closable: item.closable,
-            hidden: item.hidden,
-            tabBar: me.tabBar
-        });
-        
-        item.on({
-            scope : me,
-            enable: me.onItemEnable,
-            disable: me.onItemDisable,
-            beforeshow: me.onItemBeforeShow,
-            iconchange: me.onItemIconChange,
-            titlechange: me.onItemTitleChange
-        });
-
-        if (item.isPanel) {
-            if (me.removePanelHeader) {
-                item.preventHeader = true;
-                if (item.rendered) {
-                    item.updateHeader();
-                }
-            }
-            if (item.isPanel && me.border) {
-                item.setBorder(false);
-            }
-        }
-
-        // ensure that there is at least one active tab
-        if (this.rendered && me.items.getCount() === 1) {
-            me.setActiveTab(0);
+        if (me.columnLines) {
+            me.setColumnLines(me.columnLines);
         }
+        
+        me.callParent();
     },
     
-    /**
-     * @private
-     * Enable corresponding tab when item is enabled.
-     */
-    onItemEnable: function(item){
-        item.tab.enable();
-    },
-
-    /**
-     * @private
-     * Disable corresponding tab when item is enabled.
-     */    
-    onItemDisable: function(item){
-        item.tab.disable();
-    },
-    
-    /**
-     * @private
-     * Sets activeTab before item is shown.
-     */
-    onItemBeforeShow: function(item) {
-        if (item !== this.activeTab) {
-            this.setActiveTab(item);
-            return false;
-        }    
-    },
-    
-    /**
-     * @private
-     * Update the tab iconCls when panel iconCls has been set or changed.
-     */
-    onItemIconChange: function(item, newIconCls) {
-        item.tab.setIconCls(newIconCls);
-        this.getTabBar().doLayout();
-    },
-    
-    /**
-     * @private
-     * Update the tab title when panel title has been set or changed.
-     */
-    onItemTitleChange: function(item, newTitle) {
-        item.tab.setText(newTitle);
-        this.getTabBar().doLayout();
-    },
-
-
-    /**
-     * @ignore
-     * If we're removing the currently active tab, activate the nearest one. The item is removed when we call super,
-     * so we can do preprocessing before then to find the card's index
-     */
-    doRemove: function(item, autoDestroy) {
+    setColumnLines: function(show) {
         var me = this,
-            items = me.items,
-            /**
-             * At this point the item hasn't been removed from the items collection.
-             * As such, if we want to check if there are no more tabs left, we have to
-             * check for one, as opposed to 0.
-             */
-            hasItemsLeft = items.getCount() > 1;
-
-        if (me.destroying || !hasItemsLeft) {
-            me.activeTab = null;
-        } else if (item === me.activeTab) {
-             me.setActiveTab(item.next() || items.getAt(0)); 
-        }
-        me.callParent(arguments);
-
-        // Remove the two references
-        delete item.tab.card;
-        delete item.tab;
-    },
-
-    /**
-     * @ignore
-     * Makes sure we remove the corresponding Tab when an item is removed
-     */
-    onRemove: function(item, autoDestroy) {
-        var me = this;
+            method = (show) ? 'addClsWithUI' : 'removeClsWithUI';
         
-        item.un({
-            scope : me,
-            enable: me.onItemEnable,
-            disable: me.onItemDisable,
-            beforeshow: me.onItemBeforeShow
-        });
-        if (!me.destroying && item.tab.ownerCt == me.tabBar) {
-            me.tabBar.remove(item.tab);
-        }
+        me[method]('with-col-lines')
     }
-});
-
+});