Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Table.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-panel-Table'>/**
19 </span> * @class Ext.panel.Table
20  * @extends Ext.panel.Panel
21  * @author Nicolas Ferrero
22  * TablePanel is the basis of both TreePanel and GridPanel.
23  *
24  * TablePanel aggregates:
25  *
26  *  - a Selection Model
27  *  - a View
28  *  - a Store
29  *  - Scrollers
30  *  - Ext.grid.header.Container
31  *
32  */
33 Ext.define('Ext.panel.Table', {
34     extend: 'Ext.panel.Panel',
35
36     alias: 'widget.tablepanel',
37
38     uses: [
39         'Ext.selection.RowModel',
40         'Ext.grid.Scroller',
41         'Ext.grid.header.Container',
42         'Ext.grid.Lockable'
43     ],
44
45     cls: Ext.baseCSSPrefix + 'grid',
46     extraBodyCls: Ext.baseCSSPrefix + 'grid-body',
47
48     layout: 'fit',
49 <span id='Ext-panel-Table-property-hasView'>    /**
50 </span>     * Boolean to indicate that a view has been injected into the panel.
51      * @property hasView
52      */
53     hasView: false,
54
55     // each panel should dictate what viewType and selType to use
56     viewType: null,
57     selType: 'rowmodel',
58
59 <span id='Ext-panel-Table-cfg-scrollDelta'>    /**
60 </span>     * @cfg {Number} scrollDelta
61      * Number of pixels to scroll when scrolling with mousewheel.
62      * Defaults to 40.
63      */
64     scrollDelta: 40,
65
66 <span id='Ext-panel-Table-cfg-scroll'>    /**
67 </span>     * @cfg {String/Boolean} scroll
68      * Valid values are 'both', 'horizontal' or 'vertical'. true implies 'both'. false implies 'none'.
69      * Defaults to true.
70      */
71     scroll: true,
72
73 <span id='Ext-panel-Table-cfg-columns'>    /**
74 </span>     * @cfg {Array} columns
75      * An array of {@link Ext.grid.column.Column column} definition objects which define all columns that appear in this grid. Each
76      * column definition provides the header text for the column, and a definition of where the data for that column comes from.
77      */
78
79 <span id='Ext-panel-Table-cfg-forceFit'>    /**
80 </span>     * @cfg {Boolean} forceFit
81      * Specify as &lt;code&gt;true&lt;/code&gt; to force the columns to fit into the available width. Headers are first sized according to configuration, whether that be
82      * a specific width, or flex. Then they are all proportionally changed in width so that the entire content width is used..
83      */
84
85 <span id='Ext-panel-Table-cfg-hideHeaders'>    /**
86 </span>     * @cfg {Boolean} hideHeaders
87      * Specify as &lt;code&gt;true&lt;/code&gt; to hide the headers.
88      */
89
90 <span id='Ext-panel-Table-cfg-deferRowRender'>    /**
91 </span>     * @cfg {Boolean} deferRowRender &lt;P&gt;Defaults to &lt;code&gt;true&lt;/code&gt; to enable deferred row rendering.&lt;/p&gt;
92      * &lt;p&gt;This allows the GridView to execute a refresh quickly, with the expensive update of the row
93      * structure deferred so that layouts with GridPanels appear, and lay out more quickly.&lt;/p&gt;
94      */
95
96 <span id='Ext-panel-Table-cfg-sortableColumns'>    /**
97 </span>     * @cfg {Boolean} sortableColumns
98      * Defaults to &lt;code&gt;true&lt;/code&gt;. Set to &lt;code&gt;false&lt;/code&gt; to disable column sorting via clicking the
99      * header and via the Sorting menu items.
100      */
101     sortableColumns: true,
102
103     verticalScrollDock: 'right',
104     verticalScrollerType: 'gridscroller',
105
106     horizontalScrollerPresentCls: Ext.baseCSSPrefix + 'horizontal-scroller-present',
107     verticalScrollerPresentCls: Ext.baseCSSPrefix + 'vertical-scroller-present',
108
109     // private property used to determine where to go down to find views
110     // this is here to support locking.
111     scrollerOwner: true,
112
113     invalidateScrollerOnRefresh: true,
114
115 <span id='Ext-panel-Table-cfg-enableColumnMove'>    /**
116 </span>     * @cfg {Boolean} enableColumnMove
117      * Defaults to &lt;code&gt;true&lt;/code&gt;. Set to &lt;code&gt;false&lt;/code&gt; to disable column dragging within this grid.
118      */
119     enableColumnMove: true,
120
121 <span id='Ext-panel-Table-cfg-enableColumnResize'>    /**
122 </span>     * @cfg {Boolean} enableColumnResize
123      * Defaults to &lt;code&gt;true&lt;/code&gt;. Set to &lt;code&gt;false&lt;/code&gt; to disable column resizing within this grid.
124      */
125     enableColumnResize: true,
126
127 <span id='Ext-panel-Table-cfg-enableColumnHide'>    /**
128 </span>     * @cfg {Boolean} enableColumnHide
129      * Defaults to &lt;code&gt;true&lt;/code&gt;. Set to &lt;code&gt;false&lt;/code&gt; to disable column hiding within this grid.
130      */
131     enableColumnHide: true,
132
133     initComponent: function() {
134         //&lt;debug&gt;
135         if (!this.viewType) {
136             Ext.Error.raise(&quot;You must specify a viewType config.&quot;);
137         }
138         if (!this.store) {
139             Ext.Error.raise(&quot;You must specify a store config&quot;);
140         }
141         if (this.headers) {
142             Ext.Error.raise(&quot;The headers config is not supported. Please specify columns instead.&quot;);
143         }
144         //&lt;/debug&gt;
145
146         var me          = this,
147             scroll      = me.scroll,
148             vertical    = false,
149             horizontal  = false,
150             headerCtCfg = me.columns || me.colModel,
151             i           = 0,
152             view,
153             border = me.border;
154
155         // We cannot buffer this because that will wait for the 30msec from afterLayout (or what
156         // ever event triggers it) and we may be in the middle of an animation; that is a bad
157         // time to injectView because it causes a layout (by calling add on the container). A
158         // throttled func will be called immediately on first call and then block subsequent
159         // (rapid fire) calls for 30msec before allowing another call to go through. Similar
160         // results, but the action moves from the trailing edge of the interval to the leading
161         // edge.
162         me.injectView = Ext.Function.createThrottled(me.injectView, 30, me);
163
164         if (me.hideHeaders) {
165             border = false;
166         }
167
168         // The columns/colModel config may be either a fully instantiated HeaderContainer, or an array of Column definitions, or a config object of a HeaderContainer
169         // Either way, we extract a columns property referencing an array of Column definitions.
170         if (headerCtCfg instanceof Ext.grid.header.Container) {
171             me.headerCt = headerCtCfg;
172             me.headerCt.border = border;
173             me.columns = me.headerCt.items.items;
174         } else {
175             if (Ext.isArray(headerCtCfg)) {
176                 headerCtCfg = {
177                     items: headerCtCfg,
178                     border: border
179                 };
180             }
181             Ext.apply(headerCtCfg, {
182                 forceFit: me.forceFit,
183                 sortable: me.sortableColumns,
184                 enableColumnMove: me.enableColumnMove,
185                 enableColumnResize: me.enableColumnResize,
186                 enableColumnHide: me.enableColumnHide,
187                 border:  border
188             });
189             me.columns = headerCtCfg.items;
190
191              // If any of the Column objects contain a locked property, and are not processed, this is a lockable TablePanel, a
192              // special view will be injected by the Ext.grid.Lockable mixin, so no processing of .
193              if (Ext.ComponentQuery.query('{locked !== undefined}{processed != true}', me.columns).length) {
194                  me.self.mixin('lockable', Ext.grid.Lockable);
195                  me.injectLockable();
196              }
197         }
198
199         me.store = Ext.data.StoreManager.lookup(me.store);
200         me.addEvents(
201 <span id='Ext-panel-Table-event-reconfigure'>            /**
202 </span>             * @event reconfigure
203              * Fires after a reconfigure
204              * @param {Ext.panel.Table} this
205              */
206             'reconfigure',
207 <span id='Ext-panel-Table-event-scrollerhide'>            /**
208 </span>             * @event scrollerhide
209              * Fires when a scroller is hidden
210              * @param {Ext.grid.Scroller} scroller
211              * @param {String} orientation Orientation, can be 'vertical' or 'horizontal'
212              */
213             'scrollerhide',
214 <span id='Ext-panel-Table-event-scrollershow'>            /**
215 </span>             * @event scrollershow
216              * Fires when a scroller is shown
217              * @param {Ext.grid.Scroller} scroller
218              * @param {String} orientation Orientation, can be 'vertical' or 'horizontal'
219              */
220             'scrollershow'
221         );
222
223         me.bodyCls = me.bodyCls || '';
224         me.bodyCls += (' ' + me.extraBodyCls);
225
226         // autoScroll is not a valid configuration
227         delete me.autoScroll;
228
229         // If this TablePanel is lockable (Either configured lockable, or any of the defined columns has a 'locked' property)
230         // than a special lockable view containing 2 side-by-side grids will have been injected so we do not need to set up any UI.
231         if (!me.hasView) {
232
233             // If we were not configured with a ready-made headerCt (either by direct config with a headerCt property, or by passing
234             // a HeaderContainer instance as the 'columns' property, then go ahead and create one from the config object created above.
235             if (!me.headerCt) {
236                 me.headerCt = Ext.create('Ext.grid.header.Container', headerCtCfg);
237             }
238
239             // Extract the array of Column objects
240             me.columns = me.headerCt.items.items;
241
242             if (me.hideHeaders) {
243                 me.headerCt.height = 0;
244                 me.headerCt.border = false;
245                 me.headerCt.addCls(Ext.baseCSSPrefix + 'grid-header-ct-hidden');
246                 me.addCls(Ext.baseCSSPrefix + 'grid-header-hidden');
247                 // IE Quirks Mode fix
248                 // If hidden configuration option was used, several layout calculations will be bypassed.
249                 if (Ext.isIEQuirks) {
250                     me.headerCt.style = {
251                         display: 'none'
252                     };
253                 }
254             }
255
256             // turn both on.
257             if (scroll === true || scroll === 'both') {
258                 vertical = horizontal = true;
259             } else if (scroll === 'horizontal') {
260                 horizontal = true;
261             } else if (scroll === 'vertical') {
262                 vertical = true;
263             // All other values become 'none' or false.
264             } else {
265                 me.headerCt.availableSpaceOffset = 0;
266             }
267
268             if (vertical) {
269                 me.verticalScroller = Ext.ComponentManager.create(me.initVerticalScroller());
270                 me.mon(me.verticalScroller, {
271                     bodyscroll: me.onVerticalScroll,
272                     scope: me
273                 });
274             }
275
276             if (horizontal) {
277                 me.horizontalScroller = Ext.ComponentManager.create(me.initHorizontalScroller());
278                 me.mon(me.horizontalScroller, {
279                     bodyscroll: me.onHorizontalScroll,
280                     scope: me
281                 });
282             }
283
284             me.headerCt.on('columnresize', me.onHeaderResize, me);
285             me.relayEvents(me.headerCt, ['columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange']);
286             me.features = me.features || [];
287             me.dockedItems = me.dockedItems || [];
288             me.dockedItems.unshift(me.headerCt);
289             me.viewConfig = me.viewConfig || {};
290             me.viewConfig.invalidateScrollerOnRefresh = me.invalidateScrollerOnRefresh;
291
292             // AbstractDataView will look up a Store configured as an object
293             // getView converts viewConfig into a View instance
294             view = me.getView();
295
296             if (view) {
297                 me.mon(view.store, {
298                     load: me.onStoreLoad,
299                     scope: me
300                 });
301                 me.mon(view, {
302                     refresh: me.onViewRefresh,
303                     scope: me
304                 });
305                 this.relayEvents(view, [
306 <span id='Ext-panel-Table-event-beforeitemmousedown'>                    /**
307 </span>                     * @event beforeitemmousedown
308                      * Fires before the mousedown event on an item is processed. Returns false to cancel the default action.
309                      * @param {Ext.view.View} this
310                      * @param {Ext.data.Model} record The record that belongs to the item
311                      * @param {HTMLElement} item The item's element
312                      * @param {Number} index The item's index
313                      * @param {Ext.EventObject} e The raw event object
314                      */
315                     'beforeitemmousedown',
316 <span id='Ext-panel-Table-event-beforeitemmouseup'>                    /**
317 </span>                     * @event beforeitemmouseup
318                      * Fires before the mouseup event on an item is processed. Returns false to cancel the default action.
319                      * @param {Ext.view.View} this
320                      * @param {Ext.data.Model} record The record that belongs to the item
321                      * @param {HTMLElement} item The item's element
322                      * @param {Number} index The item's index
323                      * @param {Ext.EventObject} e The raw event object
324                      */
325                     'beforeitemmouseup',
326 <span id='Ext-panel-Table-event-beforeitemmouseenter'>                    /**
327 </span>                     * @event beforeitemmouseenter
328                      * Fires before the mouseenter event on an item is processed. Returns false to cancel the default action.
329                      * @param {Ext.view.View} this
330                      * @param {Ext.data.Model} record The record that belongs to the item
331                      * @param {HTMLElement} item The item's element
332                      * @param {Number} index The item's index
333                      * @param {Ext.EventObject} e The raw event object
334                      */
335                     'beforeitemmouseenter',
336 <span id='Ext-panel-Table-event-beforeitemmouseleave'>                    /**
337 </span>                     * @event beforeitemmouseleave
338                      * Fires before the mouseleave event on an item is processed. Returns false to cancel the default action.
339                      * @param {Ext.view.View} this
340                      * @param {Ext.data.Model} record The record that belongs to the item
341                      * @param {HTMLElement} item The item's element
342                      * @param {Number} index The item's index
343                      * @param {Ext.EventObject} e The raw event object
344                      */
345                     'beforeitemmouseleave',
346 <span id='Ext-panel-Table-event-beforeitemclick'>                    /**
347 </span>                     * @event beforeitemclick
348                      * Fires before the click event on an item is processed. Returns false to cancel the default action.
349                      * @param {Ext.view.View} this
350                      * @param {Ext.data.Model} record The record that belongs to the item
351                      * @param {HTMLElement} item The item's element
352                      * @param {Number} index The item's index
353                      * @param {Ext.EventObject} e The raw event object
354                      */
355                     'beforeitemclick',
356 <span id='Ext-panel-Table-event-beforeitemdblclick'>                    /**
357 </span>                     * @event beforeitemdblclick
358                      * Fires before the dblclick event on an item is processed. Returns false to cancel the default action.
359                      * @param {Ext.view.View} this
360                      * @param {Ext.data.Model} record The record that belongs to the item
361                      * @param {HTMLElement} item The item's element
362                      * @param {Number} index The item's index
363                      * @param {Ext.EventObject} e The raw event object
364                      */
365                     'beforeitemdblclick',
366 <span id='Ext-panel-Table-event-beforeitemcontextmenu'>                    /**
367 </span>                     * @event beforeitemcontextmenu
368                      * Fires before the contextmenu event on an item is processed. Returns false to cancel the default action.
369                      * @param {Ext.view.View} this
370                      * @param {Ext.data.Model} record The record that belongs to the item
371                      * @param {HTMLElement} item The item's element
372                      * @param {Number} index The item's index
373                      * @param {Ext.EventObject} e The raw event object
374                      */
375                     'beforeitemcontextmenu',
376 <span id='Ext-panel-Table-event-itemmousedown'>                    /**
377 </span>                     * @event itemmousedown
378                      * Fires when there is a mouse down on an item
379                      * @param {Ext.view.View} this
380                      * @param {Ext.data.Model} record The record that belongs to the item
381                      * @param {HTMLElement} item The item's element
382                      * @param {Number} index The item's index
383                      * @param {Ext.EventObject} e The raw event object
384                      */
385                     'itemmousedown',
386 <span id='Ext-panel-Table-event-itemmouseup'>                    /**
387 </span>                     * @event itemmouseup
388                      * Fires when there is a mouse up on an item
389                      * @param {Ext.view.View} this
390                      * @param {Ext.data.Model} record The record that belongs to the item
391                      * @param {HTMLElement} item The item's element
392                      * @param {Number} index The item's index
393                      * @param {Ext.EventObject} e The raw event object
394                      */
395                     'itemmouseup',
396 <span id='Ext-panel-Table-event-itemmouseenter'>                    /**
397 </span>                     * @event itemmouseenter
398                      * Fires when the mouse enters an item.
399                      * @param {Ext.view.View} this
400                      * @param {Ext.data.Model} record The record that belongs to the item
401                      * @param {HTMLElement} item The item's element
402                      * @param {Number} index The item's index
403                      * @param {Ext.EventObject} e The raw event object
404                      */
405                     'itemmouseenter',
406 <span id='Ext-panel-Table-event-itemmouseleave'>                    /**
407 </span>                     * @event itemmouseleave
408                      * Fires when the mouse leaves an item.
409                      * @param {Ext.view.View} this
410                      * @param {Ext.data.Model} record The record that belongs to the item
411                      * @param {HTMLElement} item The item's element
412                      * @param {Number} index The item's index
413                      * @param {Ext.EventObject} e The raw event object
414                      */
415                     'itemmouseleave',
416 <span id='Ext-panel-Table-event-itemclick'>                    /**
417 </span>                     * @event itemclick
418                      * Fires when an item is clicked.
419                      * @param {Ext.view.View} this
420                      * @param {Ext.data.Model} record The record that belongs to the item
421                      * @param {HTMLElement} item The item's element
422                      * @param {Number} index The item's index
423                      * @param {Ext.EventObject} e The raw event object
424                      */
425                     'itemclick',
426 <span id='Ext-panel-Table-event-itemdblclick'>                    /**
427 </span>                     * @event itemdblclick
428                      * Fires when an item is double clicked.
429                      * @param {Ext.view.View} this
430                      * @param {Ext.data.Model} record The record that belongs to the item
431                      * @param {HTMLElement} item The item's element
432                      * @param {Number} index The item's index
433                      * @param {Ext.EventObject} e The raw event object
434                      */
435                     'itemdblclick',
436 <span id='Ext-panel-Table-event-itemcontextmenu'>                    /**
437 </span>                     * @event itemcontextmenu
438                      * Fires when an item is right clicked.
439                      * @param {Ext.view.View} this
440                      * @param {Ext.data.Model} record The record that belongs to the item
441                      * @param {HTMLElement} item The item's element
442                      * @param {Number} index The item's index
443                      * @param {Ext.EventObject} e The raw event object
444                      */
445                     'itemcontextmenu',
446 <span id='Ext-panel-Table-event-beforecontainermousedown'>                    /**
447 </span>                     * @event beforecontainermousedown
448                      * Fires before the mousedown event on the container is processed. Returns false to cancel the default action.
449                      * @param {Ext.view.View} this
450                      * @param {Ext.EventObject} e The raw event object
451                      */
452                     'beforecontainermousedown',
453 <span id='Ext-panel-Table-event-beforecontainermouseup'>                    /**
454 </span>                     * @event beforecontainermouseup
455                      * Fires before the mouseup event on the container is processed. Returns false to cancel the default action.
456                      * @param {Ext.view.View} this
457                      * @param {Ext.EventObject} e The raw event object
458                      */
459                     'beforecontainermouseup',
460 <span id='Ext-panel-Table-event-beforecontainermouseover'>                    /**
461 </span>                     * @event beforecontainermouseover
462                      * Fires before the mouseover event on the container is processed. Returns false to cancel the default action.
463                      * @param {Ext.view.View} this
464                      * @param {Ext.EventObject} e The raw event object
465                      */
466                     'beforecontainermouseover',
467 <span id='Ext-panel-Table-event-beforecontainermouseout'>                    /**
468 </span>                     * @event beforecontainermouseout
469                      * Fires before the mouseout event on the container is processed. Returns false to cancel the default action.
470                      * @param {Ext.view.View} this
471                      * @param {Ext.EventObject} e The raw event object
472                      */
473                     'beforecontainermouseout',
474 <span id='Ext-panel-Table-event-beforecontainerclick'>                    /**
475 </span>                     * @event beforecontainerclick
476                      * Fires before the click event on the container is processed. Returns false to cancel the default action.
477                      * @param {Ext.view.View} this
478                      * @param {Ext.EventObject} e The raw event object
479                      */
480                     'beforecontainerclick',
481 <span id='Ext-panel-Table-event-beforecontainerdblclick'>                    /**
482 </span>                     * @event beforecontainerdblclick
483                      * Fires before the dblclick event on the container is processed. Returns false to cancel the default action.
484                      * @param {Ext.view.View} this
485                      * @param {Ext.EventObject} e The raw event object
486                      */
487                     'beforecontainerdblclick',
488 <span id='Ext-panel-Table-event-beforecontainercontextmenu'>                    /**
489 </span>                     * @event beforecontainercontextmenu
490                      * Fires before the contextmenu event on the container is processed. Returns false to cancel the default action.
491                      * @param {Ext.view.View} this
492                      * @param {Ext.EventObject} e The raw event object
493                      */
494                     'beforecontainercontextmenu',
495 <span id='Ext-panel-Table-event-containermouseup'>                    /**
496 </span>                     * @event containermouseup
497                      * Fires when there is a mouse up on the container
498                      * @param {Ext.view.View} this
499                      * @param {Ext.EventObject} e The raw event object
500                      */
501                     'containermouseup',
502 <span id='Ext-panel-Table-event-containermouseover'>                    /**
503 </span>                     * @event containermouseover
504                      * Fires when you move the mouse over the container.
505                      * @param {Ext.view.View} this
506                      * @param {Ext.EventObject} e The raw event object
507                      */
508                     'containermouseover',
509 <span id='Ext-panel-Table-event-containermouseout'>                    /**
510 </span>                     * @event containermouseout
511                      * Fires when you move the mouse out of the container.
512                      * @param {Ext.view.View} this
513                      * @param {Ext.EventObject} e The raw event object
514                      */
515                     'containermouseout',
516 <span id='Ext-panel-Table-event-containerclick'>                    /**
517 </span>                     * @event containerclick
518                      * Fires when the container is clicked.
519                      * @param {Ext.view.View} this
520                      * @param {Ext.EventObject} e The raw event object
521                      */
522                     'containerclick',
523 <span id='Ext-panel-Table-event-containerdblclick'>                    /**
524 </span>                     * @event containerdblclick
525                      * Fires when the container is double clicked.
526                      * @param {Ext.view.View} this
527                      * @param {Ext.EventObject} e The raw event object
528                      */
529                     'containerdblclick',
530 <span id='Ext-panel-Table-event-containercontextmenu'>                    /**
531 </span>                     * @event containercontextmenu
532                      * Fires when the container is right clicked.
533                      * @param {Ext.view.View} this
534                      * @param {Ext.EventObject} e The raw event object
535                      */
536                     'containercontextmenu',
537
538 <span id='Ext-panel-Table-event-selectionchange'>                    /**
539 </span>                     * @event selectionchange
540                      * Fires when the selected nodes change. Relayed event from the underlying selection model.
541                      * @param {Ext.view.View} this
542                      * @param {Array} selections Array of the selected nodes
543                      */
544                     'selectionchange',
545 <span id='Ext-panel-Table-event-beforeselect'>                    /**
546 </span>                     * @event beforeselect
547                      * Fires before a selection is made. If any handlers return false, the selection is cancelled.
548                      * @param {Ext.view.View} this
549                      * @param {HTMLElement} node The node to be selected
550                      * @param {Array} selections Array of currently selected nodes
551                      */
552                     'beforeselect'
553                 ]);
554             }
555         }
556         me.callParent(arguments);
557     },
558
559     // state management
560     initStateEvents: function(){
561         var events = this.stateEvents;
562         // push on stateEvents if they don't exist
563         Ext.each(['columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange'], function(event){
564             if (Ext.Array.indexOf(events, event)) {
565                 events.push(event);
566             }
567         });
568         this.callParent();
569     },
570
571 <span id='Ext-panel-Table-method-initHorizontalScroller'>    /**
572 </span>     * Returns the horizontal scroller config.
573      */
574     initHorizontalScroller: function () {
575         var me = this,
576             ret = {
577                 xtype: 'gridscroller',
578                 dock: 'bottom',
579                 section: me,
580                 store: me.store
581             };
582
583         return ret;
584     },
585
586 <span id='Ext-panel-Table-method-initVerticalScroller'>    /**
587 </span>     * Returns the vertical scroller config.
588      */
589     initVerticalScroller: function () {
590         var me = this,
591             ret = me.verticalScroller || {};
592
593         Ext.applyIf(ret, {
594             xtype: me.verticalScrollerType,
595             dock: me.verticalScrollDock,
596             store: me.store
597         });
598
599         return ret;
600     },
601
602     getState: function(){
603         var state = this.callParent(),
604             sorter = this.store.sorters.first(),
605             headers = this.headerCt.items.items,
606             header,
607             len = headers.length,
608             i = 0;
609
610         state.columns = [];
611         for (; i &lt; len; i++) {
612             header = headers[i];
613             state.columns[i] = {
614                 id: header.headerId
615             };
616
617             // We only store state which has changed from the initial state.
618             // So that current software settings do not override future software settings.
619             // Only user-changed state should be saved.
620             if (header.hidden !== (header.initialConfig.hidden||header.self.prototype.hidden)) {
621                 state.columns[i].hidden = header.hidden;
622             }
623             if (header.sortable !== header.initialConfig.sortable) {
624                 state.columns[i].sortable = header.sortable;
625             }
626             if (header.flex) {
627                 if (header.flex !== header.initialConfig.flex) {
628                     state.columns[i].flex = header.flex;
629                 }
630             } else {
631                 if (header.width !== header.initialConfig.width) {
632                     state.columns[i].width = header.width;
633                 }
634             }
635         }
636
637         if (sorter) {
638             state.sort = {
639                 property: sorter.property,
640                 direction: sorter.direction
641             };
642         }
643         return state;
644     },
645
646     applyState: function(state) {
647         var headers = state.columns,
648             length = headers ? headers.length : 0,
649             headerCt = this.headerCt,
650             items = headerCt.items,
651             sorter = state.sort,
652             store = this.store,
653             i = 0,
654             index,
655             headerState,
656             header;
657
658         headerCt.suspendLayout = true;
659
660         // Ensure superclass has applied *its* state.
661         // AbstractComponent saves dimensions (and anchor/flex) plus collapsed state.
662         this.callParent(arguments);
663
664         for (; i &lt; length; ++i) {
665             headerState = headers[i];
666             header = headerCt.down('gridcolumn[headerId=' + headerState.id + ']');
667             index = items.indexOf(header);
668             if (i !== index) {
669                 headerCt.moveHeader(index, i);
670             }
671
672             // Only state properties which were saved should be restored.
673             // (Only user-changed properties were saved by getState)
674             if (Ext.isDefined(headerState.hidden)) {
675                 header.hidden = headerState.hidden;
676             }
677             if (Ext.isDefined(headerState.sortable)) {
678                 header.sortable = headerState.sortable;
679             }
680             if (Ext.isDefined(headerState.flex)) {
681                 delete header.width;
682                 header.flex = headerState.flex;
683             } else if (Ext.isDefined(headerState.width)) {
684                 delete header.flex;
685                 header.minWidth = headerState.width;
686                 if (header.rendered) {
687                     header.setWidth(headerState.width);
688                 } else {
689                     header.width = headerState.width;
690                 }
691             }
692         }
693         headerCt.suspendLayout = false;
694
695         // After setting width and flexes while layout is suspended, column Container's Container layout needs running.
696         headerCt.doLayout();
697
698         if (sorter) {
699             if (store.remoteSort) {
700                 store.sorters.add(Ext.create('Ext.util.Sorter', {
701                     property: sorter.property,
702                     direction: sorter.direction
703                 }));
704             }
705             else {
706                 store.sort(sorter.property, sorter.direction);
707             }
708         }
709     },
710
711 <span id='Ext-panel-Table-method-getStore'>    /**
712 </span>     * Returns the store associated with this Panel.
713      * @return {Ext.data.Store} The store
714      */
715     getStore: function(){
716         return this.store;
717     },
718
719 <span id='Ext-panel-Table-method-getView'>    /**
720 </span>     * Gets the view for this panel.
721      * @return {Ext.view.Table}
722      */
723     getView: function() {
724         var me = this,
725             sm;
726
727         if (!me.view) {
728             sm = me.getSelectionModel();
729             me.view = me.createComponent(Ext.apply({}, me.viewConfig, {
730                 deferRowRender: me.deferRowRender,
731                 xtype: me.viewType,
732                 store: me.store,
733                 headerCt: me.headerCt,
734                 selModel: sm,
735                 features: me.features,
736                 panel: me
737             }));
738             me.mon(me.view, {
739                 uievent: me.processEvent,
740                 scope: me
741             });
742             sm.view = me.view;
743             me.headerCt.view = me.view;
744             me.relayEvents(me.view, ['cellclick', 'celldblclick']);
745         }
746         return me.view;
747     },
748
749 <span id='Ext-panel-Table-property-setAutoScroll'>    /**
750 </span>     * @private
751      * @override
752      * autoScroll is never valid for all classes which extend TablePanel.
753      */
754     setAutoScroll: Ext.emptyFn,
755
756     // This method hijacks Ext.view.Table's el scroll method.
757     // This enables us to keep the virtualized scrollbars in sync
758     // with the view. It currently does NOT support animation.
759     elScroll: function(direction, distance, animate) {
760         var me = this,
761             scroller;
762
763         if (direction === &quot;up&quot; || direction === &quot;left&quot;) {
764             distance = -distance;
765         }
766
767         if (direction === &quot;down&quot; || direction === &quot;up&quot;) {
768             scroller = me.getVerticalScroller();
769             scroller.scrollByDeltaY(distance);
770         } else {
771             scroller = me.getHorizontalScroller();
772             scroller.scrollByDeltaX(distance);
773         }
774     },
775
776 <span id='Ext-panel-Table-method-injectView'>    /**
777 </span>     * @private
778      * Called after this Component has achieved its correct initial size, after all layouts have done their thing.
779      * This is so we can add the View only after the initial size is known. This method is throttled 30ms.
780      */
781     injectView: function() {
782         if (!this.hasView &amp;&amp; !this.collapsed) {
783             var me   = this,
784                 view = me.getView();
785
786             me.hasView = true;
787             me.add(view);
788
789             function viewReady () {
790                 // hijack the view el's scroll method
791                 view.el.scroll = Ext.Function.bind(me.elScroll, me);
792                 // We use to listen to document.body wheel events, but that's a
793                 // little much. We scope just to the view now.
794                 me.mon(view.el, {
795                     mousewheel: me.onMouseWheel,
796                     scope: me
797                 });
798                 if (!me.height) {
799                     me.doComponentLayout();
800                 }
801             }
802
803             if (view.rendered) {
804                 viewReady();
805             } else {
806                 view.on({
807                     afterrender: viewReady,
808                     single: true
809                 });
810             }
811         }
812     },
813
814     afterExpand: function() {
815         // TODO - this is *not* called when part of an accordion!
816         this.callParent(arguments);
817         if (!this.hasView) {
818             this.injectView();
819         }
820     },
821
822 <span id='Ext-panel-Table-method-processEvent'>    /**
823 </span>     * @private
824      * Process UI events from the view. Propagate them to whatever internal Components need to process them
825      * @param {String} type Event type, eg 'click'
826      * @param {TableView} view TableView Component
827      * @param {HtmlElement} cell Cell HtmlElement the event took place within
828      * @param {Number} recordIndex Index of the associated Store Model (-1 if none)
829      * @param {Number} cellIndex Cell index within the row
830      * @param {EventObject} e Original event
831      */
832     processEvent: function(type, view, cell, recordIndex, cellIndex, e) {
833         var me = this,
834             header;
835
836         if (cellIndex !== -1) {
837             header = me.headerCt.getGridColumns()[cellIndex];
838             return header.processEvent.apply(header, arguments);
839         }
840     },
841
842 <span id='Ext-panel-Table-method-determineScrollbars'>    /**
843 </span>     * Request a recalculation of scrollbars and put them in if they are needed.
844      */
845     determineScrollbars: function() {
846         var me = this,
847             box,
848             tableEl,
849             scrollWidth,
850             clientWidth,
851             scrollHeight,
852             clientHeight,
853             verticalScroller = me.verticalScroller,
854             horizontalScroller = me.horizontalScroller,
855             curScrollbars = (verticalScroller   &amp;&amp; verticalScroller.ownerCt === me ? 1 : 0) |
856                             (horizontalScroller &amp;&amp; horizontalScroller.ownerCt === me ? 2 : 0),
857             reqScrollbars = 0; // 1 = vertical, 2 = horizontal, 3 = both
858
859         // If we are not collapsed, and the view has been rendered AND filled, then we can determine scrollbars
860         if (!me.collapsed &amp;&amp; me.view &amp;&amp; me.view.el &amp;&amp; me.view.el.dom.firstChild) {
861
862             // Calculate maximum, *scrollbarless* space which the view has available.
863             // It will be the Fit Layout's calculated size, plus the widths of any currently shown scrollbars
864             box = me.layout.getLayoutTargetSize();
865             clientWidth  = box.width  + ((curScrollbars &amp; 1) ? verticalScroller.width : 0);
866             clientHeight = box.height + ((curScrollbars &amp; 2) ? horizontalScroller.height : 0);
867
868             // Calculate the width of the scrolling block
869             // There will never be a horizontal scrollbar if all columns are flexed.
870
871             scrollWidth = (me.headerCt.query('[flex]').length &amp;&amp; !me.headerCt.layout.tooNarrow) ? 0 : me.headerCt.getFullWidth();
872
873             // Calculate the height of the scrolling block
874             if (verticalScroller &amp;&amp; verticalScroller.el) {
875                 scrollHeight = verticalScroller.getSizeCalculation().height;
876             } else {
877                 tableEl = me.view.el.child('table', true);
878                 scrollHeight = tableEl ? tableEl.offsetHeight : 0;
879             }
880
881             // View is too high.
882             // Definitely need a vertical scrollbar
883             if (scrollHeight &gt; clientHeight) {
884                 reqScrollbars = 1;
885
886                 // But if scrollable block width goes into the zone required by the vertical scrollbar, we'll also need a horizontal
887                 if (horizontalScroller &amp;&amp; ((clientWidth - scrollWidth) &lt; verticalScroller.width)) {
888                     reqScrollbars = 3;
889                 }
890             }
891
892             // View height fits. But we stil may need a horizontal scrollbar, and this might necessitate a vertical one.
893             else {
894                 // View is too wide.
895                 // Definitely need a horizontal scrollbar
896                 if (scrollWidth &gt; clientWidth) {
897                     reqScrollbars = 2;
898
899                     // But if scrollable block height goes into the zone required by the horizontal scrollbar, we'll also need a vertical
900                     if (verticalScroller &amp;&amp; ((clientHeight - scrollHeight) &lt; horizontalScroller.height)) {
901                         reqScrollbars = 3;
902                     }
903                 }
904             }
905
906             // If scrollbar requirements have changed, change 'em...
907             if (reqScrollbars !== curScrollbars) {
908
909                 // Suspend component layout while we add/remove the docked scrollers
910                 me.suspendLayout = true;
911                 if (reqScrollbars &amp; 1) {
912                     me.showVerticalScroller();
913                 } else {
914                     me.hideVerticalScroller();
915                 }
916                 if (reqScrollbars &amp; 2) {
917                     me.showHorizontalScroller();
918                 } else {
919                     me.hideHorizontalScroller();
920                 }
921                 me.suspendLayout = false;
922
923                 // After docked scrollers are correctly configured, lay out the Component.
924                 // Set a flag so that afterComponentLayout does not recurse back into here.
925                 me.changingScrollBars = true;
926                 me.doComponentLayout(me.getWidth(), me.getHeight(), false, me.ownerCt);
927                 me.changingScrollBars = false;
928             }
929         }
930     },
931
932     afterComponentLayout: function() {
933         var me = this;
934         me.callParent(arguments);
935
936         // Insert the View the first time the Panel has a Component layout performed.
937         me.injectView();
938
939         // Avoid recursion
940         if (!me.changingScrollBars) {
941             me.determineScrollbars();
942         }
943         me.invalidateScroller();
944     },
945
946     onHeaderResize: function() {
947         if (this.view &amp;&amp; this.view.rendered) {
948             this.determineScrollbars();
949             this.invalidateScroller();
950         }
951     },
952
953     afterCollapse: function() {
954         var me = this;
955         if (me.verticalScroller) {
956             me.verticalScroller.saveScrollPos();
957         }
958         if (me.horizontalScroller) {
959             me.horizontalScroller.saveScrollPos();
960         }
961         me.callParent(arguments);
962     },
963
964     afterExpand: function() {
965         var me = this;
966         me.callParent(arguments);
967         if (me.verticalScroller) {
968             me.verticalScroller.restoreScrollPos();
969         }
970         if (me.horizontalScroller) {
971             me.horizontalScroller.restoreScrollPos();
972         }
973     },
974
975 <span id='Ext-panel-Table-method-hideHorizontalScroller'>    /**
976 </span>     * Hide the verticalScroller and remove the horizontalScrollerPresentCls.
977      */
978     hideHorizontalScroller: function() {
979         var me = this;
980
981         if (me.horizontalScroller &amp;&amp; me.horizontalScroller.ownerCt === me) {
982             me.verticalScroller.setReservedSpace(0);
983             me.removeDocked(me.horizontalScroller, false);
984             me.removeCls(me.horizontalScrollerPresentCls);
985             me.fireEvent('scrollerhide', me.horizontalScroller, 'horizontal');
986         }
987
988     },
989
990 <span id='Ext-panel-Table-method-showHorizontalScroller'>    /**
991 </span>     * Show the horizontalScroller and add the horizontalScrollerPresentCls.
992      */
993     showHorizontalScroller: function() {
994         var me = this;
995
996         if (me.verticalScroller) {
997             me.verticalScroller.setReservedSpace(Ext.getScrollbarSize().height - 1);
998         }
999         if (me.horizontalScroller &amp;&amp; me.horizontalScroller.ownerCt !== me) {
1000             me.addDocked(me.horizontalScroller);
1001             me.addCls(me.horizontalScrollerPresentCls);
1002             me.fireEvent('scrollershow', me.horizontalScroller, 'horizontal');
1003         }
1004     },
1005
1006 <span id='Ext-panel-Table-method-hideVerticalScroller'>    /**
1007 </span>     * Hide the verticalScroller and remove the verticalScrollerPresentCls.
1008      */
1009     hideVerticalScroller: function() {
1010         var me = this;
1011
1012         me.setHeaderReserveOffset(false);
1013         if (me.verticalScroller &amp;&amp; me.verticalScroller.ownerCt === me) {
1014             me.removeDocked(me.verticalScroller, false);
1015             me.removeCls(me.verticalScrollerPresentCls);
1016             me.fireEvent('scrollerhide', me.verticalScroller, 'vertical');
1017         }
1018     },
1019
1020 <span id='Ext-panel-Table-method-showVerticalScroller'>    /**
1021 </span>     * Show the verticalScroller and add the verticalScrollerPresentCls.
1022      */
1023     showVerticalScroller: function() {
1024         var me = this;
1025
1026         me.setHeaderReserveOffset(true);
1027         if (me.verticalScroller &amp;&amp; me.verticalScroller.ownerCt !== me) {
1028             me.addDocked(me.verticalScroller);
1029             me.addCls(me.verticalScrollerPresentCls);
1030             me.fireEvent('scrollershow', me.verticalScroller, 'vertical');
1031         }
1032     },
1033
1034     setHeaderReserveOffset: function (reserveOffset) {
1035         var headerCt = this.headerCt,
1036             layout = headerCt.layout;
1037
1038         // only trigger a layout when reserveOffset is changing
1039         if (layout &amp;&amp; layout.reserveOffset !== reserveOffset) {
1040             layout.reserveOffset = reserveOffset;
1041             headerCt.doLayout();
1042         }
1043     },
1044
1045 <span id='Ext-panel-Table-method-invalidateScroller'>    /**
1046 </span>     * Invalides scrollers that are present and forces a recalculation.
1047      * (Not related to showing/hiding the scrollers)
1048      */
1049     invalidateScroller: function() {
1050         var me = this,
1051             vScroll = me.verticalScroller,
1052             hScroll = me.horizontalScroller;
1053
1054         if (vScroll) {
1055             vScroll.invalidate();
1056         }
1057         if (hScroll) {
1058             hScroll.invalidate();
1059         }
1060     },
1061
1062     // refresh the view when a header moves
1063     onHeaderMove: function(headerCt, header, fromIdx, toIdx) {
1064         this.view.refresh();
1065     },
1066
1067     // Section onHeaderHide is invoked after view.
1068     onHeaderHide: function(headerCt, header) {
1069         this.invalidateScroller();
1070     },
1071
1072     onHeaderShow: function(headerCt, header) {
1073         this.invalidateScroller();
1074     },
1075
1076     getVerticalScroller: function() {
1077         return this.getScrollerOwner().down('gridscroller[dock=' + this.verticalScrollDock + ']');
1078     },
1079
1080     getHorizontalScroller: function() {
1081         return this.getScrollerOwner().down('gridscroller[dock=bottom]');
1082     },
1083
1084     onMouseWheel: function(e) {
1085         var me = this,
1086             vertScroller = me.getVerticalScroller(),
1087             horizScroller = me.getHorizontalScroller(),
1088             scrollDelta = me.scrollDelta / -5,
1089             deltas = e.getWheelDeltas(),
1090             deltaX = scrollDelta * deltas.x,
1091             deltaY = scrollDelta * deltas.y,
1092             vertScrollerEl, horizScrollerEl,
1093             vertScrollerElDom, horizScrollerElDom,
1094             horizontalCanScrollLeft, horizontalCanScrollRight,
1095             verticalCanScrollDown, verticalCanScrollUp;
1096
1097         // calculate whether or not both scrollbars can scroll right/left and up/down
1098         if (horizScroller) {
1099             horizScrollerEl = horizScroller.scrollEl;
1100             if (horizScrollerEl) {
1101                 horizScrollerElDom = horizScrollerEl.dom;
1102                 horizontalCanScrollRight = horizScrollerElDom.scrollLeft !== horizScrollerElDom.scrollWidth - horizScrollerElDom.clientWidth;
1103                 horizontalCanScrollLeft  = horizScrollerElDom.scrollLeft !== 0;
1104             }
1105         }
1106         if (vertScroller) {
1107             vertScrollerEl = vertScroller.scrollEl;
1108             if (vertScrollerEl) {
1109                 vertScrollerElDom = vertScrollerEl.dom;
1110                 verticalCanScrollDown = vertScrollerElDom.scrollTop !== vertScrollerElDom.scrollHeight - vertScrollerElDom.clientHeight;
1111                 verticalCanScrollUp   = vertScrollerElDom.scrollTop !== 0;
1112             }
1113         }
1114
1115         if (horizScroller) {
1116             if ((deltaX &lt; 0 &amp;&amp; horizontalCanScrollLeft) || (deltaX &gt; 0 &amp;&amp; horizontalCanScrollRight)) {
1117                 e.stopEvent();
1118                 horizScroller.scrollByDeltaX(deltaX);
1119             }
1120         }
1121         if (vertScroller) {
1122             if ((deltaY &lt; 0 &amp;&amp; verticalCanScrollUp) || (deltaY &gt; 0 &amp;&amp; verticalCanScrollDown)) {
1123                 e.stopEvent();
1124                 vertScroller.scrollByDeltaY(deltaY);
1125             }
1126         }
1127     },
1128
1129 <span id='Ext-panel-Table-method-onViewRefresh'>    /**
1130 </span>     * @private
1131      * Determine and invalidate scrollers on view refresh
1132      */
1133     onViewRefresh: function() {
1134         this.determineScrollbars();
1135         if (this.invalidateScrollerOnRefresh) {
1136             this.invalidateScroller();
1137         }
1138     },
1139
1140 <span id='Ext-panel-Table-method-setScrollTop'>    /**
1141 </span>     * Sets the scrollTop of the TablePanel.
1142      * @param {Number} deltaY
1143      */
1144     setScrollTop: function(top) {
1145         var me               = this,
1146             rootCmp          = me.getScrollerOwner(),
1147             verticalScroller = me.getVerticalScroller();
1148
1149         rootCmp.virtualScrollTop = top;
1150         if (verticalScroller) {
1151             verticalScroller.setScrollTop(top);
1152         }
1153     },
1154
1155     getScrollerOwner: function() {
1156         var rootCmp = this;
1157         if (!this.scrollerOwner) {
1158             rootCmp = this.up('[scrollerOwner]');
1159         }
1160         return rootCmp;
1161     },
1162
1163 <span id='Ext-panel-Table-method-scrollByDeltaY'>    /**
1164 </span>     * Scrolls the TablePanel by deltaY
1165      * @param {Number} deltaY
1166      */
1167     scrollByDeltaY: function(deltaY) {
1168         var verticalScroller = this.getVerticalScroller();
1169
1170         if (verticalScroller) {
1171             verticalScroller.scrollByDeltaY(deltaY);
1172         }
1173     },
1174
1175 <span id='Ext-panel-Table-method-scrollByDeltaX'>    /**
1176 </span>     * Scrolls the TablePanel by deltaX
1177      * @param {Number} deltaY
1178      */
1179     scrollByDeltaX: function(deltaX) {
1180         var horizontalScroller = this.getVerticalScroller();
1181
1182         if (horizontalScroller) {
1183             horizontalScroller.scrollByDeltaX(deltaX);
1184         }
1185     },
1186
1187 <span id='Ext-panel-Table-method-getLhsMarker'>    /**
1188 </span>     * Get left hand side marker for header resizing.
1189      * @private
1190      */
1191     getLhsMarker: function() {
1192         var me = this;
1193
1194         if (!me.lhsMarker) {
1195             me.lhsMarker = Ext.core.DomHelper.append(me.el, {
1196                 cls: Ext.baseCSSPrefix + 'grid-resize-marker'
1197             }, true);
1198         }
1199         return me.lhsMarker;
1200     },
1201
1202 <span id='Ext-panel-Table-method-getRhsMarker'>    /**
1203 </span>     * Get right hand side marker for header resizing.
1204      * @private
1205      */
1206     getRhsMarker: function() {
1207         var me = this;
1208
1209         if (!me.rhsMarker) {
1210             me.rhsMarker = Ext.core.DomHelper.append(me.el, {
1211                 cls: Ext.baseCSSPrefix + 'grid-resize-marker'
1212             }, true);
1213         }
1214         return me.rhsMarker;
1215     },
1216
1217 <span id='Ext-panel-Table-method-getSelectionModel'>    /**
1218 </span>     * Returns the selection model being used and creates it via the configuration
1219      * if it has not been created already.
1220      * @return {Ext.selection.Model} selModel
1221      */
1222     getSelectionModel: function(){
1223         if (!this.selModel) {
1224             this.selModel = {};
1225         }
1226
1227         var mode = 'SINGLE',
1228             type;
1229         if (this.simpleSelect) {
1230             mode = 'SIMPLE';
1231         } else if (this.multiSelect) {
1232             mode = 'MULTI';
1233         }
1234
1235         Ext.applyIf(this.selModel, {
1236             allowDeselect: this.allowDeselect,
1237             mode: mode
1238         });
1239
1240         if (!this.selModel.events) {
1241             type = this.selModel.selType || this.selType;
1242             this.selModel = Ext.create('selection.' + type, this.selModel);
1243         }
1244
1245         if (!this.selModel.hasRelaySetup) {
1246             this.relayEvents(this.selModel, [
1247                 'selectionchange', 'beforeselect', 'beforedeselect', 'select', 'deselect'
1248             ]);
1249             this.selModel.hasRelaySetup = true;
1250         }
1251
1252         // lock the selection model if user
1253         // has disabled selection
1254         if (this.disableSelection) {
1255             this.selModel.locked = true;
1256         }
1257         return this.selModel;
1258     },
1259
1260     onVerticalScroll: function(event, target) {
1261         var owner = this.getScrollerOwner(),
1262             items = owner.query('tableview'),
1263             i = 0,
1264             len = items.length;
1265
1266         for (; i &lt; len; i++) {
1267             items[i].el.dom.scrollTop = target.scrollTop;
1268         }
1269     },
1270
1271     onHorizontalScroll: function(event, target) {
1272         var owner = this.getScrollerOwner(),
1273             items = owner.query('tableview'),
1274             center = items[1] || items[0];
1275
1276         center.el.dom.scrollLeft = target.scrollLeft;
1277         this.headerCt.el.dom.scrollLeft = target.scrollLeft;
1278     },
1279
1280     // template method meant to be overriden
1281     onStoreLoad: Ext.emptyFn,
1282
1283     getEditorParent: function() {
1284         return this.body;
1285     },
1286
1287     bindStore: function(store) {
1288         var me = this;
1289         me.store = store;
1290         me.getView().bindStore(store);
1291     },
1292
1293 <span id='Ext-panel-Table-method-reconfigure'>    /**
1294 </span>     * Reconfigure the table with a new store/column.
1295      * Either the store or the column can be ommitted if you don't wish to change them.
1296      * @param {Ext.data.Store} store The new store.
1297      * @param {Array} columns An array of column configs
1298      */
1299     reconfigure: function(store, columns) {
1300         var me = this,
1301             headerCt = me.headerCt;
1302
1303         if (me.lockable) {
1304             me.reconfigureLockable(store, columns);
1305         } else {
1306             headerCt.suspendLayout = true;
1307             headerCt.removeAll();
1308             if (columns) {
1309                 headerCt.add(columns);
1310             } else {
1311                 headerCt.doLayout();
1312             }
1313             if (store) {
1314                 store = Ext.StoreManager.lookup(store);
1315                 me.bindStore(store);
1316             } else {
1317                 me.getView().refresh();
1318             }
1319             if (columns) {
1320                 me.forceComponentLayout();
1321             }
1322         }
1323         me.fireEvent('reconfigure', me);
1324     }
1325 });</pre>
1326 </body>
1327 </html>