Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / Scroller.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="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../resources/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-grid-Scroller'>/**
19 </span> * Docked in an Ext.grid.Panel, controls virtualized scrolling and synchronization
20  * across different sections.
21  */
22 Ext.define('Ext.grid.Scroller', {
23     extend: 'Ext.Component',
24     alias: 'widget.gridscroller',
25     weight: 110,
26     baseCls: Ext.baseCSSPrefix + 'scroller',
27     focusable: false,
28     reservedSpace: 0,
29
30     renderTpl: [
31         '&lt;div class=&quot;' + Ext.baseCSSPrefix + 'scroller-ct&quot; id=&quot;{baseId}_ct&quot;&gt;',
32             '&lt;div class=&quot;' + Ext.baseCSSPrefix + 'stretcher&quot; id=&quot;{baseId}_stretch&quot;&gt;&lt;/div&gt;',
33         '&lt;/div&gt;'
34     ],
35
36     initComponent: function() {
37         var me       = this,
38             dock     = me.dock,
39             cls      = Ext.baseCSSPrefix + 'scroller-vertical';
40
41         me.offsets = {bottom: 0};
42         me.scrollProp = 'scrollTop';
43         me.vertical = true;
44         me.sizeProp = 'width';
45
46         if (dock === 'top' || dock === 'bottom') {
47             cls = Ext.baseCSSPrefix + 'scroller-horizontal';
48             me.sizeProp = 'height';
49             me.scrollProp = 'scrollLeft';
50             me.vertical = false;
51             me.weight += 5;
52         }
53
54         me.cls += (' ' + cls);
55
56         Ext.applyIf(me.renderSelectors, {
57             stretchEl: '.' + Ext.baseCSSPrefix + 'stretcher',
58             scrollEl: '.' + Ext.baseCSSPrefix + 'scroller-ct'
59         });
60         me.callParent();
61     },
62     
63     ensureDimension: function(){
64         var me = this,
65             sizeProp = me.sizeProp;
66             
67         me[sizeProp] = me.scrollerSize = Ext.getScrollbarSize()[sizeProp];  
68     },
69
70     initRenderData: function () {
71         var me = this,
72             ret = me.callParent(arguments) || {};
73
74         ret.baseId = me.id;
75
76         return ret;
77     },
78
79     afterRender: function() {
80         var me = this;
81         me.callParent();
82         
83         me.mon(me.scrollEl, 'scroll', me.onElScroll, me);
84         Ext.cache[me.el.id].skipGarbageCollection = true;
85     },
86
87     onAdded: function(container) {
88         // Capture the controlling grid Panel so that we can use it even when we are undocked, and don't have an ownerCt
89         this.ownerGrid = container;
90         this.callParent(arguments);
91     },
92
93     getSizeCalculation: function() {
94         var me     = this,
95             owner  = me.getPanel(),
96             width  = 1,
97             height = 1,
98             view, tbl;
99
100         if (!me.vertical) {
101             // TODO: Must gravitate to a single region..
102             // Horizontal scrolling only scrolls virtualized region
103             var items  = owner.query('tableview'),
104                 center = items[1] || items[0];
105
106             if (!center) {
107                 return false;
108             }
109             // center is not guaranteed to have content, such as when there
110             // are zero rows in the grid/tree. We read the width from the
111             // headerCt instead.
112             width = center.headerCt.getFullWidth();
113
114             if (Ext.isIEQuirks) {
115                 width--;
116             }
117         } else {
118             view = owner.down('tableview:not([lockableInjected])');
119             if (!view || !view.el) {
120                 return false;
121             }
122             tbl = view.el.child('table', true);
123             if (!tbl) {
124                 return false;
125             }
126
127             // needs to also account for header and scroller (if still in picture)
128             // should calculate from headerCt.
129             height = tbl.offsetHeight;
130         }
131         if (isNaN(width)) {
132             width = 1;
133         }
134         if (isNaN(height)) {
135             height = 1;
136         }
137         return {
138             width: width,
139             height: height
140         };
141     },
142
143     invalidate: function(firstPass) {
144         var me = this,
145             stretchEl = me.stretchEl;
146
147         if (!stretchEl || !me.ownerCt) {
148             return;
149         }
150
151         var size  = me.getSizeCalculation(),
152             scrollEl = me.scrollEl,
153             elDom = scrollEl.dom,
154             reservedSpace = me.reservedSpace,
155             pos,
156             extra = 5;
157
158         if (size) {
159             stretchEl.setSize(size);
160
161             size = me.el.getSize(true);
162
163             if (me.vertical) {
164                 size.width += extra;
165                 size.height -= reservedSpace;
166                 pos = 'left';
167             } else {
168                 size.width -= reservedSpace;
169                 size.height += extra;
170                 pos = 'top';
171             }
172
173             scrollEl.setSize(size);
174             elDom.style[pos] = (-extra) + 'px';
175
176             // BrowserBug: IE7
177             // This makes the scroller enabled, when initially rendering.
178             elDom.scrollTop = elDom.scrollTop;
179         }
180     },
181
182     afterComponentLayout: function() {
183         this.callParent(arguments);
184         this.invalidate();
185     },
186
187     restoreScrollPos: function () {
188         var me = this,
189             el = this.scrollEl,
190             elDom = el &amp;&amp; el.dom;
191
192         if (me._scrollPos !== null &amp;&amp; elDom) {
193             elDom[me.scrollProp] = me._scrollPos;
194             me._scrollPos = null;
195         }
196     },
197
198     setReservedSpace: function (reservedSpace) {
199         var me = this;
200         if (me.reservedSpace !== reservedSpace) {
201             me.reservedSpace = reservedSpace;
202             me.invalidate();
203         }
204     },
205
206     saveScrollPos: function () {
207         var me = this,
208             el = this.scrollEl,
209             elDom = el &amp;&amp; el.dom;
210
211         me._scrollPos = elDom ? elDom[me.scrollProp] : null;
212     },
213
214 <span id='Ext-grid-Scroller-method-setScrollTop'>    /**
215 </span>     * Sets the scrollTop and constrains the value between 0 and max.
216      * @param {Number} scrollTop
217      * @return {Number} The resulting scrollTop value after being constrained
218      */
219     setScrollTop: function(scrollTop) {
220         var el = this.scrollEl,
221             elDom = el &amp;&amp; el.dom;
222
223         if (elDom) {
224             return elDom.scrollTop = Ext.Number.constrain(scrollTop, 0, elDom.scrollHeight - elDom.clientHeight);
225         }
226     },
227
228 <span id='Ext-grid-Scroller-method-setScrollLeft'>    /**
229 </span>     * Sets the scrollLeft and constrains the value between 0 and max.
230      * @param {Number} scrollLeft
231      * @return {Number} The resulting scrollLeft value after being constrained
232      */
233     setScrollLeft: function(scrollLeft) {
234         var el = this.scrollEl,
235             elDom = el &amp;&amp; el.dom;
236
237         if (elDom) {
238             return elDom.scrollLeft = Ext.Number.constrain(scrollLeft, 0, elDom.scrollWidth - elDom.clientWidth);
239         }
240     },
241
242 <span id='Ext-grid-Scroller-method-scrollByDeltaY'>    /**
243 </span>     * Scroll by deltaY
244      * @param {Number} delta
245      * @return {Number} The resulting scrollTop value
246      */
247     scrollByDeltaY: function(delta) {
248         var el = this.scrollEl,
249             elDom = el &amp;&amp; el.dom;
250
251         if (elDom) {
252             return this.setScrollTop(elDom.scrollTop + delta);
253         }
254     },
255
256 <span id='Ext-grid-Scroller-method-scrollByDeltaX'>    /**
257 </span>     * Scroll by deltaX
258      * @param {Number} delta
259      * @return {Number} The resulting scrollLeft value
260      */
261     scrollByDeltaX: function(delta) {
262         var el = this.scrollEl,
263             elDom = el &amp;&amp; el.dom;
264
265         if (elDom) {
266             return this.setScrollLeft(elDom.scrollLeft + delta);
267         }
268     },
269
270
271 <span id='Ext-grid-Scroller-method-scrollToTop'>    /**
272 </span>     * Scroll to the top.
273      */
274     scrollToTop : function(){
275         this.setScrollTop(0);
276     },
277
278     // synchronize the scroller with the bound gridviews
279     onElScroll: function(event, target) {
280         this.fireEvent('bodyscroll', event, target);
281     },
282
283     getPanel: function() {
284         var me = this;
285         if (!me.panel) {
286             me.panel = this.up('[scrollerOwner]');
287         }
288         return me.panel;
289     }
290 });
291
292 </pre>
293 </body>
294 </html>