commit extjs-2.2.1
[extjs.git] / source / util / KeyNav.js
1 /*\r
2  * Ext JS Library 2.2.1\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 /**\r
10  * @class Ext.KeyNav\r
11  * <p>Provides a convenient wrapper for normalized keyboard navigation.  KeyNav allows you to bind\r
12  * navigation keys to function calls that will get called when the keys are pressed, providing an easy\r
13  * way to implement custom navigation schemes for any UI component.</p>\r
14  * <p>The following are all of the possible keys that can be implemented: enter, left, right, up, down, tab, esc,\r
15  * pageUp, pageDown, del, home, end.  Usage:</p>\r
16  <pre><code>\r
17 var nav = new Ext.KeyNav("my-element", {\r
18     "left" : function(e){\r
19         this.moveLeft(e.ctrlKey);\r
20     },\r
21     "right" : function(e){\r
22         this.moveRight(e.ctrlKey);\r
23     },\r
24     "enter" : function(e){\r
25         this.save();\r
26     },\r
27     scope : this\r
28 });\r
29 </code></pre>\r
30  * @constructor\r
31  * @param {Mixed} el The element to bind to\r
32  * @param {Object} config The config\r
33  */\r
34 Ext.KeyNav = function(el, config){\r
35     this.el = Ext.get(el);\r
36     Ext.apply(this, config);\r
37     if(!this.disabled){\r
38         this.disabled = true;\r
39         this.enable();\r
40     }\r
41 };\r
42 \r
43 Ext.KeyNav.prototype = {\r
44     /**\r
45      * @cfg {Boolean} disabled\r
46      * True to disable this KeyNav instance (defaults to false)\r
47      */\r
48     disabled : false,\r
49     /**\r
50      * @cfg {String} defaultEventAction\r
51      * The method to call on the {@link Ext.EventObject} after this KeyNav intercepts a key.  Valid values are\r
52      * {@link Ext.EventObject#stopEvent}, {@link Ext.EventObject#preventDefault} and\r
53      * {@link Ext.EventObject#stopPropagation} (defaults to 'stopEvent')\r
54      */\r
55     defaultEventAction: "stopEvent",\r
56     /**\r
57      * @cfg {Boolean} forceKeyDown\r
58      * Handle the keydown event instead of keypress (defaults to false).  KeyNav automatically does this for IE since\r
59      * IE does not propagate special keys on keypress, but setting this to true will force other browsers to also\r
60      * handle keydown instead of keypress.\r
61      */\r
62     forceKeyDown : false,\r
63 \r
64     // private\r
65     prepareEvent : function(e){\r
66         var k = e.getKey();\r
67         var h = this.keyToHandler[k];\r
68         //if(h && this[h]){\r
69         //    e.stopPropagation();\r
70         //}\r
71         if(Ext.isSafari2 && h && k >= 37 && k <= 40){\r
72             e.stopEvent();\r
73         }\r
74     },\r
75 \r
76     // private\r
77     relay : function(e){\r
78         var k = e.getKey();\r
79         var h = this.keyToHandler[k];\r
80         if(h && this[h]){\r
81             if(this.doRelay(e, this[h], h) !== true){\r
82                 e[this.defaultEventAction]();\r
83             }\r
84         }\r
85     },\r
86 \r
87     // private\r
88     doRelay : function(e, h, hname){\r
89         return h.call(this.scope || this, e);\r
90     },\r
91 \r
92     // possible handlers\r
93     enter : false,\r
94     left : false,\r
95     right : false,\r
96     up : false,\r
97     down : false,\r
98     tab : false,\r
99     esc : false,\r
100     pageUp : false,\r
101     pageDown : false,\r
102     del : false,\r
103     home : false,\r
104     end : false,\r
105 \r
106     // quick lookup hash\r
107     keyToHandler : {\r
108         37 : "left",\r
109         39 : "right",\r
110         38 : "up",\r
111         40 : "down",\r
112         33 : "pageUp",\r
113         34 : "pageDown",\r
114         46 : "del",\r
115         36 : "home",\r
116         35 : "end",\r
117         13 : "enter",\r
118         27 : "esc",\r
119         9  : "tab"\r
120     },\r
121 \r
122         /**\r
123          * Enable this KeyNav\r
124          */\r
125         enable: function(){\r
126                 if(this.disabled){\r
127             if(this.forceKeyDown || Ext.isIE || Ext.isSafari3 || Ext.isAir){\r
128                 this.el.on("keydown", this.relay,  this);\r
129             }else{\r
130                 this.el.on("keydown", this.prepareEvent,  this);\r
131                 this.el.on("keypress", this.relay,  this);\r
132             }\r
133                     this.disabled = false;\r
134                 }\r
135         },\r
136 \r
137         /**\r
138          * Disable this KeyNav\r
139          */\r
140         disable: function(){\r
141                 if(!this.disabled){\r
142                     if(this.forceKeyDown || Ext.isIE || Ext.isSafari3 || Ext.isAir){\r
143                 this.el.un("keydown", this.relay, this);\r
144             }else{\r
145                 this.el.un("keydown", this.prepareEvent, this);\r
146                 this.el.un("keypress", this.relay, this);\r
147             }\r
148                     this.disabled = true;\r
149                 }\r
150         }\r
151 };