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