source: trunk/web/addons/job_monarch/lib/extjs-30/src/util/KeyMap.js @ 625

Last change on this file since 625 was 625, checked in by ramonb, 15 years ago

lib/extjs-30:

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