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