Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / docs / source / PivotGridView.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 <div id="cls-Ext.grid.PivotGridView"></div>/**
16  * @class Ext.grid.PivotGridView
17  * @extends Ext.grid.GridView
18  * Specialised GridView for rendering Pivot Grid components. Config can be passed to the PivotGridView via the PivotGrid constructor's
19  * viewConfig option:
20 <pre><code>
21 new Ext.grid.PivotGrid({
22     viewConfig: {
23         title: 'My Pivot Grid',
24         getCellCls: function(value) {
25             return value > 10 'red' : 'green';
26         }
27     }
28 });
29 </code></pre>
30  * <p>Currently {@link #title} and {@link #getCellCls} are the only configuration options accepted by PivotGridView. All other 
31  * interaction is performed via the {@link Ext.grid.PivotGrid PivotGrid} class.</p>
32  */
33 Ext.grid.PivotGridView = Ext.extend(Ext.grid.GridView, {
34     
35     <div id="prop-Ext.grid.PivotGridView-colHeaderCellCls"></div>/**
36      * The CSS class added to all group header cells. Defaults to 'grid-hd-group-cell'
37      * @property colHeaderCellCls
38      * @type String
39      */
40     colHeaderCellCls: 'grid-hd-group-cell',
41     
42     <div id="cfg-Ext.grid.PivotGridView-title"></div>/**
43      * @cfg {String} title Optional title to be placed in the top left corner of the PivotGrid. Defaults to an empty string.
44      */
45     title: '',
46     
47     <div id="cfg-Ext.grid.PivotGridView-getCellCls"></div>/**
48      * @cfg {Function} getCellCls Optional function which should return a CSS class name for each cell value. This is useful when
49      * color coding cells based on their value. Defaults to undefined.
50      */
51     
52     <div id="method-Ext.grid.PivotGridView-getColumnHeaders"></div>/**
53      * Returns the headers to be rendered at the top of the grid. Should be a 2-dimensional array, where each item specifies the number
54      * of columns it groups (column in this case refers to normal grid columns). In the example below we have 5 city groups, which are
55      * each part of a continent supergroup. The colspan for each city group refers to the number of normal grid columns that group spans,
56      * so in this case the grid would be expected to have a total of 12 columns:
57 <pre><code>
58 [
59     {
60         items: [
61             {header: 'England',   colspan: 5},
62             {header: 'USA',       colspan: 3}
63         ]
64     },
65     {
66         items: [
67             {header: 'London',    colspan: 2},
68             {header: 'Cambridge', colspan: 3},
69             {header: 'Palo Alto', colspan: 3}
70         ]
71     }
72 ]
73 </code></pre>
74      * In the example above we have cities nested under countries. The nesting could be deeper if desired - e.g. Continent -> Country ->
75      * State -> City, or any other structure. The only constaint is that the same depth must be used throughout the structure.
76      * @return {Array} A tree structure containing the headers to be rendered. Must include the colspan property at each level, which should
77      * be the sum of all child nodes beneath this node.
78      */
79     getColumnHeaders: function() {
80         return this.grid.topAxis.buildHeaders();;
81     },
82     
83     <div id="method-Ext.grid.PivotGridView-getRowHeaders"></div>/**
84      * Returns the headers to be rendered on the left of the grid. Should be a 2-dimensional array, where each item specifies the number
85      * of rows it groups. In the example below we have 5 city groups, which are each part of a continent supergroup. The rowspan for each 
86      * city group refers to the number of normal grid columns that group spans, so in this case the grid would be expected to have a 
87      * total of 12 rows:
88 <pre><code>
89 [
90     {
91         width: 90,
92         items: [
93             {header: 'England',   rowspan: 5},
94             {header: 'USA',       rowspan: 3}
95         ]
96     },
97     {
98         width: 50,
99         items: [
100             {header: 'London',    rowspan: 2},
101             {header: 'Cambridge', rowspan: 3},
102             {header: 'Palo Alto', rowspan: 3}
103         ]
104     }
105 ]
106 </code></pre>
107      * In the example above we have cities nested under countries. The nesting could be deeper if desired - e.g. Continent -> Country ->
108      * State -> City, or any other structure. The only constaint is that the same depth must be used throughout the structure.
109      * @return {Array} A tree structure containing the headers to be rendered. Must include the colspan property at each level, which should
110      * be the sum of all child nodes beneath this node.
111      * Each group may specify the width it should be rendered with.
112      * @return {Array} The row groups
113      */
114     getRowHeaders: function() {
115         return this.grid.leftAxis.buildHeaders();
116     },
117     
118     /**
119      * @private
120      * Renders rows between start and end indexes
121      * @param {Number} startRow Index of the first row to render
122      * @param {Number} endRow Index of the last row to render
123      */
124     renderRows : function(startRow, endRow) {
125         var grid          = this.grid,
126             rows          = grid.extractData(),
127             rowCount      = rows.length,
128             templates     = this.templates,
129             renderer      = grid.renderer,
130             hasRenderer   = typeof renderer == 'function',
131             getCellCls    = this.getCellCls,
132             hasGetCellCls = typeof getCellCls == 'function',
133             cellTemplate  = templates.cell,
134             rowTemplate   = templates.row,
135             rowBuffer     = [],
136             meta          = {},
137             tstyle        = 'width:' + this.getGridInnerWidth() + 'px;',
138             colBuffer, column, i;
139         
140         startRow = startRow || 0;
141         endRow   = Ext.isDefined(endRow) ? endRow : rowCount - 1;
142         
143         for (i = 0; i < rowCount; i++) {
144             row = rows[i];
145             colCount  = row.length;
146             colBuffer = [];
147             
148             rowIndex = startRow + i;
149
150             //build up each column's HTML
151             for (j = 0; j < colCount; j++) {
152                 cell = row[j];
153
154                 meta.css   = j === 0 ? 'x-grid3-cell-first ' : (j == (colCount - 1) ? 'x-grid3-cell-last ' : '');
155                 meta.attr  = meta.cellAttr = '';
156                 meta.value = cell;
157
158                 if (Ext.isEmpty(meta.value)) {
159                     meta.value = '&#160;';
160                 }
161                 
162                 if (hasRenderer) {
163                     meta.value = renderer(meta.value);
164                 }
165                 
166                 if (hasGetCellCls) {
167                     meta.css += getCellCls(meta.value) + ' ';
168                 }
169
170                 colBuffer[colBuffer.length] = cellTemplate.apply(meta);
171             }
172             
173             rowBuffer[rowBuffer.length] = rowTemplate.apply({
174                 tstyle: tstyle,
175                 cols  : colCount,
176                 cells : colBuffer.join(""),
177                 alt   : ''
178             });
179         }
180         
181         return rowBuffer.join("");
182     },
183     
184     <div id="prop-Ext.grid.PivotGridView-Ext.Template"></div>/**
185      * The master template to use when rendering the GridView. Has a default template
186      * @property Ext.Template
187      * @type masterTpl
188      */
189     masterTpl: new Ext.Template(
190         '<div class="x-grid3 x-pivotgrid" hidefocus="true">',
191             '<div class="x-grid3-viewport">',
192                 '<div class="x-grid3-header">',
193                     '<div class="x-grid3-header-title"><span>{title}</span></div>',
194                     '<div class="x-grid3-header-inner">',
195                         '<div class="x-grid3-header-offset" style="{ostyle}"></div>',
196                     '</div>',
197                     '<div class="x-clear"></div>',
198                 '</div>',
199                 '<div class="x-grid3-scroller">',
200                     '<div class="x-grid3-row-headers"></div>',
201                     '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
202                     '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
203                 '</div>',
204             '</div>',
205             '<div class="x-grid3-resize-marker">&#160;</div>',
206             '<div class="x-grid3-resize-proxy">&#160;</div>',
207         '</div>'
208     ),
209     
210     /**
211      * @private
212      * Adds a gcell template to the internal templates object. This is used to render the headers in a multi-level column header.
213      */
214     initTemplates: function() {
215         Ext.grid.PivotGridView.superclass.initTemplates.apply(this, arguments);
216         
217         var templates = this.templates || {};
218         if (!templates.gcell) {
219             templates.gcell = new Ext.XTemplate(
220                 '<td class="x-grid3-hd x-grid3-gcell x-grid3-td-{id} ux-grid-hd-group-row-{row} ' + this.colHeaderCellCls + '" style="{style}">',
221                     '<div {tooltip} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', 
222                         this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '', '{value}',
223                     '</div>',
224                 '</td>'
225             );
226         }
227         
228         this.templates = templates;
229         this.hrowRe = new RegExp("ux-grid-hd-group-row-(\\d+)", "");
230     },
231     
232     /**
233      * @private
234      * Sets up the reference to the row headers element
235      */
236     initElements: function() {
237         Ext.grid.PivotGridView.superclass.initElements.apply(this, arguments);
238         
239         <div id="prop-Ext.grid.PivotGridView-rowHeadersEl"></div>/**
240          * @property rowHeadersEl
241          * @type Ext.Element
242          * The element containing all row headers
243          */
244         this.rowHeadersEl = new Ext.Element(this.scroller.child('div.x-grid3-row-headers'));
245         
246         <div id="prop-Ext.grid.PivotGridView-headerTitleEl"></div>/**
247          * @property headerTitleEl
248          * @type Ext.Element
249          * The element that contains the optional title (top left section of the pivot grid)
250          */
251         this.headerTitleEl = new Ext.Element(this.mainHd.child('div.x-grid3-header-title'));
252     },
253     
254     /**
255      * @private
256      * Takes row headers into account when calculating total available width
257      */
258     getGridInnerWidth: function() {
259         var previousWidth = Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this, arguments);
260         
261         return previousWidth - this.getTotalRowHeaderWidth();
262     },
263     
264     <div id="method-Ext.grid.PivotGridView-getTotalRowHeaderWidth"></div>/**
265      * Returns the total width of all row headers as specified by {@link #getRowHeaders}
266      * @return {Number} The total width
267      */
268     getTotalRowHeaderWidth: function() {
269         var headers = this.getRowHeaders(),
270             length  = headers.length,
271             total   = 0,
272             i;
273         
274         for (i = 0; i< length; i++) {
275             total += headers[i].width;
276         }
277         
278         return total;
279     },
280     
281     /**
282      * @private
283      * Returns the total height of all column headers
284      * @return {Number} The total height
285      */
286     getTotalColumnHeaderHeight: function() {
287         return this.getColumnHeaders().length * 21;
288     },
289     
290     /**
291      * @private
292      * Slight specialisation of the GridView renderUI - just adds the row headers
293      */
294     renderUI : function() {
295         var templates  = this.templates,
296             innerWidth = this.getGridInnerWidth();
297             
298         return templates.master.apply({
299             body  : templates.body.apply({rows:'&#160;'}),
300             ostyle: 'width:' + innerWidth + 'px',
301             bstyle: 'width:' + innerWidth + 'px'
302         });
303     },
304     
305     /**
306      * @private
307      * Make sure that the headers and rows are all sized correctly during layout
308      */
309     onLayout: function(width, height) {
310         Ext.grid.PivotGridView.superclass.onLayout.apply(this, arguments);
311         
312         var width = this.getGridInnerWidth();
313         
314         this.resizeColumnHeaders(width);
315         this.resizeAllRows(width);
316     },
317     
318     <div id="method-Ext.grid.PivotGridView-refresh"></div>/**
319      * Refreshs the grid UI
320      * @param {Boolean} headersToo (optional) True to also refresh the headers
321      */
322     refresh : function(headersToo) {
323         this.fireEvent('beforerefresh', this);
324         this.grid.stopEditing(true);
325         
326         var result = this.renderBody();
327         this.mainBody.update(result).setWidth(this.getGridInnerWidth());
328         if (headersToo === true) {
329             this.updateHeaders();
330             this.updateHeaderSortState();
331         }
332         this.processRows(0, true);
333         this.layout();
334         this.applyEmptyText();
335         this.fireEvent('refresh', this);
336     },
337     
338     /**
339      * @private
340      * Bypasses GridView's renderHeaders as they are taken care of separately by the PivotAxis instances
341      */
342     renderHeaders: Ext.emptyFn,
343     
344     /**
345      * @private
346      * Taken care of by PivotAxis
347      */
348     fitColumns: Ext.emptyFn,
349     
350     /**
351      * @private
352      * Called on layout, ensures that the width of each column header is correct. Omitting this can lead to faulty
353      * layouts when nested in a container.
354      * @param {Number} width The new width
355      */
356     resizeColumnHeaders: function(width) {
357         var topAxis = this.grid.topAxis;
358         
359         if (topAxis.rendered) {
360             topAxis.el.setWidth(width);
361         }
362     },
363     
364     /**
365      * @private
366      * Sets the row header div to the correct width. Should be called after rendering and reconfiguration of headers
367      */
368     resizeRowHeaders: function() {
369         var rowHeaderWidth = this.getTotalRowHeaderWidth(),
370             marginStyle    = String.format("margin-left: {0}px;", rowHeaderWidth);
371         
372         this.rowHeadersEl.setWidth(rowHeaderWidth);
373         this.mainBody.applyStyles(marginStyle);
374         Ext.fly(this.innerHd).applyStyles(marginStyle);
375         
376         this.headerTitleEl.setWidth(rowHeaderWidth);
377         this.headerTitleEl.setHeight(this.getTotalColumnHeaderHeight());
378     },
379     
380     /**
381      * @private
382      * Resizes all rendered rows to the given width. Usually called by onLayout
383      * @param {Number} width The new width
384      */
385     resizeAllRows: function(width) {
386         var rows   = this.getRows(),
387             length = rows.length,
388             i;
389         
390         for (i = 0; i < length; i++) {
391             Ext.fly(rows[i]).setWidth(width);
392             Ext.fly(rows[i]).child('table').setWidth(width);
393         }
394     },
395     
396     /**
397      * @private
398      * Updates the Row Headers, deferring the updating of Column Headers to GridView
399      */
400     updateHeaders: function() {
401         this.renderGroupRowHeaders();
402         this.renderGroupColumnHeaders();
403     },
404     
405     /**
406      * @private
407      * Renders all row header groups at all levels based on the structure fetched from {@link #getGroupRowHeaders}
408      */
409     renderGroupRowHeaders: function() {
410         var leftAxis = this.grid.leftAxis;
411         
412         this.resizeRowHeaders();
413         leftAxis.rendered = false;
414         leftAxis.render(this.rowHeadersEl);
415         
416         this.setTitle(this.title);
417     },
418     
419     <div id="method-Ext.grid.PivotGridView-setTitle"></div>/**
420      * Sets the title text in the top left segment of the PivotGridView
421      * @param {String} title The title
422      */
423     setTitle: function(title) {
424         this.headerTitleEl.child('span').dom.innerHTML = title;
425     },
426     
427     /**
428      * @private
429      * Renders all column header groups at all levels based on the structure fetched from {@link #getColumnHeaders}
430      */
431     renderGroupColumnHeaders: function() {
432         var topAxis = this.grid.topAxis;
433         
434         topAxis.rendered = false;
435         topAxis.render(this.innerHd.firstChild);
436     },
437     
438     /**
439      * @private
440      * Overridden to test whether the user is hovering over a group cell, in which case we don't show the menu
441      */
442     isMenuDisabled: function(cellIndex, el) {
443         return true;
444     }
445 });</pre>    
446 </body>
447 </html>