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