KeyNav.html 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-util-KeyNav'>/**
  19. </span> * Provides a convenient wrapper for normalized keyboard navigation. KeyNav allows you to bind navigation keys to
  20. * function calls that will get called when the keys are pressed, providing an easy way to implement custom navigation
  21. * schemes for any UI component.
  22. *
  23. * The following are all of the possible keys that can be implemented: enter, space, left, right, up, down, tab, esc,
  24. * pageUp, pageDown, del, backspace, home, end.
  25. *
  26. * Usage:
  27. *
  28. * var nav = new Ext.util.KeyNav({
  29. * target : &quot;my-element&quot;,
  30. * left : function(e){
  31. * this.moveLeft(e.ctrlKey);
  32. * },
  33. * right : function(e){
  34. * this.moveRight(e.ctrlKey);
  35. * },
  36. * enter : function(e){
  37. * this.save();
  38. * },
  39. *
  40. * // Binding may be a function specifiying fn, scope and defaultAction
  41. * esc: {
  42. * fn: this.onEsc,
  43. * defaultEventAction: false
  44. * },
  45. * scope : this
  46. * });
  47. */
  48. Ext.define('Ext.util.KeyNav', {
  49. alternateClassName: 'Ext.KeyNav',
  50. requires: ['Ext.util.KeyMap'],
  51. statics: {
  52. keyOptions: {
  53. left: 37,
  54. right: 39,
  55. up: 38,
  56. down: 40,
  57. space: 32,
  58. pageUp: 33,
  59. pageDown: 34,
  60. del: 46,
  61. backspace: 8,
  62. home: 36,
  63. end: 35,
  64. enter: 13,
  65. esc: 27,
  66. tab: 9
  67. }
  68. },
  69. constructor: function(config) {
  70. var me = this;
  71. if (arguments.length === 2) {
  72. me.legacyConstructor.apply(me, arguments);
  73. return;
  74. }
  75. me.setConfig(config);
  76. },
  77. <span id='Ext-util-KeyNav-method-legacyConstructor'> /**
  78. </span> * @private
  79. * Old constructor signature.
  80. * @param {String/HTMLElement/Ext.Element} el The element or its ID to bind to
  81. * @param {Object} config The config
  82. */
  83. legacyConstructor: function(el, config) {
  84. this.setConfig(Ext.apply({
  85. target: el
  86. }, config));
  87. },
  88. <span id='Ext-util-KeyNav-method-setConfig'> /**
  89. </span> * Sets up a configuration for the KeyNav.
  90. * @private
  91. * @param {String/HTMLElement/Ext.Element} el The element or its ID to bind to
  92. * @param {Object} config A configuration object as specified in the constructor.
  93. */
  94. setConfig: function(config) {
  95. var me = this,
  96. keymapCfg = {
  97. target: config.target,
  98. ignoreInputFields: config.ignoreInputFields,
  99. eventName: me.getKeyEvent('forceKeyDown' in config ? config.forceKeyDown : me.forceKeyDown, config.eventName)
  100. },
  101. map, keyCodes, defaultScope, keyName, binding;
  102. if (me.map) {
  103. me.map.destroy();
  104. }
  105. if (config.processEvent) {
  106. keymapCfg.processEvent = config.processEvent;
  107. keymapCfg.processEventScope = config.processEventScope||me;
  108. }
  109. map = me.map = new Ext.util.KeyMap(keymapCfg);
  110. keyCodes = Ext.util.KeyNav.keyOptions;
  111. defaultScope = config.scope || me;
  112. for (keyName in keyCodes) {
  113. if (keyCodes.hasOwnProperty(keyName)) {
  114. // There is a property named after a key name.
  115. // It may be a function or an binding spec containing handler, scope and defaultAction configs
  116. if (binding = config[keyName]) {
  117. if (typeof binding === 'function') {
  118. binding = {
  119. handler: binding,
  120. defaultAction: (config.defaultEventAction !== undefined) ? config.defaultEventAction : me.defaultEventAction
  121. };
  122. }
  123. map.addBinding({
  124. key: keyCodes[keyName],
  125. handler: Ext.Function.bind(me.handleEvent, binding.scope||defaultScope, binding.handler||binding.fn, true),
  126. defaultEventAction: (binding.defaultEventAction !== undefined) ? binding.defaultAction : me.defaultEventAction
  127. });
  128. }
  129. }
  130. }
  131. map.disable();
  132. if (!config.disabled) {
  133. map.enable();
  134. }
  135. },
  136. <span id='Ext-util-KeyNav-method-handleEvent'> /**
  137. </span> * Method for filtering out the map argument
  138. * @private
  139. * @param {Number} keyCode
  140. * @param {Ext.EventObject} event
  141. * @param {Object} options Contains the handler to call
  142. */
  143. handleEvent: function(keyCode, event, handler){
  144. return handler.call(this, event);
  145. },
  146. <span id='Ext-util-KeyNav-cfg-disabled'> /**
  147. </span> * @cfg {Boolean} disabled
  148. * True to disable this KeyNav instance.
  149. */
  150. disabled: false,
  151. <span id='Ext-util-KeyNav-cfg-defaultEventAction'> /**
  152. </span> * @cfg {String} defaultEventAction
  153. * The method to call on the {@link Ext.EventObject} after this KeyNav intercepts a key. Valid values are {@link
  154. * Ext.EventObject#stopEvent}, {@link Ext.EventObject#preventDefault} and {@link Ext.EventObject#stopPropagation}.
  155. *
  156. * If a falsy value is specified, no method is called on the key event.
  157. */
  158. defaultEventAction: &quot;stopEvent&quot;,
  159. <span id='Ext-util-KeyNav-cfg-forceKeyDown'> /**
  160. </span> * @cfg {Boolean} forceKeyDown
  161. * Handle the keydown event instead of keypress. KeyNav automatically does this for IE since IE does not propagate
  162. * special keys on keypress, but setting this to true will force other browsers to also handle keydown instead of
  163. * keypress.
  164. */
  165. forceKeyDown: false,
  166. <span id='Ext-util-KeyNav-cfg-target'> /**
  167. </span> * @cfg {Ext.Component/Ext.Element/HTMLElement/String} target
  168. * The object on which to listen for the event specified by the {@link #eventName} config option.
  169. */
  170. <span id='Ext-util-KeyNav-cfg-eventName'> /**
  171. </span> * @cfg {String} eventName
  172. * The event to listen for to pick up key events.
  173. */
  174. eventName: 'keypress',
  175. <span id='Ext-util-KeyNav-cfg-processEvent'> /**
  176. </span> * @cfg {Function} processEvent
  177. * An optional event processor function which accepts the argument list provided by the {@link #eventName configured
  178. * event} of the {@link #target}, and returns a keyEvent for processing by the KeyMap.
  179. *
  180. * This may be useful when the {@link #target} is a Component with s complex event signature. Extra information from
  181. * the event arguments may be injected into the event for use by the handler functions before returning it.
  182. */
  183. <span id='Ext-util-KeyNav-cfg-processEventScope'> /**
  184. </span> * @cfg {Object} [processEventScope=this]
  185. * The scope (`this` context) in which the {@link #processEvent} method is executed.
  186. */
  187. <span id='Ext-util-KeyNav-cfg-ignoreInputFields'> /**
  188. </span> * @cfg {Boolean} [ignoreInputFields=false]
  189. * Configure this as `true` if there are any input fields within the {@link #target}, and this KeyNav
  190. * should not process events from input fields, (`&amp;lt;input&gt;, &amp;lt;textarea&gt; and elements with `contentEditable=&quot;true&quot;`)
  191. */
  192. <span id='Ext-util-KeyNav-method-destroy'> /**
  193. </span> * Destroy this KeyNav (this is the same as calling disable).
  194. * @param {Boolean} removeEl True to remove the element associated with this KeyNav.
  195. */
  196. destroy: function(removeEl) {
  197. this.map.destroy(removeEl);
  198. delete this.map;
  199. },
  200. <span id='Ext-util-KeyNav-method-enable'> /**
  201. </span> * Enables this KeyNav.
  202. */
  203. enable: function() {
  204. this.map.enable();
  205. this.disabled = false;
  206. },
  207. <span id='Ext-util-KeyNav-method-disable'> /**
  208. </span> * Disables this KeyNav.
  209. */
  210. disable: function() {
  211. this.map.disable();
  212. this.disabled = true;
  213. },
  214. <span id='Ext-util-KeyNav-method-setDisabled'> /**
  215. </span> * Convenience function for setting disabled/enabled by boolean.
  216. * @param {Boolean} disabled
  217. */
  218. setDisabled : function(disabled) {
  219. this.map.setDisabled(disabled);
  220. this.disabled = disabled;
  221. },
  222. <span id='Ext-util-KeyNav-method-getKeyEvent'> /**
  223. </span> * @private
  224. * Determines the event to bind to listen for keys. Defaults to the {@link #eventName} value, but
  225. * may be overridden the {@link #forceKeyDown} setting.
  226. *
  227. * The useKeyDown option on the EventManager modifies the default {@link #eventName} to be `keydown`,
  228. * but a configured {@link #eventName} takes priority over this.
  229. *
  230. * @return {String} The type of event to listen for.
  231. */
  232. getKeyEvent: function(forceKeyDown, configuredEventName) {
  233. if (forceKeyDown || (Ext.EventManager.useKeyDown &amp;&amp; !configuredEventName)) {
  234. return 'keydown';
  235. } else {
  236. return configuredEventName||this.eventName;
  237. }
  238. }
  239. });</pre>
  240. </body>
  241. </html>