Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / PagingScroller.html
diff --git a/docs/source/PagingScroller.html b/docs/source/PagingScroller.html
new file mode 100644 (file)
index 0000000..ba64936
--- /dev/null
@@ -0,0 +1,270 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>The source code</title>
+  <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
+  <script type="text/javascript" src="../prettify/prettify.js"></script>
+  <style type="text/css">
+    .highlight { display: block; background-color: #ddd; }
+  </style>
+  <script type="text/javascript">
+    function highlight() {
+      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+    }
+  </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+  <pre class="prettyprint lang-js"><span id='Ext-grid-PagingScroller'>/**
+</span> * @class Ext.grid.PagingScroller
+ * @extends Ext.grid.Scroller
+ *
+ * @private
+ */
+Ext.define('Ext.grid.PagingScroller', {
+    extend: 'Ext.grid.Scroller',
+    alias: 'widget.paginggridscroller',
+    //renderTpl: null,
+    //tpl: [
+    //    '&lt;tpl for=&quot;pages&quot;&gt;',
+    //        '&lt;div class=&quot;' + Ext.baseCSSPrefix + 'stretcher&quot; style=&quot;width: {width}px;height: {height}px;&quot;&gt;&lt;/div&gt;',
+    //    '&lt;/tpl&gt;'
+    //],
+<span id='Ext-grid-PagingScroller-cfg-percentageFromEdge'>    /**
+</span>     * @cfg {Number} percentageFromEdge This is a number above 0 and less than 1 which specifies
+     * at what percentage to begin fetching the next page. For example if the pageSize is 100
+     * and the percentageFromEdge is the default of 0.35, the paging scroller will prefetch pages
+     * when scrolling up between records 0 and 34 and when scrolling down between records 65 and 99.
+     */
+    percentageFromEdge: 0.35,
+    
+<span id='Ext-grid-PagingScroller-cfg-scrollToLoadBuffer'>    /**
+</span>     * @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);
+    },
+    
+    
+    onGuaranteedRange: function(range, start, end) {
+        var me = this,
+            ds = me.store,
+            rs;
+        // this should never happen
+        if (range.length &amp;&amp; me.visibleStart &lt; 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.firstLoad = true;
+        } else {
+            // adjust to visible
+            me.syncTo();
+        }
+    },
+    
+    syncTo: function() {
+        var me            = this,
+            pnl           = me.getPanel(),
+            store         = pnl.store,
+            scrollerElDom = this.el.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 &amp;&amp; Ext.isStrict) {
+            clientHeight = scrollerElDom.offsetHeight + 2;
+        }
+
+        // This should always be zero or greater than zero but staying
+        // safe and less than 0 we'll scroll to the bottom.        
+        useMaximum = (scrollHeight - clientHeight - scrollTop &lt;= 0);
+        this.setViewScrollTop(scrollBy, useMaximum);
+    },
+    
+    getPageData : function(){
+        var panel = this.getPanel(),
+            store = panel.store,
+            totalCount = store.getTotalCount();
+            
+        return {
+            total : totalCount,
+            currentPage : store.currentPage,
+            pageCount: Math.ceil(totalCount / store.pageSize),
+            fromRecord: ((store.currentPage - 1) * store.pageSize) + 1,
+            toRecord: Math.min(store.currentPage * store.pageSize, totalCount)
+        };
+    },
+    
+    onElScroll: function(e, t) {
+        var me = this,
+            panel = me.getPanel(),
+            store = panel.store,
+            pageSize = store.pageSize,
+            guaranteedStart = store.guaranteedStart,
+            guaranteedEnd = store.guaranteedEnd,
+            totalCount = store.getTotalCount(),
+            numFromEdge = Math.ceil(me.percentageFromEdge * store.pageSize),
+            position = t.scrollTop,
+            visibleStart = Math.floor(position / me.rowHeight),
+            view = panel.down('tableview'),
+            viewEl = view.el,
+            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,
+            requestEnd = requestStart + pageSize - 1,
+            activePrefetch = me.activePrefetch;
+
+        me.visibleStart = visibleStart;
+        me.visibleEnd = visibleEnd;
+        
+        
+        me.syncScroll = true;
+        if (totalCount &gt;= pageSize) {
+            // end of request was past what the total is, grab from the end back a pageSize
+            if (requestEnd &gt; totalCount - 1) {
+                this.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 &lt; guaranteedStart || visibleEnd &gt; guaranteedEnd) {
+                if (store.rangeSatisfied(requestStart, requestEnd)) {
+                    this.cancelLoad();
+                    store.guaranteeRange(requestStart, requestEnd);
+                } else {
+                    store.mask();
+                    me.attemptLoad(requestStart, requestEnd);
+                }
+                // dont sync the scroll view immediately, sync after the range has been guaranteed
+                me.syncScroll = false;
+            } else if (activePrefetch &amp;&amp; visibleStart &lt; (guaranteedStart + numFromEdge) &amp;&amp; prevPage &gt; 0) {
+                me.syncScroll = true;
+                store.prefetchPage(prevPage);
+            } else if (activePrefetch &amp;&amp; visibleEnd &gt; (guaranteedEnd - numFromEdge) &amp;&amp; nextPage &lt; lastPage) {
+                me.syncScroll = true;
+                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,
+            view   = owner.getView(),
+            store  = this.store,
+            dock   = this.dock,
+            elDom  = this.el.dom,
+            width  = 1,
+            height = 1;
+        
+        if (!this.rowHeight) {
+            this.rowHeight = view.el.down(view.getItemSelector()).getHeight(false, true);
+        }
+
+        height = store.getTotalCount() * this.rowHeight;
+
+        if (isNaN(width)) {
+            width = 1;
+        }
+        if (isNaN(height)) {
+            height = 1;
+        }
+        return {
+            width: width,
+            height: height
+        };
+    },
+    
+    attemptLoad: function(start, end) {
+        var me = this;
+        if (!me.loadTask) {
+            me.loadTask = Ext.create('Ext.util.DelayedTask', me.doAttemptLoad, me, []);
+        }
+        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(),
+            items = owner.query('tableview'),
+            i = 0,
+            len = items.length,
+            center,
+            centerEl,
+            calcScrollTop,
+            maxScrollTop,
+            scrollerElDom = this.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));
+        if (useMax) {
+            calcScrollTop = maxScrollTop;
+        }
+        if (calcScrollTop &gt; maxScrollTop) {
+            //Ext.Error.raise(&quot;Calculated scrollTop was larger than maxScrollTop&quot;);
+            return;
+            // calcScrollTop = maxScrollTop;
+        }
+        for (; i &lt; len; i++) {
+            items[i].el.dom.scrollTop = calcScrollTop;
+        }
+    }
+});
+
+</pre>
+</body>
+</html>