Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / RowModel.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-selection-RowModel'>/**
19 </span> * @class Ext.selection.RowModel
20  * @extends Ext.selection.Model
21  */
22 Ext.define('Ext.selection.RowModel', {
23     extend: 'Ext.selection.Model',
24     alias: 'selection.rowmodel',
25     requires: ['Ext.util.KeyNav'],
26
27 <span id='Ext-selection-RowModel-property-deltaScroll'>    /**
28 </span>     * @private
29      * Number of pixels to scroll to the left/right when pressing
30      * left/right keys.
31      */
32     deltaScroll: 5,
33
34 <span id='Ext-selection-RowModel-cfg-enableKeyNav'>    /**
35 </span>     * @cfg {Boolean} enableKeyNav
36      *
37      * Turns on/off keyboard navigation within the grid.
38      */
39     enableKeyNav: true,
40     
41 <span id='Ext-selection-RowModel-cfg-ignoreRightMouseSelection'>    /**
42 </span>     * @cfg {Boolean} [ignoreRightMouseSelection=true]
43      * True to ignore selections that are made when using the right mouse button if there are
44      * records that are already selected. If no records are selected, selection will continue 
45      * as normal
46      */
47     ignoreRightMouseSelection: true,
48
49     constructor: function(){
50         this.addEvents(
51 <span id='Ext-selection-RowModel-event-beforedeselect'>            /**
52 </span>             * @event beforedeselect
53              * Fired before a record is deselected. If any listener returns false, the
54              * deselection is cancelled.
55              * @param {Ext.selection.RowModel} this
56              * @param {Ext.data.Model} record The deselected record
57              * @param {Number} index The row index deselected
58              */
59             'beforedeselect',
60
61 <span id='Ext-selection-RowModel-event-beforeselect'>            /**
62 </span>             * @event beforeselect
63              * Fired before a record is selected. If any listener returns false, the
64              * selection is cancelled.
65              * @param {Ext.selection.RowModel} this
66              * @param {Ext.data.Model} record The selected record
67              * @param {Number} index The row index selected
68              */
69             'beforeselect',
70
71 <span id='Ext-selection-RowModel-event-deselect'>            /**
72 </span>             * @event deselect
73              * Fired after a record is deselected
74              * @param {Ext.selection.RowModel} this
75              * @param {Ext.data.Model} record The deselected record
76              * @param {Number} index The row index deselected
77              */
78             'deselect',
79
80 <span id='Ext-selection-RowModel-event-select'>            /**
81 </span>             * @event select
82              * Fired after a record is selected
83              * @param {Ext.selection.RowModel} this
84              * @param {Ext.data.Model} record The selected record
85              * @param {Number} index The row index selected
86              */
87             'select'
88         );
89         this.callParent(arguments);
90     },
91
92     bindComponent: function(view) {
93         var me = this;
94
95         me.views = me.views || [];
96         me.views.push(view);
97         me.bind(view.getStore(), true);
98
99         view.on({
100             itemmousedown: me.onRowMouseDown,
101             scope: me
102         });
103
104         if (me.enableKeyNav) {
105             me.initKeyNav(view);
106         }
107     },
108
109     initKeyNav: function(view) {
110         var me = this;
111
112         if (!view.rendered) {
113             view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true});
114             return;
115         }
116
117         view.el.set({
118             tabIndex: -1
119         });
120
121         // view.el has tabIndex -1 to allow for
122         // keyboard events to be passed to it.
123         me.keyNav = new Ext.util.KeyNav(view.el, {
124             up: me.onKeyUp,
125             down: me.onKeyDown,
126             right: me.onKeyRight,
127             left: me.onKeyLeft,
128             pageDown: me.onKeyPageDown,
129             pageUp: me.onKeyPageUp,
130             home: me.onKeyHome,
131             end: me.onKeyEnd,
132             scope: me
133         });
134         view.el.on(Ext.EventManager.getKeyEvent(), me.onKeyPress, me);
135     },
136
137     // Returns the number of rows currently visible on the screen or
138     // false if there were no rows. This assumes that all rows are
139     // of the same height and the first view is accurate.
140     getRowsVisible: function() {
141         var rowsVisible = false,
142             view = this.views[0],
143             row = view.getNode(0),
144             rowHeight, gridViewHeight;
145
146         if (row) {
147             rowHeight = Ext.fly(row).getHeight();
148             gridViewHeight = view.el.getHeight();
149             rowsVisible = Math.floor(gridViewHeight / rowHeight);
150         }
151
152         return rowsVisible;
153     },
154
155     // go to last visible record in grid.
156     onKeyEnd: function(e, t) {
157         var me = this,
158             last = me.store.getAt(me.store.getCount() - 1);
159
160         if (last) {
161             if (e.shiftKey) {
162                 me.selectRange(last, me.lastFocused || 0);
163                 me.setLastFocused(last);
164             } else if (e.ctrlKey) {
165                 me.setLastFocused(last);
166             } else {
167                 me.doSelect(last);
168             }
169         }
170     },
171
172     // go to first visible record in grid.
173     onKeyHome: function(e, t) {
174         var me = this,
175             first = me.store.getAt(0);
176
177         if (first) {
178             if (e.shiftKey) {
179                 me.selectRange(first, me.lastFocused || 0);
180                 me.setLastFocused(first);
181             } else if (e.ctrlKey) {
182                 me.setLastFocused(first);
183             } else {
184                 me.doSelect(first, false);
185             }
186         }
187     },
188
189     // Go one page up from the lastFocused record in the grid.
190     onKeyPageUp: function(e, t) {
191         var me = this,
192             rowsVisible = me.getRowsVisible(),
193             selIdx,
194             prevIdx,
195             prevRecord,
196             currRec;
197
198         if (rowsVisible) {
199             selIdx = me.lastFocused ? me.store.indexOf(me.lastFocused) : 0;
200             prevIdx = selIdx - rowsVisible;
201             if (prevIdx &lt; 0) {
202                 prevIdx = 0;
203             }
204             prevRecord = me.store.getAt(prevIdx);
205             if (e.shiftKey) {
206                 currRec = me.store.getAt(selIdx);
207                 me.selectRange(prevRecord, currRec, e.ctrlKey, 'up');
208                 me.setLastFocused(prevRecord);
209             } else if (e.ctrlKey) {
210                 e.preventDefault();
211                 me.setLastFocused(prevRecord);
212             } else {
213                 me.doSelect(prevRecord);
214             }
215
216         }
217     },
218
219     // Go one page down from the lastFocused record in the grid.
220     onKeyPageDown: function(e, t) {
221         var me = this,
222             rowsVisible = me.getRowsVisible(),
223             selIdx,
224             nextIdx,
225             nextRecord,
226             currRec;
227
228         if (rowsVisible) {
229             selIdx = me.lastFocused ? me.store.indexOf(me.lastFocused) : 0;
230             nextIdx = selIdx + rowsVisible;
231             if (nextIdx &gt;= me.store.getCount()) {
232                 nextIdx = me.store.getCount() - 1;
233             }
234             nextRecord = me.store.getAt(nextIdx);
235             if (e.shiftKey) {
236                 currRec = me.store.getAt(selIdx);
237                 me.selectRange(nextRecord, currRec, e.ctrlKey, 'down');
238                 me.setLastFocused(nextRecord);
239             } else if (e.ctrlKey) {
240                 // some browsers, this means go thru browser tabs
241                 // attempt to stop.
242                 e.preventDefault();
243                 me.setLastFocused(nextRecord);
244             } else {
245                 me.doSelect(nextRecord);
246             }
247         }
248     },
249
250     // Select/Deselect based on pressing Spacebar.
251     // Assumes a SIMPLE selectionmode style
252     onKeyPress: function(e, t) {
253         if (e.getKey() === e.SPACE) {
254             e.stopEvent();
255             var me = this,
256                 record = me.lastFocused;
257
258             if (record) {
259                 if (me.isSelected(record)) {
260                     me.doDeselect(record, false);
261                 } else {
262                     me.doSelect(record, true);
263                 }
264             }
265         }
266     },
267
268     // Navigate one record up. This could be a selection or
269     // could be simply focusing a record for discontiguous
270     // selection. Provides bounds checking.
271     onKeyUp: function(e, t) {
272         var me = this,
273             view = me.views[0],
274             idx  = me.store.indexOf(me.lastFocused),
275             record;
276
277         if (idx &gt; 0) {
278             // needs to be the filtered count as thats what
279             // will be visible.
280             record = me.store.getAt(idx - 1);
281             if (e.shiftKey &amp;&amp; me.lastFocused) {
282                 if (me.isSelected(me.lastFocused) &amp;&amp; me.isSelected(record)) {
283                     me.doDeselect(me.lastFocused, true);
284                     me.setLastFocused(record);
285                 } else if (!me.isSelected(me.lastFocused)) {
286                     me.doSelect(me.lastFocused, true);
287                     me.doSelect(record, true);
288                 } else {
289                     me.doSelect(record, true);
290                 }
291             } else if (e.ctrlKey) {
292                 me.setLastFocused(record);
293             } else {
294                 me.doSelect(record);
295                 //view.focusRow(idx - 1);
296             }
297         }
298         // There was no lastFocused record, and the user has pressed up
299         // Ignore??
300         //else if (this.selected.getCount() == 0) {
301         //
302         //    this.doSelect(record);
303         //    //view.focusRow(idx - 1);
304         //}
305     },
306
307     // Navigate one record down. This could be a selection or
308     // could be simply focusing a record for discontiguous
309     // selection. Provides bounds checking.
310     onKeyDown: function(e, t) {
311         var me = this,
312             view = me.views[0],
313             idx  = me.store.indexOf(me.lastFocused),
314             record;
315
316         // needs to be the filtered count as thats what
317         // will be visible.
318         if (idx + 1 &lt; me.store.getCount()) {
319             record = me.store.getAt(idx + 1);
320             if (me.selected.getCount() === 0) {
321                 me.doSelect(record);
322                 //view.focusRow(idx + 1);
323             } else if (e.shiftKey &amp;&amp; me.lastFocused) {
324                 if (me.isSelected(me.lastFocused) &amp;&amp; me.isSelected(record)) {
325                     me.doDeselect(me.lastFocused, true);
326                     me.setLastFocused(record);
327                 } else if (!me.isSelected(me.lastFocused)) {
328                     me.doSelect(me.lastFocused, true);
329                     me.doSelect(record, true);
330                 } else {
331                     me.doSelect(record, true);
332                 }
333             } else if (e.ctrlKey) {
334                 me.setLastFocused(record);
335             } else {
336                 me.doSelect(record);
337                 //view.focusRow(idx + 1);
338             }
339         }
340     },
341
342     scrollByDeltaX: function(delta) {
343         var view    = this.views[0],
344             section = view.up(),
345             hScroll = section.horizontalScroller;
346
347         if (hScroll) {
348             hScroll.scrollByDeltaX(delta);
349         }
350     },
351
352     onKeyLeft: function(e, t) {
353         this.scrollByDeltaX(-this.deltaScroll);
354     },
355
356     onKeyRight: function(e, t) {
357         this.scrollByDeltaX(this.deltaScroll);
358     },
359
360     // Select the record with the event included so that
361     // we can take into account ctrlKey, shiftKey, etc
362     onRowMouseDown: function(view, record, item, index, e) {
363         view.el.focus();
364         if (!this.allowRightMouseSelection(e)) {
365             return;
366         }
367         this.selectWithEvent(record, e);
368     },
369     
370 <span id='Ext-selection-RowModel-method-allowRightMouseSelection'>    /**
371 </span>     * Checks whether a selection should proceed based on the ignoreRightMouseSelection
372      * option.
373      * @private
374      * @param {Ext.EventObject} e The event
375      * @return {Boolean} False if the selection should not proceed
376      */
377     allowRightMouseSelection: function(e) {
378         var disallow = this.ignoreRightMouseSelection &amp;&amp; e.button !== 0;
379         if (disallow) {
380             disallow = this.hasSelection();
381         }
382         return !disallow;
383     },
384
385     // Allow the GridView to update the UI by
386     // adding/removing a CSS class from the row.
387     onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
388         var me      = this,
389             views   = me.views,
390             viewsLn = views.length,
391             store   = me.store,
392             rowIdx  = store.indexOf(record),
393             eventName = isSelected ? 'select' : 'deselect',
394             i = 0;
395
396         if ((suppressEvent || me.fireEvent('before' + eventName, me, record, rowIdx)) !== false &amp;&amp;
397                 commitFn() !== false) {
398
399             for (; i &lt; viewsLn; i++) {
400                 if (isSelected) {
401                     views[i].onRowSelect(rowIdx, suppressEvent);
402                 } else {
403                     views[i].onRowDeselect(rowIdx, suppressEvent);
404                 }
405             }
406
407             if (!suppressEvent) {
408                 me.fireEvent(eventName, me, record, rowIdx);
409             }
410         }
411     },
412
413     // Provide indication of what row was last focused via
414     // the gridview.
415     onLastFocusChanged: function(oldFocused, newFocused, supressFocus) {
416         var views   = this.views,
417             viewsLn = views.length,
418             store   = this.store,
419             rowIdx,
420             i = 0;
421
422         if (oldFocused) {
423             rowIdx = store.indexOf(oldFocused);
424             if (rowIdx != -1) {
425                 for (; i &lt; viewsLn; i++) {
426                     views[i].onRowFocus(rowIdx, false);
427                 }
428             }
429         }
430
431         if (newFocused) {
432             rowIdx = store.indexOf(newFocused);
433             if (rowIdx != -1) {
434                 for (i = 0; i &lt; viewsLn; i++) {
435                     views[i].onRowFocus(rowIdx, true, supressFocus);
436                 }
437             }
438         }
439     },
440
441     onEditorTab: function(editingPlugin, e) {
442         var me = this,
443             view = me.views[0],
444             record = editingPlugin.getActiveRecord(),
445             header = editingPlugin.getActiveColumn(),
446             position = view.getPosition(record, header),
447             direction = e.shiftKey ? 'left' : 'right',
448             newPosition  = view.walkCells(position, direction, e, this.preventWrap);
449
450         if (newPosition) {
451             editingPlugin.startEditByPosition(newPosition);
452         }
453     },
454
455     selectByPosition: function(position) {
456         var record = this.store.getAt(position.row);
457         this.select(record);
458     }
459 });</pre>
460 </body>
461 </html>