Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / src / selection / DataViewModel.js
1 /**
2  * @class Ext.selection.DataViewModel
3  * @ignore
4  */
5 Ext.define('Ext.selection.DataViewModel', {
6     extend: 'Ext.selection.Model',
7     
8     requires: ['Ext.util.KeyNav'],
9
10     deselectOnContainerClick: true,
11     
12     /**
13      * @cfg {Boolean} enableKeyNav
14      * 
15      * Turns on/off keyboard navigation within the DataView. Defaults to true.
16      */
17     enableKeyNav: true,
18     
19     constructor: function(cfg){
20         this.addEvents(
21             /**
22              * @event deselect
23              * Fired after a record is deselected
24              * @param {Ext.selection.DataViewModel} this
25              * @param  {Ext.data.Model} record The deselected record
26              */
27             'deselect',
28             
29             /**
30              * @event select
31              * Fired after a record is selected
32              * @param {Ext.selection.DataViewModel} this
33              * @param  {Ext.data.Model} record The selected record
34              */
35             'select'
36         );
37         this.callParent(arguments);
38     },
39     
40     bindComponent: function(view) {
41         var me = this,
42             eventListeners = {
43                 refresh: me.refresh,
44                 scope: me
45             };
46
47         me.view = view;
48         me.bind(view.getStore());
49
50         view.on(view.triggerEvent, me.onItemClick, me);
51         view.on(view.triggerCtEvent, me.onContainerClick, me);
52
53         view.on(eventListeners);
54
55         if (me.enableKeyNav) {
56             me.initKeyNav(view);
57         }
58     },
59
60     onItemClick: function(view, record, item, index, e) {
61         this.selectWithEvent(record, e);
62     },
63
64     onContainerClick: function() {
65         if (this.deselectOnContainerClick) {
66             this.deselectAll();
67         }
68     },
69     
70     initKeyNav: function(view) {
71         var me = this;
72         
73         if (!view.rendered) {
74             view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true});
75             return;
76         }
77         
78         view.el.set({
79             tabIndex: -1
80         });
81         me.keyNav = Ext.create('Ext.util.KeyNav', view.el, {
82             down: Ext.pass(me.onNavKey, [1], me),
83             right: Ext.pass(me.onNavKey, [1], me),
84             left: Ext.pass(me.onNavKey, [-1], me),
85             up: Ext.pass(me.onNavKey, [-1], me),
86             scope: me
87         });
88     },
89     
90     onNavKey: function(step) {
91         step = step || 1;
92         var me = this,
93             view = me.view,
94             selected = me.getSelection()[0],
95             numRecords = me.view.store.getCount(),
96             idx;
97                 
98         if (selected) {
99             idx = view.indexOf(view.getNode(selected)) + step;
100         } else {
101             idx = 0;
102         }
103         
104         if (idx < 0) {
105             idx = numRecords - 1;
106         } else if (idx >= numRecords) {
107             idx = 0;
108         }
109         
110         me.select(idx);
111     },
112
113     // Allow the DataView to update the ui
114     onSelectChange: function(record, isSelected, suppressEvent) {
115         var me = this,
116             view = me.view,
117             allowSelect = true;
118         
119         if (isSelected) {
120             if (!suppressEvent) {
121                 allowSelect = me.fireEvent('beforeselect', me, record) !== false;
122             }
123             if (allowSelect) {
124                 view.onItemSelect(record);
125                 if (!suppressEvent) {
126                     me.fireEvent('select', me, record);
127                 }
128             }
129         } else {
130             view.onItemDeselect(record);
131             if (!suppressEvent) {
132                 me.fireEvent('deselect', me, record);
133             }
134         }
135     }
136 });