Upgrade to ExtJS 3.2.0 - Released 03/30/2010
[extjs.git] / docs / source / KeyMap.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.2.0
11  * Copyright(c) 2006-2010 Ext JS, Inc.
12  * licensing@extjs.com
13  * http://www.extjs.com/license
14  */
15 <div id="cls-Ext.KeyMap"></div>/**
16  * @class Ext.KeyMap
17  * Handles mapping keys to actions for an element. One key map can be used for multiple actions.
18  * The constructor accepts the same config object as defined by {@link #addBinding}.
19  * If you bind a callback function to a KeyMap, anytime the KeyMap handles an expected key
20  * combination it will call the function with this signature (if the match is a multi-key
21  * combination the callback will still be called only once): (String key, Ext.EventObject e)
22  * A KeyMap can also handle a string representation of keys.<br />
23  * Usage:
24  <pre><code>
25 // map one key by key code
26 var map = new Ext.KeyMap("my-element", {
27     key: 13, // or Ext.EventObject.ENTER
28     fn: myHandler,
29     scope: myObject
30 });
31
32 // map multiple keys to one action by string
33 var map = new Ext.KeyMap("my-element", {
34     key: "a\r\n\t",
35     fn: myHandler,
36     scope: myObject
37 });
38
39 // map multiple keys to multiple actions by strings and array of codes
40 var map = new Ext.KeyMap("my-element", [
41     {
42         key: [10,13],
43         fn: function(){ alert("Return was pressed"); }
44     }, {
45         key: "abc",
46         fn: function(){ alert('a, b or c was pressed'); }
47     }, {
48         key: "\t",
49         ctrl:true,
50         shift:true,
51         fn: function(){ alert('Control + shift + tab was pressed.'); }
52     }
53 ]);
54 </code></pre>
55  * <b>Note: A KeyMap starts enabled</b>
56  * @constructor
57  * @param {Mixed} el The element to bind to
58  * @param {Object} config The config (see {@link #addBinding})
59  * @param {String} eventName (optional) The event to bind to (defaults to "keydown")
60  */
61 Ext.KeyMap = function(el, config, eventName){
62     this.el  = Ext.get(el);
63     this.eventName = eventName || "keydown";
64     this.bindings = [];
65     if(config){
66         this.addBinding(config);
67     }
68     this.enable();
69 };
70
71 Ext.KeyMap.prototype = {
72     <div id="prop-Ext.KeyMap-stopEvent"></div>/**
73      * True to stop the event from bubbling and prevent the default browser action if the
74      * key was handled by the KeyMap (defaults to false)
75      * @type Boolean
76      */
77     stopEvent : false,
78
79     <div id="method-Ext.KeyMap-addBinding"></div>/**
80      * Add a new binding to this KeyMap. The following config object properties are supported:
81      * <pre>
82 Property    Type             Description
83 ----------  ---------------  ----------------------------------------------------------------------
84 key         String/Array     A single keycode or an array of keycodes to handle
85 shift       Boolean          True to handle key only when shift is pressed, False to handle the key only when shift is not pressed (defaults to undefined)
86 ctrl        Boolean          True to handle key only when ctrl is pressed, False to handle the key only when ctrl is not pressed (defaults to undefined)
87 alt         Boolean          True to handle key only when alt is pressed, False to handle the key only when alt is not pressed (defaults to undefined)
88 handler     Function         The function to call when KeyMap finds the expected key combination
89 fn          Function         Alias of handler (for backwards-compatibility)
90 scope       Object           The scope of the callback function
91 stopEvent   Boolean          True to stop the event from bubbling and prevent the default browser action if the key was handled by the KeyMap (defaults to false)
92 </pre>
93      *
94      * Usage:
95      * <pre><code>
96 // Create a KeyMap
97 var map = new Ext.KeyMap(document, {
98     key: Ext.EventObject.ENTER,
99     fn: handleKey,
100     scope: this
101 });
102
103 //Add a new binding to the existing KeyMap later
104 map.addBinding({
105     key: 'abc',
106     shift: true,
107     fn: handleKey,
108     scope: this
109 });
110 </code></pre>
111      * @param {Object/Array} config A single KeyMap config or an array of configs
112      */
113         addBinding : function(config){
114         if(Ext.isArray(config)){
115             Ext.each(config, function(c){
116                 this.addBinding(c);
117             }, this);
118             return;
119         }
120         var keyCode = config.key,
121             fn = config.fn || config.handler,
122             scope = config.scope;
123
124         if (config.stopEvent) {
125             this.stopEvent = config.stopEvent;    
126         }       
127
128         if(typeof keyCode == "string"){
129             var ks = [];
130             var keyString = keyCode.toUpperCase();
131             for(var j = 0, len = keyString.length; j < len; j++){
132                 ks.push(keyString.charCodeAt(j));
133             }
134             keyCode = ks;
135         }
136         var keyArray = Ext.isArray(keyCode);
137         
138         var handler = function(e){
139             if(this.checkModifiers(config, e)){
140                 var k = e.getKey();
141                 if(keyArray){
142                     for(var i = 0, len = keyCode.length; i < len; i++){
143                         if(keyCode[i] == k){
144                           if(this.stopEvent){
145                               e.stopEvent();
146                           }
147                           fn.call(scope || window, k, e);
148                           return;
149                         }
150                     }
151                 }else{
152                     if(k == keyCode){
153                         if(this.stopEvent){
154                            e.stopEvent();
155                         }
156                         fn.call(scope || window, k, e);
157                     }
158                 }
159             }
160         };
161         this.bindings.push(handler);
162         },
163     
164     // private
165     checkModifiers: function(config, e){
166         var val, key, keys = ['shift', 'ctrl', 'alt'];
167         for (var i = 0, len = keys.length; i < len; ++i){
168             key = keys[i];
169             val = config[key];
170             if(!(val === undefined || (val === e[key + 'Key']))){
171                 return false;
172             }
173         }
174         return true;
175     },
176
177     <div id="method-Ext.KeyMap-on"></div>/**
178      * Shorthand for adding a single key listener
179      * @param {Number/Array/Object} key Either the numeric key code, array of key codes or an object with the
180      * following options:
181      * {key: (number or array), shift: (true/false), ctrl: (true/false), alt: (true/false)}
182      * @param {Function} fn The function to call
183      * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to the browser window.
184      */
185     on : function(key, fn, scope){
186         var keyCode, shift, ctrl, alt;
187         if(typeof key == "object" && !Ext.isArray(key)){
188             keyCode = key.key;
189             shift = key.shift;
190             ctrl = key.ctrl;
191             alt = key.alt;
192         }else{
193             keyCode = key;
194         }
195         this.addBinding({
196             key: keyCode,
197             shift: shift,
198             ctrl: ctrl,
199             alt: alt,
200             fn: fn,
201             scope: scope
202         });
203     },
204
205     // private
206     handleKeyDown : function(e){
207             if(this.enabled){ //just in case
208             var b = this.bindings;
209             for(var i = 0, len = b.length; i < len; i++){
210                 b[i].call(this, e);
211             }
212             }
213         },
214
215         <div id="method-Ext.KeyMap-isEnabled"></div>/**
216          * Returns true if this KeyMap is enabled
217          * @return {Boolean}
218          */
219         isEnabled : function(){
220             return this.enabled;
221         },
222
223         <div id="method-Ext.KeyMap-enable"></div>/**
224          * Enables this KeyMap
225          */
226         enable: function(){
227                 if(!this.enabled){
228                     this.el.on(this.eventName, this.handleKeyDown, this);
229                     this.enabled = true;
230                 }
231         },
232
233         <div id="method-Ext.KeyMap-disable"></div>/**
234          * Disable this KeyMap
235          */
236         disable: function(){
237                 if(this.enabled){
238                     this.el.removeListener(this.eventName, this.handleKeyDown, this);
239                     this.enabled = false;
240                 }
241         },
242     
243     <div id="method-Ext.KeyMap-setDisabled"></div>/**
244      * Convenience function for setting disabled/enabled by boolean.
245      * @param {Boolean} disabled
246      */
247     setDisabled : function(disabled){
248         this[disabled ? "disable" : "enable"]();
249     }
250 };</pre>    
251 </body>
252 </html>