Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / selection / DataViewModel.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @class Ext.selection.DataViewModel
17  * @ignore
18  */
19 Ext.define('Ext.selection.DataViewModel', {
20     extend: 'Ext.selection.Model',
21
22     requires: ['Ext.util.KeyNav'],
23
24     deselectOnContainerClick: true,
25
26     /**
27      * @cfg {Boolean} enableKeyNav
28      *
29      * Turns on/off keyboard navigation within the DataView.
30      */
31     enableKeyNav: true,
32
33     constructor: function(cfg){
34         this.addEvents(
35             /**
36              * @event beforedeselect
37              * Fired before a record is deselected. If any listener returns false, the
38              * deselection is cancelled.
39              * @param {Ext.selection.DataViewModel} this
40              * @param {Ext.data.Model} record The deselected record
41              */
42             'beforedeselect',
43
44             /**
45              * @event beforeselect
46              * Fired before a record is selected. If any listener returns false, the
47              * selection is cancelled.
48              * @param {Ext.selection.DataViewModel} this
49              * @param {Ext.data.Model} record The selected record
50              */
51             'beforeselect',
52
53             /**
54              * @event deselect
55              * Fired after a record is deselected
56              * @param {Ext.selection.DataViewModel} this
57              * @param  {Ext.data.Model} record The deselected record
58              */
59             'deselect',
60
61             /**
62              * @event select
63              * Fired after a record is selected
64              * @param {Ext.selection.DataViewModel} this
65              * @param  {Ext.data.Model} record The selected record
66              */
67             'select'
68         );
69         this.callParent(arguments);
70     },
71
72     bindComponent: function(view) {
73         var me = this,
74             eventListeners = {
75                 refresh: me.refresh,
76                 scope: me
77             };
78
79         me.view = view;
80         me.bind(view.getStore());
81
82         view.on(view.triggerEvent, me.onItemClick, me);
83         view.on(view.triggerCtEvent, me.onContainerClick, me);
84
85         view.on(eventListeners);
86
87         if (me.enableKeyNav) {
88             me.initKeyNav(view);
89         }
90     },
91
92     onItemClick: function(view, record, item, index, e) {
93         this.selectWithEvent(record, e);
94     },
95
96     onContainerClick: function() {
97         if (this.deselectOnContainerClick) {
98             this.deselectAll();
99         }
100     },
101
102     initKeyNav: function(view) {
103         var me = this;
104
105         if (!view.rendered) {
106             view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true});
107             return;
108         }
109
110         view.el.set({
111             tabIndex: -1
112         });
113         me.keyNav = Ext.create('Ext.util.KeyNav', view.el, {
114             down: Ext.pass(me.onNavKey, [1], me),
115             right: Ext.pass(me.onNavKey, [1], me),
116             left: Ext.pass(me.onNavKey, [-1], me),
117             up: Ext.pass(me.onNavKey, [-1], me),
118             scope: me
119         });
120     },
121
122     onNavKey: function(step) {
123         step = step || 1;
124         var me = this,
125             view = me.view,
126             selected = me.getSelection()[0],
127             numRecords = me.view.store.getCount(),
128             idx;
129
130         if (selected) {
131             idx = view.indexOf(view.getNode(selected)) + step;
132         } else {
133             idx = 0;
134         }
135
136         if (idx < 0) {
137             idx = numRecords - 1;
138         } else if (idx >= numRecords) {
139             idx = 0;
140         }
141
142         me.select(idx);
143     },
144
145     // Allow the DataView to update the ui
146     onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
147         var me = this,
148             view = me.view,
149             eventName = isSelected ? 'select' : 'deselect';
150
151         if ((suppressEvent || me.fireEvent('before' + eventName, me, record)) !== false &&
152                 commitFn() !== false) {
153
154             if (isSelected) {
155                 view.onItemSelect(record);
156             } else {
157                 view.onItemDeselect(record);
158             }
159
160             if (!suppressEvent) {
161                 me.fireEvent(eventName, me, record);
162             }
163         }
164     },
165     
166     destroy: function(){
167         Ext.destroy(this.keyNav);
168         this.callParent();
169     }
170 });
171