Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / grid / PagingScroller.js
index 9c322fc..c9dd252 100644 (file)
@@ -1,8 +1,20 @@
+/*
+
+This file is part of Ext JS 4
+
+Copyright (c) 2011 Sencha Inc
+
+Contact:  http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
+
+*/
 /**
  * @class Ext.grid.PagingScroller
  * @extends Ext.grid.Scroller
- *
- * @private
  */
 Ext.define('Ext.grid.PagingScroller', {
     extend: 'Ext.grid.Scroller',
@@ -20,29 +32,28 @@ Ext.define('Ext.grid.PagingScroller', {
      * when scrolling up between records 0 and 34 and when scrolling down between records 65 and 99.
      */
     percentageFromEdge: 0.35,
-    
+
     /**
      * @cfg {Number} scrollToLoadBuffer This is the time in milliseconds to buffer load requests
      * when scrolling the PagingScrollbar.
      */
     scrollToLoadBuffer: 200,
-    
+
     activePrefetch: true,
-    
+
     chunkSize: 50,
     snapIncrement: 25,
-    
+
     syncScroll: true,
-    
+
     initComponent: function() {
         var me = this,
             ds = me.store;
 
-        ds.on('guaranteedrange', this.onGuaranteedRange, this);
-        this.callParent(arguments);
+        ds.on('guaranteedrange', me.onGuaranteedRange, me);
+        me.callParent(arguments);
     },
-    
-    
+
     onGuaranteedRange: function(range, start, end) {
         var me = this,
             ds = me.store,
@@ -51,34 +62,38 @@ Ext.define('Ext.grid.PagingScroller', {
         if (range.length && me.visibleStart < range[0].index) {
             return;
         }
-        
+
         ds.loadRecords(range);
 
         if (!me.firstLoad) {
             if (me.rendered) {
                 me.invalidate();
             } else {
-                me.on('afterrender', this.invalidate, this, {single: true});
+                me.on('afterrender', me.invalidate, me, {single: true});
             }
             me.firstLoad = true;
         } else {
             // adjust to visible
-            me.syncTo();
+            // only sync if there is a paging scrollbar element and it has a scroll height (meaning it's currently in the DOM)
+            if (me.scrollEl && me.scrollEl.dom && me.scrollEl.dom.scrollHeight) {
+                me.syncTo();
+            }
         }
     },
-    
+
     syncTo: function() {
         var me            = this,
             pnl           = me.getPanel(),
             store         = pnl.store,
-            scrollerElDom = this.el.dom,
+            scrollerElDom = this.scrollEl.dom,
             rowOffset     = me.visibleStart - store.guaranteedStart,
             scrollBy      = rowOffset * me.rowHeight,
             scrollHeight  = scrollerElDom.scrollHeight,
             clientHeight  = scrollerElDom.clientHeight,
             scrollTop     = scrollerElDom.scrollTop,
             useMaximum;
-        
+            
+
         // BrowserBug: clientHeight reports 0 in IE9 StrictMode
         // Instead we are using offsetHeight and hardcoding borders
         if (Ext.isIE9 && Ext.isStrict) {
@@ -86,16 +101,16 @@ Ext.define('Ext.grid.PagingScroller', {
         }
 
         // This should always be zero or greater than zero but staying
-        // safe and less than 0 we'll scroll to the bottom.        
+        // safe and less than 0 we'll scroll to the bottom.
         useMaximum = (scrollHeight - clientHeight - scrollTop <= 0);
         this.setViewScrollTop(scrollBy, useMaximum);
     },
-    
+
     getPageData : function(){
         var panel = this.getPanel(),
             store = panel.store,
             totalCount = store.getTotalCount();
-            
+
         return {
             total : totalCount,
             currentPage : store.currentPage,
@@ -104,7 +119,7 @@ Ext.define('Ext.grid.PagingScroller', {
             toRecord: Math.min(store.currentPage * store.pageSize, totalCount)
         };
     },
-    
+
     onElScroll: function(e, t) {
         var me = this,
             panel = me.getPanel(),
@@ -113,7 +128,7 @@ Ext.define('Ext.grid.PagingScroller', {
             guaranteedStart = store.guaranteedStart,
             guaranteedEnd = store.guaranteedEnd,
             totalCount = store.getTotalCount(),
-            numFromEdge = Math.ceil(me.percentageFromEdge * store.pageSize),
+            numFromEdge = Math.ceil(me.percentageFromEdge * pageSize),
             position = t.scrollTop,
             visibleStart = Math.floor(position / me.rowHeight),
             view = panel.down('tableview'),
@@ -121,11 +136,11 @@ Ext.define('Ext.grid.PagingScroller', {
             visibleHeight = viewEl.getHeight(),
             visibleAhead = Math.ceil(visibleHeight / me.rowHeight),
             visibleEnd = visibleStart + visibleAhead,
-            prevPage = Math.floor(visibleStart / store.pageSize),
-            nextPage = Math.floor(visibleEnd / store.pageSize) + 2,
-            lastPage = Math.ceil(totalCount / store.pageSize),
-            //requestStart = visibleStart,
-            requestStart = Math.floor(visibleStart / me.snapIncrement) * me.snapIncrement,
+            prevPage = Math.floor(visibleStart / pageSize),
+            nextPage = Math.floor(visibleEnd / pageSize) + 2,
+            lastPage = Math.ceil(totalCount / pageSize),
+            snap = me.snapIncrement,
+            requestStart = Math.floor(visibleStart / snap) * snap,
             requestEnd = requestStart + pageSize - 1,
             activePrefetch = me.activePrefetch;
 
@@ -137,15 +152,25 @@ Ext.define('Ext.grid.PagingScroller', {
         if (totalCount >= pageSize) {
             // end of request was past what the total is, grab from the end back a pageSize
             if (requestEnd > totalCount - 1) {
-                this.cancelLoad();
+                me.cancelLoad();
                 if (store.rangeSatisfied(totalCount - pageSize, totalCount - 1)) {
                     me.syncScroll = true;
                 }
                 store.guaranteeRange(totalCount - pageSize, totalCount - 1);
             // Out of range, need to reset the current data set
-            } else if (visibleStart < guaranteedStart || visibleEnd > guaranteedEnd) {
+            } else if (visibleStart <= guaranteedStart || visibleEnd > guaranteedEnd) {
+                if (visibleStart <= guaranteedStart) {
+                    // need to scroll up
+                    requestStart -= snap;
+                    requestEnd -= snap;
+                    
+                    if (requestStart < 0) {
+                        requestStart = 0;
+                        requestEnd = pageSize;
+                    }
+                }
                 if (store.rangeSatisfied(requestStart, requestEnd)) {
-                    this.cancelLoad();
+                    me.cancelLoad();
                     store.guaranteeRange(requestStart, requestEnd);
                 } else {
                     store.mask();
@@ -161,29 +186,30 @@ Ext.define('Ext.grid.PagingScroller', {
                 store.prefetchPage(nextPage);
             }
         }
-    
-    
+
         if (me.syncScroll) {
             me.syncTo();
         }
     },
-    
+
     getSizeCalculation: function() {
         // Use the direct ownerCt here rather than the scrollerOwner
         // because we are calculating widths/heights.
-        var owner = this.ownerCt,
+        var me     = this,
+            owner  = me.ownerGrid,
             view   = owner.getView(),
-            store  = this.store,
-            dock   = this.dock,
-            elDom  = this.el.dom,
+            store  = me.store,
+            dock   = me.dock,
+            elDom  = me.el.dom,
             width  = 1,
             height = 1;
-        
-        if (!this.rowHeight) {
-            this.rowHeight = view.el.down(view.getItemSelector()).getHeight(false, true);
+
+        if (!me.rowHeight) {
+            me.rowHeight = view.el.down(view.getItemSelector()).getHeight(false, true);
         }
 
-        height = store.getTotalCount() * this.rowHeight;
+        // If the Store is *locally* filtered, use the filtered count from getCount.
+        height = store[(!store.remoteFilter && store.isFiltered()) ? 'getCount' : 'getTotalCount']() * me.rowHeight;
 
         if (isNaN(width)) {
             width = 1;
@@ -196,7 +222,7 @@ Ext.define('Ext.grid.PagingScroller', {
             height: height
         };
     },
-    
+
     attemptLoad: function(start, end) {
         var me = this;
         if (!me.loadTask) {
@@ -204,20 +230,21 @@ Ext.define('Ext.grid.PagingScroller', {
         }
         me.loadTask.delay(me.scrollToLoadBuffer, me.doAttemptLoad, me, [start, end]);
     },
-    
+
     cancelLoad: function() {
         if (this.loadTask) {
             this.loadTask.cancel();
         }
     },
-    
+
     doAttemptLoad:  function(start, end) {
         var store = this.getPanel().store;
         store.guaranteeRange(start, end);
     },
-    
+
     setViewScrollTop: function(scrollTop, useMax) {
-        var owner = this.getPanel(),
+        var me = this,
+            owner = me.getPanel(),
             items = owner.query('tableview'),
             i = 0,
             len = items.length,
@@ -225,15 +252,15 @@ Ext.define('Ext.grid.PagingScroller', {
             centerEl,
             calcScrollTop,
             maxScrollTop,
-            scrollerElDom = this.el.dom;
-            
+            scrollerElDom = me.el.dom;
+
         owner.virtualScrollTop = scrollTop;
-            
+
         center = items[1] || items[0];
         centerEl = center.el.dom;
-        
-        maxScrollTop = ((owner.store.pageSize * this.rowHeight) - centerEl.clientHeight);
-        calcScrollTop = (scrollTop % ((owner.store.pageSize * this.rowHeight) + 1));
+
+        maxScrollTop = ((owner.store.pageSize * me.rowHeight) - centerEl.clientHeight);
+        calcScrollTop = (scrollTop % ((owner.store.pageSize * me.rowHeight) + 1));
         if (useMax) {
             calcScrollTop = maxScrollTop;
         }