Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / docs / source / CellSelectionModel.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.CellSelectionModel"></div>/**
16  * @class Ext.grid.CellSelectionModel
17  * @extends Ext.grid.AbstractSelectionModel
18  * This class provides the basic implementation for <i>single</i> <b>cell</b> selection in a grid.
19  * The object stored as the selection contains the following properties:
20  * <div class="mdetail-params"><ul>
21  * <li><b>cell</b> : see {@link #getSelectedCell} 
22  * <li><b>record</b> : Ext.data.record The {@link Ext.data.Record Record}
23  * which provides the data for the row containing the selection</li>
24  * </ul></div>
25  * @constructor
26  * @param {Object} config The object containing the configuration of this model.
27  */
28 Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
29     
30     constructor : function(config){
31         Ext.apply(this, config);
32
33             this.selection = null;
34         
35             this.addEvents(
36                 <div id="event-Ext.grid.CellSelectionModel-beforecellselect"></div>/**
37                  * @event beforecellselect
38                  * Fires before a cell is selected, return false to cancel the selection.
39                  * @param {SelectionModel} this
40                  * @param {Number} rowIndex The selected row index
41                  * @param {Number} colIndex The selected cell index
42                  */
43                 "beforecellselect",
44                 <div id="event-Ext.grid.CellSelectionModel-cellselect"></div>/**
45                  * @event cellselect
46                  * Fires when a cell is selected.
47                  * @param {SelectionModel} this
48                  * @param {Number} rowIndex The selected row index
49                  * @param {Number} colIndex The selected cell index
50                  */
51                 "cellselect",
52                 <div id="event-Ext.grid.CellSelectionModel-selectionchange"></div>/**
53                  * @event selectionchange
54                  * Fires when the active selection changes.
55                  * @param {SelectionModel} this
56                  * @param {Object} selection null for no selection or an object with two properties
57                  * <div class="mdetail-params"><ul>
58                  * <li><b>cell</b> : see {@link #getSelectedCell} 
59                  * <li><b>record</b> : Ext.data.record<p class="sub-desc">The {@link Ext.data.Record Record}
60                  * which provides the data for the row containing the selection</p></li>
61                  * </ul></div>
62                  */
63                 "selectionchange"
64             );
65         
66             Ext.grid.CellSelectionModel.superclass.constructor.call(this);
67     },
68
69     /** @ignore */
70     initEvents : function(){
71         this.grid.on('cellmousedown', this.handleMouseDown, this);
72         this.grid.on(Ext.EventManager.getKeyEvent(), this.handleKeyDown, this);
73         this.grid.getView().on({
74             scope: this,
75             refresh: this.onViewChange,
76             rowupdated: this.onRowUpdated,
77             beforerowremoved: this.clearSelections,
78             beforerowsinserted: this.clearSelections
79         });
80         if(this.grid.isEditor){
81             this.grid.on('beforeedit', this.beforeEdit,  this);
82         }
83     },
84
85         //private
86     beforeEdit : function(e){
87         this.select(e.row, e.column, false, true, e.record);
88     },
89
90         //private
91     onRowUpdated : function(v, index, r){
92         if(this.selection && this.selection.record == r){
93             v.onCellSelect(index, this.selection.cell[1]);
94         }
95     },
96
97         //private
98     onViewChange : function(){
99         this.clearSelections(true);
100     },
101
102         <div id="method-Ext.grid.CellSelectionModel-getSelectedCell"></div>/**
103      * Returns an array containing the row and column indexes of the currently selected cell
104      * (e.g., [0, 0]), or null if none selected. The array has elements:
105      * <div class="mdetail-params"><ul>
106      * <li><b>rowIndex</b> : Number<p class="sub-desc">The index of the selected row</p></li>
107      * <li><b>cellIndex</b> : Number<p class="sub-desc">The index of the selected cell. 
108      * Due to possible column reordering, the cellIndex should <b>not</b> be used as an
109      * index into the Record's data. Instead, use the cellIndex to determine the <i>name</i>
110      * of the selected cell and use the field name to retrieve the data value from the record:<pre><code>
111 // get name
112 var fieldName = grid.getColumnModel().getDataIndex(cellIndex);
113 // get data value based on name
114 var data = record.get(fieldName);
115      * </code></pre></p></li>
116      * </ul></div>
117      * @return {Array} An array containing the row and column indexes of the selected cell, or null if none selected.
118          */
119     getSelectedCell : function(){
120         return this.selection ? this.selection.cell : null;
121     },
122
123     <div id="method-Ext.grid.CellSelectionModel-clearSelections"></div>/**
124      * If anything is selected, clears all selections and fires the selectionchange event.
125      * @param {Boolean} preventNotify <tt>true</tt> to prevent the gridview from
126      * being notified about the change.
127      */
128     clearSelections : function(preventNotify){
129         var s = this.selection;
130         if(s){
131             if(preventNotify !== true){
132                 this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
133             }
134             this.selection = null;
135             this.fireEvent("selectionchange", this, null);
136         }
137     },
138
139     <div id="method-Ext.grid.CellSelectionModel-hasSelection"></div>/**
140      * Returns <tt>true</tt> if there is a selection.
141      * @return {Boolean}
142      */
143     hasSelection : function(){
144         return this.selection ? true : false;
145     },
146
147     /** @ignore */
148     handleMouseDown : function(g, row, cell, e){
149         if(e.button !== 0 || this.isLocked()){
150             return;
151         }
152         this.select(row, cell);
153     },
154
155     <div id="method-Ext.grid.CellSelectionModel-select"></div>/**
156      * Selects a cell.  Before selecting a cell, fires the
157      * {@link #beforecellselect} event.  If this check is satisfied the cell
158      * will be selected and followed up by  firing the {@link #cellselect} and
159      * {@link #selectionchange} events.
160      * @param {Number} rowIndex The index of the row to select
161      * @param {Number} colIndex The index of the column to select
162      * @param {Boolean} preventViewNotify (optional) Specify <tt>true</tt> to
163      * prevent notifying the view (disables updating the selected appearance)
164      * @param {Boolean} preventFocus (optional) Whether to prevent the cell at
165      * the specified rowIndex / colIndex from being focused.
166      * @param {Ext.data.Record} r (optional) The record to select
167      */
168     select : function(rowIndex, colIndex, preventViewNotify, preventFocus, /*internal*/ r){
169         if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
170             this.clearSelections();
171             r = r || this.grid.store.getAt(rowIndex);
172             this.selection = {
173                 record : r,
174                 cell : [rowIndex, colIndex]
175             };
176             if(!preventViewNotify){
177                 var v = this.grid.getView();
178                 v.onCellSelect(rowIndex, colIndex);
179                 if(preventFocus !== true){
180                     v.focusCell(rowIndex, colIndex);
181                 }
182             }
183             this.fireEvent("cellselect", this, rowIndex, colIndex);
184             this.fireEvent("selectionchange", this, this.selection);
185         }
186     },
187
188         //private
189     isSelectable : function(rowIndex, colIndex, cm){
190         return !cm.isHidden(colIndex);
191     },
192     
193     // private
194     onEditorKey: function(field, e){
195         if(e.getKey() == e.TAB){
196             this.handleKeyDown(e);
197         }
198     },
199
200     /** @ignore */
201     handleKeyDown : function(e){
202         if(!e.isNavKeyPress()){
203             return;
204         }
205         
206         var k = e.getKey(),
207             g = this.grid,
208             s = this.selection,
209             sm = this,
210             walk = function(row, col, step){
211                 return g.walkCells(
212                     row,
213                     col,
214                     step,
215                     g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable, // *** handle tabbing while editorgrid is in edit mode
216                     sm
217                 );
218             },
219             cell, newCell, r, c, ae;
220
221         switch(k){
222             case e.ESC:
223             case e.PAGE_UP:
224             case e.PAGE_DOWN:
225                 // do nothing
226                 break;
227             default:
228                 // *** call e.stopEvent() only for non ESC, PAGE UP/DOWN KEYS
229                 e.stopEvent();
230                 break;
231         }
232
233         if(!s){
234             cell = walk(0, 0, 1); // *** use private walk() function defined above
235             if(cell){
236                 this.select(cell[0], cell[1]);
237             }
238             return;
239         }
240
241         cell = s.cell;  // currently selected cell
242         r = cell[0];    // current row
243         c = cell[1];    // current column
244         
245         switch(k){
246             case e.TAB:
247                 if(e.shiftKey){
248                     newCell = walk(r, c - 1, -1);
249                 }else{
250                     newCell = walk(r, c + 1, 1);
251                 }
252                 break;
253             case e.DOWN:
254                 newCell = walk(r + 1, c, 1);
255                 break;
256             case e.UP:
257                 newCell = walk(r - 1, c, -1);
258                 break;
259             case e.RIGHT:
260                 newCell = walk(r, c + 1, 1);
261                 break;
262             case e.LEFT:
263                 newCell = walk(r, c - 1, -1);
264                 break;
265             case e.ENTER:
266                 if (g.isEditor && !g.editing) {
267                     g.startEditing(r, c);
268                     return;
269                 }
270                 break;
271         }
272
273         if(newCell){
274             // *** reassign r & c variables to newly-selected cell's row and column
275             r = newCell[0];
276             c = newCell[1];
277
278             this.select(r, c); // *** highlight newly-selected cell and update selection
279
280             if(g.isEditor && g.editing){ // *** handle tabbing while editorgrid is in edit mode
281                 ae = g.activeEditor;
282                 if(ae && ae.field.triggerBlur){
283                     // *** if activeEditor is a TriggerField, explicitly call its triggerBlur() method
284                     ae.field.triggerBlur();
285                 }
286                 g.startEditing(r, c);
287             }
288         }
289     },
290
291     acceptsNav : function(row, col, cm){
292         return !cm.isHidden(col) && cm.isCellEditable(col, row);
293     }
294 });</pre>    
295 </body>
296 </html>