Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / src / selection / TreeModel.js
1 /**
2  * @class Ext.selection.TreeModel
3  * @extends Ext.selection.RowModel
4  *
5  * Adds custom behavior for left/right keyboard navigation for use with a tree.
6  * Depends on the view having an expand and collapse method which accepts a
7  * record.
8  * 
9  * @private
10  */
11 Ext.define('Ext.selection.TreeModel', {
12     extend: 'Ext.selection.RowModel',
13     alias: 'selection.treemodel',
14     
15     // typically selection models prune records from the selection
16     // model when they are removed, because the TreeView constantly
17     // adds/removes records as they are expanded/collapsed
18     pruneRemoved: false,
19     
20     onKeyRight: function(e, t) {
21         var focused = this.getLastFocused(),
22             view    = this.view;
23             
24         if (focused) {
25             // tree node is already expanded, go down instead
26             // this handles both the case where we navigate to firstChild and if
27             // there are no children to the nextSibling
28             if (focused.isExpanded()) {
29                 this.onKeyDown(e, t);
30             // if its not a leaf node, expand it
31             } else if (!focused.isLeaf()) {
32                 view.expand(focused);
33             }
34         }
35     },
36     
37     onKeyLeft: function(e, t) {
38         var focused = this.getLastFocused(),
39             view    = this.view,
40             viewSm  = view.getSelectionModel(),
41             parentNode, parentRecord;
42
43         if (focused) {
44             parentNode = focused.parentNode;
45             // if focused node is already expanded, collapse it
46             if (focused.isExpanded()) {
47                 view.collapse(focused);
48             // has a parentNode and its not root
49             // TODO: this needs to cover the case where the root isVisible
50             } else if (parentNode && !parentNode.isRoot()) {
51                 // Select a range of records when doing multiple selection.
52                 if (e.shiftKey) {
53                     viewSm.selectRange(parentNode, focused, e.ctrlKey, 'up');
54                     viewSm.setLastFocused(parentNode);
55                 // just move focus, not selection
56                 } else if (e.ctrlKey) {
57                     viewSm.setLastFocused(parentNode);
58                 // select it
59                 } else {
60                     viewSm.select(parentNode);
61                 }
62             }
63         }
64     },
65     
66     onKeyPress: function(e, t) {
67         var selected, checked;
68         
69         if (e.getKey() === e.SPACE || e.getKey() === e.ENTER) {
70             e.stopEvent();
71             selected = this.getLastSelected();
72             if (selected && selected.isLeaf()) {
73                 checked = selected.get('checked');
74                 if (Ext.isBoolean(checked)) {
75                     selected.set('checked', !checked);
76                 }
77             }
78         } else {
79             this.callParent(arguments);
80         }
81     }
82 });