Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / examples / docs / source / BufferView.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.3.1
11  * Copyright(c) 2006-2010 Sencha Inc.
12  * licensing@sencha.com
13  * http://www.sencha.com/license
14  */
15 Ext.ns('Ext.ux.grid');
16
17 <div id="cls-Ext.ux.grid.BufferView"></div>/**
18  * @class Ext.ux.grid.BufferView
19  * @extends Ext.grid.GridView
20  * A custom GridView which renders rows on an as-needed basis.
21  */
22 Ext.ux.grid.BufferView = Ext.extend(Ext.grid.GridView, {
23         <div id="cfg-Ext.ux.grid.BufferView-rowHeight"></div>/**
24          * @cfg {Number} rowHeight
25          * The height of a row in the grid.
26          */
27         rowHeight: 19,
28
29         <div id="cfg-Ext.ux.grid.BufferView-borderHeight"></div>/**
30          * @cfg {Number} borderHeight
31          * The combined height of border-top and border-bottom of a row.
32          */
33         borderHeight: 2,
34
35         <div id="cfg-Ext.ux.grid.BufferView-scrollDelay"></div>/**
36          * @cfg {Boolean/Number} scrollDelay
37          * The number of milliseconds before rendering rows out of the visible
38          * viewing area. Defaults to 100. Rows will render immediately with a config
39          * of false.
40          */
41         scrollDelay: 100,
42
43         <div id="cfg-Ext.ux.grid.BufferView-cacheSize"></div>/**
44          * @cfg {Number} cacheSize
45          * The number of rows to look forward and backwards from the currently viewable
46          * area.  The cache applies only to rows that have been rendered already.
47          */
48         cacheSize: 20,
49
50         <div id="cfg-Ext.ux.grid.BufferView-cleanDelay"></div>/**
51          * @cfg {Number} cleanDelay
52          * The number of milliseconds to buffer cleaning of extra rows not in the
53          * cache.
54          */
55         cleanDelay: 500,
56
57         initTemplates : function(){
58                 Ext.ux.grid.BufferView.superclass.initTemplates.call(this);
59                 var ts = this.templates;
60                 // empty div to act as a place holder for a row
61                 ts.rowHolder = new Ext.Template(
62                         '<div class="x-grid3-row {alt}" style="{tstyle}"></div>'
63                 );
64                 ts.rowHolder.disableFormats = true;
65                 ts.rowHolder.compile();
66
67                 ts.rowBody = new Ext.Template(
68                         '<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
69                         '<tbody><tr>{cells}</tr>',
70                         (this.enableRowBody ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>' : ''),
71                         '</tbody></table>'
72                 );
73                 ts.rowBody.disableFormats = true;
74                 ts.rowBody.compile();
75         },
76
77         getStyleRowHeight : function(){
78                 return Ext.isBorderBox ? (this.rowHeight + this.borderHeight) : this.rowHeight;
79         },
80
81         getCalculatedRowHeight : function(){
82                 return this.rowHeight + this.borderHeight;
83         },
84
85         getVisibleRowCount : function(){
86                 var rh = this.getCalculatedRowHeight(),
87                     visibleHeight = this.scroller.dom.clientHeight;
88                 return (visibleHeight < 1) ? 0 : Math.ceil(visibleHeight / rh);
89         },
90
91         getVisibleRows: function(){
92                 var count = this.getVisibleRowCount(),
93                     sc = this.scroller.dom.scrollTop,
94                     start = (sc === 0 ? 0 : Math.floor(sc/this.getCalculatedRowHeight())-1);
95                 return {
96                         first: Math.max(start, 0),
97                         last: Math.min(start + count + 2, this.ds.getCount()-1)
98                 };
99         },
100
101         doRender : function(cs, rs, ds, startRow, colCount, stripe, onlyBody){
102                 var ts = this.templates, 
103             ct = ts.cell, 
104             rt = ts.row, 
105             rb = ts.rowBody, 
106             last = colCount-1,
107                     rh = this.getStyleRowHeight(),
108                     vr = this.getVisibleRows(),
109                     tstyle = 'width:'+this.getTotalWidth()+';height:'+rh+'px;',
110                     // buffers
111                     buf = [], 
112             cb, 
113             c, 
114             p = {}, 
115             rp = {tstyle: tstyle}, 
116             r;
117                 for (var j = 0, len = rs.length; j < len; j++) {
118                         r = rs[j]; cb = [];
119                         var rowIndex = (j+startRow),
120                             visible = rowIndex >= vr.first && rowIndex <= vr.last;
121                         if (visible) {
122                                 for (var i = 0; i < colCount; i++) {
123                                         c = cs[i];
124                                         p.id = c.id;
125                                         p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
126                                         p.attr = p.cellAttr = "";
127                                         p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
128                                         p.style = c.style;
129                                         if (p.value === undefined || p.value === "") {
130                                                 p.value = "&#160;";
131                                         }
132                                         if (r.dirty && typeof r.modified[c.name] !== 'undefined') {
133                                                 p.css += ' x-grid3-dirty-cell';
134                                         }
135                                         cb[cb.length] = ct.apply(p);
136                                 }
137                         }
138                         var alt = [];
139                         if(stripe && ((rowIndex+1) % 2 === 0)){
140                             alt[0] = "x-grid3-row-alt";
141                         }
142                         if(r.dirty){
143                             alt[1] = " x-grid3-dirty-row";
144                         }
145                         rp.cols = colCount;
146                         if(this.getRowClass){
147                             alt[2] = this.getRowClass(r, rowIndex, rp, ds);
148                         }
149                         rp.alt = alt.join(" ");
150                         rp.cells = cb.join("");
151                         buf[buf.length] =  !visible ? ts.rowHolder.apply(rp) : (onlyBody ? rb.apply(rp) : rt.apply(rp));
152                 }
153                 return buf.join("");
154         },
155
156         isRowRendered: function(index){
157                 var row = this.getRow(index);
158                 return row && row.childNodes.length > 0;
159         },
160
161         syncScroll: function(){
162                 Ext.ux.grid.BufferView.superclass.syncScroll.apply(this, arguments);
163                 this.update();
164         },
165
166         // a (optionally) buffered method to update contents of gridview
167         update: function(){
168                 if (this.scrollDelay) {
169                         if (!this.renderTask) {
170                                 this.renderTask = new Ext.util.DelayedTask(this.doUpdate, this);
171                         }
172                         this.renderTask.delay(this.scrollDelay);
173                 }else{
174                         this.doUpdate();
175                 }
176         },
177     
178     onRemove : function(ds, record, index, isUpdate){
179         Ext.ux.grid.BufferView.superclass.onRemove.apply(this, arguments);
180         if(isUpdate !== true){
181             this.update();
182         }
183     },
184
185         doUpdate: function(){
186                 if (this.getVisibleRowCount() > 0) {
187                         var g = this.grid, 
188                 cm = g.colModel, 
189                 ds = g.store,
190                 cs = this.getColumnData(),
191                         vr = this.getVisibleRows(),
192                 row;
193                         for (var i = vr.first; i <= vr.last; i++) {
194                                 // if row is NOT rendered and is visible, render it
195                                 if(!this.isRowRendered(i) && (row = this.getRow(i))){
196                                         var html = this.doRender(cs, [ds.getAt(i)], ds, i, cm.getColumnCount(), g.stripeRows, true);
197                                         row.innerHTML = html;
198                                 }
199                         }
200                         this.clean();
201                 }
202         },
203
204         // a buffered method to clean rows
205         clean : function(){
206                 if(!this.cleanTask){
207                         this.cleanTask = new Ext.util.DelayedTask(this.doClean, this);
208                 }
209                 this.cleanTask.delay(this.cleanDelay);
210         },
211
212         doClean: function(){
213                 if (this.getVisibleRowCount() > 0) {
214                         var vr = this.getVisibleRows();
215                         vr.first -= this.cacheSize;
216                         vr.last += this.cacheSize;
217
218                         var i = 0, rows = this.getRows();
219                         // if first is less than 0, all rows have been rendered
220                         // so lets clean the end...
221                         if(vr.first <= 0){
222                                 i = vr.last + 1;
223                         }
224                         for(var len = this.ds.getCount(); i < len; i++){
225                                 // if current row is outside of first and last and
226                                 // has content, update the innerHTML to nothing
227                                 if ((i < vr.first || i > vr.last) && rows[i].innerHTML) {
228                                         rows[i].innerHTML = '';
229                                 }
230                         }
231                 }
232         },
233     
234     removeTask: function(name){
235         var task = this[name];
236         if(task && task.cancel){
237             task.cancel();
238             this[name] = null;
239         }
240     },
241     
242     destroy : function(){
243         this.removeTask('cleanTask');
244         this.removeTask('renderTask');  
245         Ext.ux.grid.BufferView.superclass.destroy.call(this);
246     },
247
248         layout: function(){
249                 Ext.ux.grid.BufferView.superclass.layout.call(this);
250                 this.update();
251         }
252 });</pre>    
253 </body>
254 </html>