1 <!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-panel.Table'>/**
2 </span> * @class Ext.panel.Table
3 * @extends Ext.panel.Panel
6 * @author Nicolas Ferrero
7 * TablePanel is a private class and the basis of both TreePanel and GridPanel.
9 * TablePanel aggregates:
15 * - Ext.grid.header.Container
18 Ext.define('Ext.panel.Table', {
19 extend: 'Ext.panel.Panel',
21 alias: 'widget.tablepanel',
24 'Ext.selection.RowModel',
26 'Ext.grid.header.Container',
30 cls: Ext.baseCSSPrefix + 'grid',
31 extraBodyCls: Ext.baseCSSPrefix + 'grid-body',
34 <span id='Ext-panel.Table-property-hasView'> /**
35 </span> * Boolean to indicate that a view has been injected into the panel.
40 // each panel should dictate what viewType and selType to use
44 <span id='Ext-panel.Table-cfg-scrollDelta'> /**
45 </span> * @cfg {Number} scrollDelta
46 * Number of pixels to scroll when scrolling with mousewheel.
51 <span id='Ext-panel.Table-cfg-scroll'> /**
52 </span> * @cfg {String/Boolean} scroll
53 * Valid values are 'both', 'horizontal' or 'vertical'. true implies 'both'. false implies 'none'.
58 <span id='Ext-panel.Table-cfg-columns'> /**
59 </span> * @cfg {Array} columns
60 * An array of {@link Ext.grid.column.Column column} definition objects which define all columns that appear in this grid. Each
61 * column definition provides the header text for the column, and a definition of where the data for that column comes from.
64 <span id='Ext-panel.Table-cfg-forceFit'> /**
65 </span> * @cfg {Boolean} forceFit
66 * Specify as <code>true</code> to force the columns to fit into the available width. Headers are first sized according to configuration, whether that be
67 * a specific width, or flex. Then they are all proportionally changed in width so that the entire content width is used..
70 <span id='Ext-panel.Table-cfg-hideHeaders'> /**
71 </span> * @cfg {Boolean} hideHeaders
72 * Specify as <code>true</code> to hide the headers.
75 <span id='Ext-panel.Table-cfg-sortableColumns'> /**
76 </span> * @cfg {Boolean} sortableColumns
77 * Defaults to true. Set to false to disable column sorting via clicking the
78 * header and via the Sorting menu items.
80 sortableColumns: true,
82 verticalScrollDock: 'right',
83 verticalScrollerType: 'gridscroller',
85 horizontalScrollerPresentCls: Ext.baseCSSPrefix + 'horizontal-scroller-present',
86 verticalScrollerPresentCls: Ext.baseCSSPrefix + 'vertical-scroller-present',
88 // private property used to determine where to go down to find views
89 // this is here to support locking.
92 invalidateScrollerOnRefresh: true,
94 enableColumnMove: true,
95 enableColumnResize: true,
98 initComponent: function() {
100 if (!this.viewType) {
101 Ext.Error.raise("You must specify a viewType config.");
104 Ext.Error.raise("You must specify a store config");
107 Ext.Error.raise("The headers config is not supported. Please specify columns instead.");
115 headerCtCfg = me.columns || me.colModel,
120 // Set our determinScrollbars method to reference a buffered call to determinScrollbars which fires on a 30ms buffer.
121 me.determineScrollbars = Ext.Function.createBuffered(me.determineScrollbars, 30);
122 me.injectView = Ext.Function.createBuffered(me.injectView, 30);
124 if (me.hideHeaders) {
128 // The columns/colModel config may be either a fully instantiated HeaderContainer, or an array of Column definitions, or a config object of a HeaderContainer
129 // Either way, we extract a columns property referencing an array of Column definitions.
130 if (headerCtCfg instanceof Ext.grid.header.Container) {
131 me.headerCt = headerCtCfg;
132 me.headerCt.border = border;
133 me.columns = me.headerCt.items.items;
135 if (Ext.isArray(headerCtCfg)) {
141 Ext.apply(headerCtCfg, {
142 forceFit: me.forceFit,
143 sortable: me.sortableColumns,
144 enableColumnMove: me.enableColumnMove,
145 enableColumnResize: me.enableColumnResize,
148 me.columns = headerCtCfg.items;
150 // If any of the Column objects contain a locked property, and are not processed, this is a lockable TablePanel, a
151 // special view will be injected by the Ext.grid.Lockable mixin, so no processing of .
152 if (Ext.ComponentQuery.query('{locked !== undefined}{processed != true}', me.columns).length) {
153 me.self.mixin('lockable', Ext.grid.Lockable);
158 me.store = Ext.data.StoreManager.lookup(me.store);
160 <span id='Ext-panel.Table-event-scrollerhide'> /**
161 </span> * @event scrollerhide
162 * Fires when a scroller is hidden
163 * @param {Ext.grid.Scroller} scroller
164 * @param {String} orientation Orientation, can be 'vertical' or 'horizontal'
167 <span id='Ext-panel.Table-event-scrollershow'> /**
168 </span> * @event scrollershow
169 * Fires when a scroller is shown
170 * @param {Ext.grid.Scroller} scroller
171 * @param {String} orientation Orientation, can be 'vertical' or 'horizontal'
176 me.bodyCls = me.bodyCls || '';
177 me.bodyCls += (' ' + me.extraBodyCls);
179 // autoScroll is not a valid configuration
180 delete me.autoScroll;
182 // If this TablePanel is lockable (Either configured lockable, or any of the defined columns has a 'locked' property)
183 // 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.
186 // If we were not configured with a ready-made headerCt (either by direct config with a headerCt property, or by passing
187 // a HeaderContainer instance as the 'columns' property, then go ahead and create one from the config object created above.
189 me.headerCt = Ext.create('Ext.grid.header.Container', headerCtCfg);
192 // Extract the array of Column objects
193 me.columns = me.headerCt.items.items;
195 if (me.hideHeaders) {
196 me.headerCt.height = 0;
197 me.headerCt.border = false;
198 me.headerCt.addCls(Ext.baseCSSPrefix + 'grid-header-ct-hidden');
199 me.addCls(Ext.baseCSSPrefix + 'grid-header-hidden');
200 // IE Quirks Mode fix
201 // If hidden configuration option was used, several layout calculations will be bypassed.
202 if (Ext.isIEQuirks) {
203 me.headerCt.style = {
210 if (scroll === true || scroll === 'both') {
211 vertical = horizontal = true;
212 } else if (scroll === 'horizontal') {
214 } else if (scroll === 'vertical') {
216 // All other values become 'none' or false.
218 me.headerCt.availableSpaceOffset = 0;
222 me.verticalScroller = me.verticalScroller || {};
223 Ext.applyIf(me.verticalScroller, {
224 dock: me.verticalScrollDock,
225 xtype: me.verticalScrollerType,
228 me.verticalScroller = Ext.ComponentManager.create(me.verticalScroller);
229 me.mon(me.verticalScroller, {
230 bodyscroll: me.onVerticalScroll,
236 me.horizontalScroller = Ext.ComponentManager.create({
237 xtype: 'gridscroller',
242 me.mon(me.horizontalScroller, {
243 bodyscroll: me.onHorizontalScroll,
248 me.headerCt.on('columnresize', me.onHeaderResize, me);
249 me.relayEvents(me.headerCt, ['columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange']);
250 me.features = me.features || [];
251 me.dockedItems = me.dockedItems || [];
252 me.dockedItems.unshift(me.headerCt);
253 me.viewConfig = me.viewConfig || {};
254 me.viewConfig.invalidateScrollerOnRefresh = me.invalidateScrollerOnRefresh;
256 // AbstractDataView will look up a Store configured as an object
257 // getView converts viewConfig into a View instance
262 load: me.onStoreLoad,
267 fn: this.onViewRefresh,
271 itemupdate: me.onViewItemUpdate,
274 this.relayEvents(view, [
275 <span id='Ext-panel.Table-event-beforeitemmousedown'> /**
276 </span> * @event beforeitemmousedown
277 * Fires before the mousedown event on an item is processed. Returns false to cancel the default action.
278 * @param {Ext.view.View} this
279 * @param {Ext.data.Model} record The record that belongs to the item
280 * @param {HTMLElement} item The item's element
281 * @param {Number} index The item's index
282 * @param {Ext.EventObject} e The raw event object
284 'beforeitemmousedown',
285 <span id='Ext-panel.Table-event-beforeitemmouseup'> /**
286 </span> * @event beforeitemmouseup
287 * Fires before the mouseup event on an item is processed. Returns false to cancel the default action.
288 * @param {Ext.view.View} this
289 * @param {Ext.data.Model} record The record that belongs to the item
290 * @param {HTMLElement} item The item's element
291 * @param {Number} index The item's index
292 * @param {Ext.EventObject} e The raw event object
295 <span id='Ext-panel.Table-event-beforeitemmouseenter'> /**
296 </span> * @event beforeitemmouseenter
297 * Fires before the mouseenter event on an item is processed. Returns false to cancel the default action.
298 * @param {Ext.view.View} this
299 * @param {Ext.data.Model} record The record that belongs to the item
300 * @param {HTMLElement} item The item's element
301 * @param {Number} index The item's index
302 * @param {Ext.EventObject} e The raw event object
304 'beforeitemmouseenter',
305 <span id='Ext-panel.Table-event-beforeitemmouseleave'> /**
306 </span> * @event beforeitemmouseleave
307 * Fires before the mouseleave event on an item is processed. Returns false to cancel the default action.
308 * @param {Ext.view.View} this
309 * @param {Ext.data.Model} record The record that belongs to the item
310 * @param {HTMLElement} item The item's element
311 * @param {Number} index The item's index
312 * @param {Ext.EventObject} e The raw event object
314 'beforeitemmouseleave',
315 <span id='Ext-panel.Table-event-beforeitemclick'> /**
316 </span> * @event beforeitemclick
317 * Fires before the click event on an item is processed. Returns false to cancel the default action.
318 * @param {Ext.view.View} this
319 * @param {Ext.data.Model} record The record that belongs to the item
320 * @param {HTMLElement} item The item's element
321 * @param {Number} index The item's index
322 * @param {Ext.EventObject} e The raw event object
325 <span id='Ext-panel.Table-event-beforeitemdblclick'> /**
326 </span> * @event beforeitemdblclick
327 * Fires before the dblclick event on an item is processed. Returns false to cancel the default action.
328 * @param {Ext.view.View} this
329 * @param {Ext.data.Model} record The record that belongs to the item
330 * @param {HTMLElement} item The item's element
331 * @param {Number} index The item's index
332 * @param {Ext.EventObject} e The raw event object
334 'beforeitemdblclick',
335 <span id='Ext-panel.Table-event-beforeitemcontextmenu'> /**
336 </span> * @event beforeitemcontextmenu
337 * Fires before the contextmenu event on an item is processed. Returns false to cancel the default action.
338 * @param {Ext.view.View} this
339 * @param {Ext.data.Model} record The record that belongs to the item
340 * @param {HTMLElement} item The item's element
341 * @param {Number} index The item's index
342 * @param {Ext.EventObject} e The raw event object
344 'beforeitemcontextmenu',
345 <span id='Ext-panel.Table-event-itemmousedown'> /**
346 </span> * @event itemmousedown
347 * Fires when there is a mouse down on an item
348 * @param {Ext.view.View} this
349 * @param {Ext.data.Model} record The record that belongs to the item
350 * @param {HTMLElement} item The item's element
351 * @param {Number} index The item's index
352 * @param {Ext.EventObject} e The raw event object
355 <span id='Ext-panel.Table-event-itemmouseup'> /**
356 </span> * @event itemmouseup
357 * Fires when there is a mouse up on an item
358 * @param {Ext.view.View} this
359 * @param {Ext.data.Model} record The record that belongs to the item
360 * @param {HTMLElement} item The item's element
361 * @param {Number} index The item's index
362 * @param {Ext.EventObject} e The raw event object
365 <span id='Ext-panel.Table-event-itemmouseenter'> /**
366 </span> * @event itemmouseenter
367 * Fires when the mouse enters an item.
368 * @param {Ext.view.View} this
369 * @param {Ext.data.Model} record The record that belongs to the item
370 * @param {HTMLElement} item The item's element
371 * @param {Number} index The item's index
372 * @param {Ext.EventObject} e The raw event object
375 <span id='Ext-panel.Table-event-itemmouseleave'> /**
376 </span> * @event itemmouseleave
377 * Fires when the mouse leaves an item.
378 * @param {Ext.view.View} this
379 * @param {Ext.data.Model} record The record that belongs to the item
380 * @param {HTMLElement} item The item's element
381 * @param {Number} index The item's index
382 * @param {Ext.EventObject} e The raw event object
385 <span id='Ext-panel.Table-event-itemclick'> /**
386 </span> * @event itemclick
387 * Fires when an item is clicked.
388 * @param {Ext.view.View} this
389 * @param {Ext.data.Model} record The record that belongs to the item
390 * @param {HTMLElement} item The item's element
391 * @param {Number} index The item's index
392 * @param {Ext.EventObject} e The raw event object
395 <span id='Ext-panel.Table-event-itemdblclick'> /**
396 </span> * @event itemdblclick
397 * Fires when an item is double clicked.
398 * @param {Ext.view.View} this
399 * @param {Ext.data.Model} record The record that belongs to the item
400 * @param {HTMLElement} item The item's element
401 * @param {Number} index The item's index
402 * @param {Ext.EventObject} e The raw event object
405 <span id='Ext-panel.Table-event-itemcontextmenu'> /**
406 </span> * @event itemcontextmenu
407 * Fires when an item is right clicked.
408 * @param {Ext.view.View} this
409 * @param {Ext.data.Model} record The record that belongs to the item
410 * @param {HTMLElement} item The item's element
411 * @param {Number} index The item's index
412 * @param {Ext.EventObject} e The raw event object
415 <span id='Ext-panel.Table-event-beforecontainermousedown'> /**
416 </span> * @event beforecontainermousedown
417 * Fires before the mousedown event on the container is processed. Returns false to cancel the default action.
418 * @param {Ext.view.View} this
419 * @param {Ext.EventObject} e The raw event object
421 'beforecontainermousedown',
422 <span id='Ext-panel.Table-event-beforecontainermouseup'> /**
423 </span> * @event beforecontainermouseup
424 * Fires before the mouseup event on the container is processed. Returns false to cancel the default action.
425 * @param {Ext.view.View} this
426 * @param {Ext.EventObject} e The raw event object
428 'beforecontainermouseup',
429 <span id='Ext-panel.Table-event-beforecontainermouseover'> /**
430 </span> * @event beforecontainermouseover
431 * Fires before the mouseover event on the container is processed. Returns false to cancel the default action.
432 * @param {Ext.view.View} this
433 * @param {Ext.EventObject} e The raw event object
435 'beforecontainermouseover',
436 <span id='Ext-panel.Table-event-beforecontainermouseout'> /**
437 </span> * @event beforecontainermouseout
438 * Fires before the mouseout event on the container is processed. Returns false to cancel the default action.
439 * @param {Ext.view.View} this
440 * @param {Ext.EventObject} e The raw event object
442 'beforecontainermouseout',
443 <span id='Ext-panel.Table-event-beforecontainerclick'> /**
444 </span> * @event beforecontainerclick
445 * Fires before the click event on the container is processed. Returns false to cancel the default action.
446 * @param {Ext.view.View} this
447 * @param {Ext.EventObject} e The raw event object
449 'beforecontainerclick',
450 <span id='Ext-panel.Table-event-beforecontainerdblclick'> /**
451 </span> * @event beforecontainerdblclick
452 * Fires before the dblclick event on the container is processed. Returns false to cancel the default action.
453 * @param {Ext.view.View} this
454 * @param {Ext.EventObject} e The raw event object
456 'beforecontainerdblclick',
457 <span id='Ext-panel.Table-event-beforecontainercontextmenu'> /**
458 </span> * @event beforecontainercontextmenu
459 * Fires before the contextmenu event on the container is processed. Returns false to cancel the default action.
460 * @param {Ext.view.View} this
461 * @param {Ext.EventObject} e The raw event object
463 'beforecontainercontextmenu',
464 <span id='Ext-panel.Table-event-containermouseup'> /**
465 </span> * @event containermouseup
466 * Fires when there is a mouse up on the container
467 * @param {Ext.view.View} this
468 * @param {Ext.EventObject} e The raw event object
471 <span id='Ext-panel.Table-event-containermouseover'> /**
472 </span> * @event containermouseover
473 * Fires when you move the mouse over the container.
474 * @param {Ext.view.View} this
475 * @param {Ext.EventObject} e The raw event object
477 'containermouseover',
478 <span id='Ext-panel.Table-event-containermouseout'> /**
479 </span> * @event containermouseout
480 * Fires when you move the mouse out of the container.
481 * @param {Ext.view.View} this
482 * @param {Ext.EventObject} e The raw event object
485 <span id='Ext-panel.Table-event-containerclick'> /**
486 </span> * @event containerclick
487 * Fires when the container is clicked.
488 * @param {Ext.view.View} this
489 * @param {Ext.EventObject} e The raw event object
492 <span id='Ext-panel.Table-event-containerdblclick'> /**
493 </span> * @event containerdblclick
494 * Fires when the container is double clicked.
495 * @param {Ext.view.View} this
496 * @param {Ext.EventObject} e The raw event object
499 <span id='Ext-panel.Table-event-containercontextmenu'> /**
500 </span> * @event containercontextmenu
501 * Fires when the container is right clicked.
502 * @param {Ext.view.View} this
503 * @param {Ext.EventObject} e The raw event object
505 'containercontextmenu',
507 <span id='Ext-panel.Table-event-selectionchange'> /**
508 </span> * @event selectionchange
509 * Fires when the selected nodes change. Relayed event from the underlying selection model.
510 * @param {Ext.view.View} this
511 * @param {Array} selections Array of the selected nodes
514 <span id='Ext-panel.Table-event-beforeselect'> /**
515 </span> * @event beforeselect
516 * Fires before a selection is made. If any handlers return false, the selection is cancelled.
517 * @param {Ext.view.View} this
518 * @param {HTMLElement} node The node to be selected
519 * @param {Array} selections Array of currently selected nodes
525 me.callParent(arguments);
529 initStateEvents: function(){
530 var events = this.stateEvents;
531 // push on stateEvents if they don't exist
532 Ext.each(['columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange'], function(event){
533 if (Ext.Array.indexOf(events, event)) {
540 getState: function(){
544 sorter = this.store.sorters.first();
546 this.headerCt.items.each(function(header){
549 width: header.flex ? undefined : header.width,
550 hidden: header.hidden,
551 sortable: header.sortable
557 property: sorter.property,
558 direction: sorter.direction
564 applyState: function(state) {
565 var headers = state.columns,
566 length = headers ? headers.length : 0,
567 headerCt = this.headerCt,
568 items = headerCt.items,
576 for (; i < length; ++i) {
577 headerState = headers[i];
578 header = headerCt.down('gridcolumn[headerId=' + headerState.id + ']');
579 index = items.indexOf(header);
581 headerCt.moveHeader(index, i);
583 header.sortable = headerState.sortable;
584 if (Ext.isDefined(headerState.width)) {
586 if (header.rendered) {
587 header.setWidth(headerState.width);
589 header.minWidth = header.width = headerState.width;
592 header.hidden = headerState.hidden;
596 if (store.remoteSort) {
597 store.sorters.add(Ext.create('Ext.util.Sorter', {
598 property: sorter.property,
599 direction: sorter.direction
603 store.sort(sorter.property, sorter.direction);
608 <span id='Ext-panel.Table-method-getStore'> /**
609 </span> * Returns the store associated with this Panel.
610 * @return {Ext.data.Store} The store
612 getStore: function(){
616 <span id='Ext-panel.Table-method-getView'> /**
617 </span> * Gets the view for this panel.
618 * @return {Ext.view.Table}
620 getView: function() {
625 sm = me.getSelectionModel();
626 me.view = me.createComponent(Ext.apply({}, me.viewConfig, {
629 headerCt: me.headerCt,
631 features: me.features,
635 uievent: me.processEvent,
639 me.headerCt.view = me.view;
640 me.relayEvents(me.view, ['cellclick', 'celldblclick']);
645 <span id='Ext-panel.Table-property-setAutoScroll'> /**
648 * autoScroll is never valid for all classes which extend TablePanel.
650 setAutoScroll: Ext.emptyFn,
652 // This method hijacks Ext.view.Table's el scroll method.
653 // This enables us to keep the virtualized scrollbars in sync
654 // with the view. It currently does NOT support animation.
655 elScroll: function(direction, distance, animate) {
659 if (direction === "up" || direction === "left") {
660 distance = -distance;
663 if (direction === "down" || direction === "up") {
664 scroller = me.getVerticalScroller();
665 scroller.scrollByDeltaY(distance);
667 scroller = me.getHorizontalScroller();
668 scroller.scrollByDeltaX(distance);
672 afterLayout: function() {
673 this.callParent(arguments);
678 <span id='Ext-panel.Table-method-injectView'> /**
680 * Called after this Component has achieved its correct initial size, after all layouts have done their thing.
681 * This is so we can add the View only after the initial size is known. This method is buffered 30ms.
683 injectView: function() {
684 if (!this.hasView && !this.collapsed) {
691 // hijack the view el's scroll method
692 view.el.scroll = Ext.Function.bind(me.elScroll, me);
693 // We use to listen to document.body wheel events, but that's a
694 // little much. We scope just to the view now.
696 mousewheel: me.onMouseWheel,
702 afterExpand: function() {
703 this.callParent(arguments);
709 <span id='Ext-panel.Table-method-processEvent'> /**
711 * Process UI events from the view. Propagate them to whatever internal Components need to process them
712 * @param {String} type Event type, eg 'click'
713 * @param {TableView} view TableView Component
714 * @param {HtmlElement} cell Cell HtmlElement the event took place within
715 * @param {Number} recordIndex Index of the associated Store Model (-1 if none)
716 * @param {Number} cellIndex Cell index within the row
717 * @param {EventObject} e Original event
719 processEvent: function(type, view, cell, recordIndex, cellIndex, e) {
723 if (cellIndex !== -1) {
724 header = me.headerCt.getGridColumns()[cellIndex];
725 return header.processEvent.apply(header, arguments);
729 <span id='Ext-panel.Table-method-determineScrollbars'> /**
730 </span> * Request a recalculation of scrollbars and put them in if they are needed.
732 determineScrollbars: function() {
740 if (!me.collapsed && me.view && me.view.el) {
741 viewElDom = me.view.el.dom;
742 //centerScrollWidth = viewElDom.scrollWidth;
743 centerScrollWidth = me.headerCt.getFullWidth();
744 <span id='Ext-panel.Table-property-centerClientWidth'> /**
745 </span> * clientWidth often returns 0 in IE resulting in an
746 * infinity result, here we use offsetWidth bc there are
747 * no possible scrollbars and we don't care about margins
749 centerClientWidth = viewElDom.offsetWidth;
750 if (me.verticalScroller && me.verticalScroller.el) {
751 scrollHeight = me.verticalScroller.getSizeCalculation().height;
753 scrollHeight = viewElDom.scrollHeight;
756 clientHeight = viewElDom.clientHeight;
758 if (!me.collapsed && scrollHeight > clientHeight) {
759 me.showVerticalScroller();
761 me.hideVerticalScroller();
764 if (!me.collapsed && centerScrollWidth > (centerClientWidth + Ext.getScrollBarWidth() - 2)) {
765 me.showHorizontalScroller();
767 me.hideHorizontalScroller();
772 onHeaderResize: function() {
773 if (this.view && this.view.rendered) {
774 this.determineScrollbars();
775 this.invalidateScroller();
779 <span id='Ext-panel.Table-method-hideHorizontalScroller'> /**
780 </span> * Hide the verticalScroller and remove the horizontalScrollerPresentCls.
782 hideHorizontalScroller: function() {
785 if (me.horizontalScroller && me.horizontalScroller.ownerCt === me) {
786 me.verticalScroller.offsets.bottom = 0;
787 me.removeDocked(me.horizontalScroller, false);
788 me.removeCls(me.horizontalScrollerPresentCls);
789 me.fireEvent('scrollerhide', me.horizontalScroller, 'horizontal');
794 <span id='Ext-panel.Table-method-showHorizontalScroller'> /**
795 </span> * Show the horizontalScroller and add the horizontalScrollerPresentCls.
797 showHorizontalScroller: function() {
800 if (me.verticalScroller) {
801 me.verticalScroller.offsets.bottom = Ext.getScrollBarWidth() - 2;
803 if (me.horizontalScroller && me.horizontalScroller.ownerCt !== me) {
804 me.addDocked(me.horizontalScroller);
805 me.addCls(me.horizontalScrollerPresentCls);
806 me.fireEvent('scrollershow', me.horizontalScroller, 'horizontal');
810 <span id='Ext-panel.Table-method-hideVerticalScroller'> /**
811 </span> * Hide the verticalScroller and remove the verticalScrollerPresentCls.
813 hideVerticalScroller: function() {
815 headerCt = me.headerCt;
817 // only trigger a layout when reserveOffset is changing
818 if (headerCt && headerCt.layout.reserveOffset) {
819 headerCt.layout.reserveOffset = false;
822 if (me.verticalScroller && me.verticalScroller.ownerCt === me) {
823 me.removeDocked(me.verticalScroller, false);
824 me.removeCls(me.verticalScrollerPresentCls);
825 me.fireEvent('scrollerhide', me.verticalScroller, 'vertical');
829 <span id='Ext-panel.Table-method-showVerticalScroller'> /**
830 </span> * Show the verticalScroller and add the verticalScrollerPresentCls.
832 showVerticalScroller: function() {
834 headerCt = me.headerCt;
836 // only trigger a layout when reserveOffset is changing
837 if (headerCt && !headerCt.layout.reserveOffset) {
838 headerCt.layout.reserveOffset = true;
841 if (me.verticalScroller && me.verticalScroller.ownerCt !== me) {
842 me.addDocked(me.verticalScroller);
843 me.addCls(me.verticalScrollerPresentCls);
844 me.fireEvent('scrollershow', me.verticalScroller, 'vertical');
848 <span id='Ext-panel.Table-method-invalidateScroller'> /**
849 </span> * Invalides scrollers that are present and forces a recalculation.
850 * (Not related to showing/hiding the scrollers)
852 invalidateScroller: function() {
854 vScroll = me.verticalScroller,
855 hScroll = me.horizontalScroller;
858 vScroll.invalidate();
861 hScroll.invalidate();
865 // refresh the view when a header moves
866 onHeaderMove: function(headerCt, header, fromIdx, toIdx) {
870 // Section onHeaderHide is invoked after view.
871 onHeaderHide: function(headerCt, header) {
872 this.invalidateScroller();
875 onHeaderShow: function(headerCt, header) {
876 this.invalidateScroller();
879 getVerticalScroller: function() {
880 return this.getScrollerOwner().down('gridscroller[dock=' + this.verticalScrollDock + ']');
883 getHorizontalScroller: function() {
884 return this.getScrollerOwner().down('gridscroller[dock=bottom]');
887 onMouseWheel: function(e) {
889 browserEvent = e.browserEvent,
890 vertScroller = me.getVerticalScroller(),
891 horizScroller = me.getHorizontalScroller(),
892 scrollDelta = me.scrollDelta,
894 vertScrollerEl, horizScrollerEl,
895 origScrollLeft, origScrollTop,
896 newScrollLeft, newScrollTop;
898 // Track original scroll values, so we can see if we've
899 // reached the end of our scroll height/width.
901 horizScrollerEl = horizScroller.el;
902 if (horizScrollerEl) {
903 origScrollLeft = horizScrollerEl.dom.scrollLeft;
907 vertScrollerEl = vertScroller.el;
908 if (vertScrollerEl) {
909 origScrollTop = vertScrollerEl.dom.scrollTop;
913 // Webkit Horizontal Axis
914 if (browserEvent.wheelDeltaX || browserEvent.wheelDeltaY) {
915 deltaX = -browserEvent.wheelDeltaX / 120 * scrollDelta / 3;
916 deltaY = -browserEvent.wheelDeltaY / 120 * scrollDelta / 3;
918 newScrollLeft = horizScroller.scrollByDeltaX(deltaX);
921 newScrollTop = vertScroller.scrollByDeltaY(deltaY);
924 // Gecko Horizontal Axis
925 if (browserEvent.axis && browserEvent.axis === 1) {
927 deltaX = -(scrollDelta * e.getWheelDelta()) / 3;
928 newScrollLeft = horizScroller.scrollByDeltaX(deltaX);
933 deltaY = -(scrollDelta * e.getWheelDelta() / 3);
934 newScrollTop = vertScroller.scrollByDeltaY(deltaY);
939 // If after given our delta, the scroller has not progressed, then we're
940 // at the end of our scroll range and shouldn't stop the browser event.
941 if ((deltaX !== 0 && newScrollLeft !== origScrollLeft) ||
942 (deltaY !== 0 && newScrollTop !== origScrollTop)) {
947 <span id='Ext-panel.Table-method-onViewRefresh'> /**
949 * Determine and invalidate scrollers on view refresh
951 onViewRefresh: function() {
953 this.syncCellHeight();
955 this.determineScrollbars();
956 if (this.invalidateScrollerOnRefresh) {
957 this.invalidateScroller();
961 onViewItemUpdate: function(record, index, tr) {
963 this.syncCellHeight([tr]);
967 // BrowserBug: IE will not stretch the td to fit the height of the entire
968 // tr, so manually sync cellheights on refresh and when an item has been
970 syncCellHeight: function(trs) {
979 cellClsSelector = ('.' + Ext.baseCSSPrefix + 'grid-cell');
981 trs = trs || me.view.getNodes();
985 for (; i < trsLn; i++) {
987 tds = Ext.fly(tr).query(cellClsSelector);
990 for (j = 0; j < tdsLn; j++) {
992 cellHeights.push(td.clientHeight);
994 rowHeights.push(Ext.Array.max(cellHeights));
998 for (i = 0; i < trsLn; i++) {
1000 tdsLn = tr.childNodes.length;
1001 for (j = 0; j < tdsLn; j++) {
1002 td = Ext.fly(tr.childNodes[j]);
1003 if (rowHeights[i]) {
1004 if (td.is(cellClsSelector)) {
1005 td.setHeight(rowHeights[i]);
1007 td.down(cellClsSelector).setHeight(rowHeights[i]);
1015 <span id='Ext-panel.Table-method-setScrollTop'> /**
1016 </span> * Sets the scrollTop of the TablePanel.
1017 * @param {Number} deltaY
1019 setScrollTop: function(top) {
1021 rootCmp = me.getScrollerOwner(),
1022 verticalScroller = me.getVerticalScroller();
1024 rootCmp.virtualScrollTop = top;
1025 if (verticalScroller) {
1026 verticalScroller.setScrollTop(top);
1031 getScrollerOwner: function() {
1033 if (!this.scrollerOwner) {
1034 rootCmp = this.up('[scrollerOwner]');
1039 <span id='Ext-panel.Table-method-scrollByDeltaY'> /**
1040 </span> * Scrolls the TablePanel by deltaY
1041 * @param {Number} deltaY
1043 scrollByDeltaY: function(deltaY) {
1044 var rootCmp = this.getScrollerOwner(),
1046 scrollerRight = rootCmp.down('gridscroller[dock=' + this.verticalScrollDock + ']');
1047 if (scrollerRight) {
1048 scrollerRight.scrollByDeltaY(deltaY);
1053 <span id='Ext-panel.Table-method-scrollByDeltaX'> /**
1054 </span> * Scrolls the TablePanel by deltaX
1055 * @param {Number} deltaY
1057 scrollByDeltaX: function(deltaX) {
1058 this.horizontalScroller.scrollByDeltaX(deltaX);
1061 <span id='Ext-panel.Table-method-getLhsMarker'> /**
1062 </span> * Get left hand side marker for header resizing.
1065 getLhsMarker: function() {
1068 if (!me.lhsMarker) {
1069 me.lhsMarker = Ext.core.DomHelper.append(me.el, {
1070 cls: Ext.baseCSSPrefix + 'grid-resize-marker'
1073 return me.lhsMarker;
1076 <span id='Ext-panel.Table-method-getRhsMarker'> /**
1077 </span> * Get right hand side marker for header resizing.
1080 getRhsMarker: function() {
1083 if (!me.rhsMarker) {
1084 me.rhsMarker = Ext.core.DomHelper.append(me.el, {
1085 cls: Ext.baseCSSPrefix + 'grid-resize-marker'
1088 return me.rhsMarker;
1091 <span id='Ext-panel.Table-method-getSelectionModel'> /**
1092 </span> * Returns the selection model being used and creates it via the configuration
1093 * if it has not been created already.
1094 * @return {Ext.selection.Model} selModel
1096 getSelectionModel: function(){
1097 if (!this.selModel) {
1101 var mode = 'SINGLE',
1103 if (this.simpleSelect) {
1105 } else if (this.multiSelect) {
1109 Ext.applyIf(this.selModel, {
1110 allowDeselect: this.allowDeselect,
1114 if (!this.selModel.events) {
1115 type = this.selModel.selType || this.selType;
1116 this.selModel = Ext.create('selection.' + type, this.selModel);
1119 if (!this.selModel.hasRelaySetup) {
1120 this.relayEvents(this.selModel, ['selectionchange', 'select', 'deselect']);
1121 this.selModel.hasRelaySetup = true;
1124 // lock the selection model if user
1125 // has disabled selection
1126 if (this.disableSelection) {
1127 this.selModel.locked = true;
1129 return this.selModel;
1132 onVerticalScroll: function(event, target) {
1133 var owner = this.getScrollerOwner(),
1134 items = owner.query('tableview'),
1138 for (; i < len; i++) {
1139 items[i].el.dom.scrollTop = target.scrollTop;
1143 onHorizontalScroll: function(event, target) {
1144 var owner = this.getScrollerOwner(),
1145 items = owner.query('tableview'),
1154 center = items[1] || items[0];
1155 centerEl = center.el.dom;
1156 centerScrollWidth = centerEl.scrollWidth;
1157 centerClientWidth = centerEl.offsetWidth;
1158 width = this.horizontalScroller.getWidth();
1160 centerEl.scrollLeft = target.scrollLeft;
1161 this.headerCt.el.dom.scrollLeft = target.scrollLeft;
1164 // template method meant to be overriden
1165 onStoreLoad: Ext.emptyFn,
1167 getEditorParent: function() {
1171 bindStore: function(store) {
1174 me.getView().bindStore(store);
1177 reconfigure: function(store, columns) {
1181 me.reconfigureLockable(store, columns);
1186 me.headerCt.removeAll();
1187 me.headerCt.add(columns);
1190 store = Ext.StoreManager.lookup(store);
1191 me.bindStore(store);
1193 me.getView().refresh();
1197 afterComponentLayout: function() {
1198 this.callParent(arguments);
1199 this.determineScrollbars();
1200 this.invalidateScroller();
1202 });</pre></pre></body></html>