jquery-keypad-rails 1.5.1 → 2.0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZDZhZWUxY2RmZGZlOTNjYWNkMzA2Yjg0OGE3OTIwZTM2ZWUwYjc1OA==
4
+ YjNlZjYyZmZmYzcwYjkyZWI4ZmJmNmFlMWQ3NjQ0NjI4MTdjNzk0MQ==
5
5
  data.tar.gz: !binary |-
6
- ZDBjOTg5MzM2NzgxMDdlZWM4MjJmOWMyMjExNDllYzBjMDc5NmFiYw==
6
+ ZmNhMGJkZDRkMGIwMTA1YjIzYWE3OWE0ZWQ0YWRjZGQyNDMyMzgyZg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YmU3YmQ2MDE5OWU4NmFkMTQzMDU1MzI2MmU5OWFiMTdiZjcxMTk1ZTUyOTg1
10
- YTZjZjBkYmM4MWEzN2I1M2ExYzYyYTFiOGE0MzFlN2U3ZjNjZTI5YWFmYWIw
11
- ZTgwZjYxY2RhNjU3ZDBjNGEzNjU2YzEzNGQ1YjY3N2RjZjQ2Mzg=
9
+ YjgxMmQ1Zjg5YTY4OGY2YzUwZTY5NjUyYjdkYTkyZWVmZjY0ZTIzNGQ1MDAw
10
+ ZmU1NGVjNDE4OTdlYTk3NTNmMzgxMzQ3ZmM4MTAwNzVjMmY1MDJhZTAzY2Rl
11
+ NmUzOTgxYzY0YzNlYjdiYWYwYTVkOTcwNzMwZjFjOTdjMjA2NWI=
12
12
  data.tar.gz: !binary |-
13
- ZWQ1MGZhZDM4Mjc3NTJhN2E3ZGU2MzM4ZGNkNjI2ZjAyMmE0N2I1ZTBjMWE2
14
- OWQwMzQ5ODgwYjViOTc3MmE1N2ZiYjVhNjgxZmE5ZDc5NmNiZGI4YmMxN2Yz
15
- OGNiYTViNzMyMTkyMzFkZDZhN2Q3MWY4MGY0NzBiMmJjMzc1YWE=
13
+ ZjRmZGViNzAyNjIwZTM4ZmQ2ODdhMTZhZjE0MzAwMmY0NDU4NDZjZWNkMmJh
14
+ MzI3MzQ5N2JlODdkNzAyZWFiNTc3OTI5ZDA4MmM1Y2MzODlhZGFmYmNmZTQx
15
+ ODMzZjE5OTNjMTRkNGRmYjUzMjY0NjQ2M2JkNjEyZjM2OTY5NzA=
data/README.md CHANGED
@@ -20,7 +20,11 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- No helpers at this time, maybe in the future or from a contributor?
23
+ Add to your 'application.js'
24
+
25
+ //= require jquery.plugin
26
+ //= require jquery.keypad
27
+
24
28
 
25
29
  ## Contributing
26
30
 
data/build.me CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/bin/bash
2
2
 
3
- VER=1.5.1
3
+ VER=2.0.0
4
+ REV=.1
4
5
 
5
6
  rm build/*
6
7
  pushd build
@@ -19,13 +20,15 @@ cat >lib/jquery/keypad/rails/version.rb <<EOF
19
20
  module Jquery
20
21
  module Keypad
21
22
  module Rails
22
- VERSION = "${VER}"
23
+ VERSION = "${VER}${REV}"
23
24
  end
24
25
  end
25
26
  end
26
27
  EOF
27
28
 
29
+ git commit -a
30
+
28
31
  gem update --system
29
32
  gem build jquery-keypad-rails.gemspec
30
- gem push jquery-keypad-rails-${VER}.gem
33
+ # gem push jquery-keypad-rails-${VER}.gem
31
34
 
@@ -17,6 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
+ spec.add_runtime_dependency 'jquery-plugins-rails', '~> 0.2', '>= 0.2.1'
20
21
 
21
22
  spec.add_development_dependency "bundler", "~> 1.3"
22
23
  spec.add_development_dependency "rake"
@@ -1,7 +1,7 @@
1
1
  module Jquery
2
2
  module Keypad
3
3
  module Rails
4
- VERSION = "1.5.1"
4
+ VERSION = "2.0.0.1"
5
5
  end
6
6
  end
7
7
  end
@@ -2,7 +2,7 @@
2
2
  Catalan initialisation for the jQuery keypad extension
3
3
  Written by Ignasi Nogues (inogues@clickartedu.com). */
4
4
  (function($) { // hide the namespace
5
- $.keypad.regional['ca'] = {
5
+ $.keypad.regionalOptions['ca'] = {
6
6
  buttonText: '...', buttonStatus: 'Obrir el teclat',
7
7
  closeText: 'Tancar', closeStatus: 'Tancar el teclat',
8
8
  clearText: 'Netejar', clearStatus: 'Eliminar tot el text',
@@ -17,5 +17,5 @@
17
17
  isNumeric: $.keypad.isNumeric,
18
18
  toUpper: $.keypad.toUpper,
19
19
  isRTL: false};
20
- $.keypad.setDefaults($.keypad.regional['ca']);
20
+ $.keypad.setDefaults($.keypad.regionalOptions['ca']);
21
21
  })(jQuery);
@@ -2,7 +2,7 @@
2
2
  Czech initialisation for the jQuery keypad extension
3
3
  Written by Amadeo Mareš. */
4
4
  (function($) { // hide the namespace
5
- $.keypad.regional['cs'] = {
5
+ $.keypad.regionalOptions['cs'] = {
6
6
  buttonText: '...', buttonStatus: 'Otevřít',
7
7
  closeText: 'Zavřít', closeStatus: 'Zavře klávesnici',
8
8
  clearText: 'Vymazat', clearStatus: 'Smaže text',
@@ -17,5 +17,5 @@
17
17
  isNumeric: $.keypad.isNumeric,
18
18
  toUpper: $.keypad.toUpper,
19
19
  isRTL: false};
20
- $.keypad.setDefaults($.keypad.regional['cs']);
20
+ $.keypad.setDefaults($.keypad.regionalOptions['cs']);
21
21
  })(jQuery);
@@ -16,7 +16,7 @@
16
16
  $.keypad.SHIFT + $.keypad.SPACE + $.keypad.SPACE_BAR +
17
17
  $.keypad.SPACE + $.keypad.SPACE + $.keypad.SPACE + $.keypad.CLEAR +
18
18
  $.keypad.SPACE + $.keypad.SPACE + $.keypad.HALF_SPACE + $.keypad.CLOSE];
19
- $.keypad.regional['de'] = {
19
+ $.keypad.regionalOptions['de'] = {
20
20
  buttonText: '...', buttonStatus: 'Öffnen',
21
21
  closeText: 'schließen', closeStatus: 'schließen',
22
22
  clearText: 'löschen', clearStatus: 'Gesamten Inhalt löschen',
@@ -31,6 +31,6 @@
31
31
  isNumeric: $.keypad.isNumeric,
32
32
  toUpper: $.keypad.toUpper,
33
33
  isRTL: false};
34
- $.keypad.setDefaults($.keypad.regional['de']);
34
+ $.keypad.setDefaults($.keypad.regionalOptions['de']);
35
35
 
36
36
  })(jQuery);
@@ -2,7 +2,7 @@
2
2
  Spanish initialisation for the jQuery keypad extension
3
3
  Written by Cristhian Benitez (cbenitez@gmail.com). */
4
4
  (function($) { // hide the namespace
5
- $.keypad.regional['es'] = {
5
+ $.keypad.regionalOptions['es'] = {
6
6
  buttonText: '...', buttonStatus: 'Abrir el teclado',
7
7
  closeText: 'Cerrar', closeStatus: 'Cerrar el teclado',
8
8
  clearText: 'Limpiar', clearStatus: 'Eliminar todo el texto',
@@ -17,5 +17,5 @@
17
17
  isNumeric: $.keypad.isNumeric,
18
18
  toUpper: $.keypad.toUpper,
19
19
  isRTL: false};
20
- $.keypad.setDefaults($.keypad.regional['es']);
20
+ $.keypad.setDefaults($.keypad.regionalOptions['es']);
21
21
  })(jQuery);
@@ -12,7 +12,7 @@
12
12
  '§' + $.keypad.azertyAlphabetic[3] + ',.;:' + $.keypad.HALF_SPACE + '-0+',
13
13
  $.keypad.SHIFT + $.keypad.SPACE_BAR + $.keypad.HALF_SPACE +
14
14
  $.keypad.BACK + $.keypad.CLEAR + $.keypad.CLOSE];
15
- $.keypad.regional['fr'] = {
15
+ $.keypad.regionalOptions['fr'] = {
16
16
  buttonText: '...', buttonStatus: 'Ouvrir',
17
17
  closeText: 'Fermer', closeStatus: 'Fermer le pavé numérique',
18
18
  clearText: 'Effacer', clearStatus: 'Effacer la valeur',
@@ -27,7 +27,7 @@
27
27
  isNumeric: $.keypad.isNumeric,
28
28
  toUpper: $.keypad.toUpper,
29
29
  isRTL: false};
30
- $.keypad.setDefaults($.keypad.regional['fr']);
30
+ $.keypad.setDefaults($.keypad.regionalOptions['fr']);
31
31
 
32
32
  function isAlphabetic(ch) {
33
33
  return ($.keypad.isAlphabetic(ch) ||
@@ -2,7 +2,7 @@
2
2
  Italian initialisation for the jQuery keypad extension
3
3
  Written by Francesco Strappini (www.strx.it). */
4
4
  (function($) { // hide the namespace
5
- $.keypad.regional['it'] = {
5
+ $.keypad.regionalOptions['it'] = {
6
6
  buttonText: '...', buttonStatus: 'Visualizza Tastiera',
7
7
  closeText: 'Chiudi', closeStatus: 'Nascondi Tastiera',
8
8
  clearText: 'Pulisci', clearStatus: 'Elimina il Testo',
@@ -17,5 +17,5 @@
17
17
  isNumeric: $.keypad.isNumeric,
18
18
  toUpper: $.keypad.toUpper,
19
19
  isRTL: false};
20
- $.keypad.setDefaults($.keypad.regional['it']);
20
+ $.keypad.setDefaults($.keypad.regionalOptions['it']);
21
21
  })(jQuery);
@@ -2,7 +2,7 @@
2
2
  dutch initialisation for the jQuery keypad extension
3
3
  Written by Michiel Mussies (mail{at}webcrafts.nl) November 2009. */
4
4
  (function($) { // hide the namespace
5
- $.keypad.regional['nl'] = {
5
+ $.keypad.regionalOptions['nl'] = {
6
6
  buttonText: '...', buttonStatus: 'Open',
7
7
  closeText: 'Sluit', closeStatus: 'Sluit',
8
8
  clearText: 'Wissen', clearStatus: 'Wis alle tekens',
@@ -17,5 +17,5 @@
17
17
  isNumeric: $.keypad.isNumeric,
18
18
  toUpper: $.keypad.toUpper,
19
19
  isRTL: false};
20
- $.keypad.setDefaults($.keypad.regional['nl']);
20
+ $.keypad.setDefaults($.keypad.regionalOptions['nl']);
21
21
  })(jQuery);
@@ -2,7 +2,7 @@
2
2
  brazilian portuguese initialisation for the jQuery keypad extension
3
3
  Written by Israel Rodriguez (yzraeu{at}gmail.com) July 2009. */
4
4
  (function($) { // hide the namespace
5
- $.keypad.regional['pt-BR'] = {
5
+ $.keypad.regionalOptions['pt-BR'] = {
6
6
  buttonText: '...', buttonStatus: 'Abrir o teclado',
7
7
  closeText: 'Fechar', closeStatus: 'Fechar o teclado',
8
8
  clearText: 'Limpar', clearStatus: 'Limpar todo o texto',
@@ -17,5 +17,5 @@
17
17
  isNumeric: $.keypad.isNumeric,
18
18
  toUpper: $.keypad.toUpper,
19
19
  isRTL: false};
20
- $.keypad.setDefaults($.keypad.regional['pt-BR']);
20
+ $.keypad.setDefaults($.keypad.regionalOptions['pt-BR']);
21
21
  })(jQuery);
@@ -0,0 +1,21 @@
1
+ /* http://keith-wood.name/keypad.html
2
+ Slovak initialisation for the jQuery keypad extension
3
+ Written by Peter Čáni - inac.sk. */
4
+ (function($) { // hide the namespace
5
+ $.keypad.regionalOptions['sk'] = {
6
+ buttonText: '...', buttonStatus: 'Otvoriť',
7
+ closeText: 'Zatvoriť', closeStatus: 'Zatvoriť klávesnicu',
8
+ clearText: 'Vymazať', clearStatus: 'Vymazať text',
9
+ backText: 'Vymazať', backStatus: 'Vymazať posledné písmeno',
10
+ shiftText: 'Veľkosť', shiftStatus: 'Nastaví veľké/malé písmená',
11
+ spacebarText: '&nbsp;', spacebarStatus: '',
12
+ enterText: 'Enter', enterStatus: '',
13
+ tabText: '→', tabStatus: '',
14
+ alphabeticLayout: $.keypad.qwertyAlphabetic,
15
+ fullLayout: $.keypad.qwertyLayout,
16
+ isAlphabetic: $.keypad.isAlphabetic,
17
+ isNumeric: $.keypad.isNumeric,
18
+ toUpper: $.keypad.toUpper,
19
+ isRTL: false};
20
+ $.keypad.setDefaults($.keypad.regionalOptions['sk']);
21
+ })(jQuery);
@@ -2,7 +2,7 @@
2
2
  Turkish localisation for the jQuery keypad extension
3
3
  Written by Yücel Kandemir(yucel{at}21bilisim.com) September 2010. */
4
4
  (function($) { // hide the namespace
5
- $.keypad.regional['tr'] = {
5
+ $.keypad.regionalOptions['tr'] = {
6
6
  buttonText: '...', buttonStatus: 'Aç',
7
7
  closeText: 'Kapat', closeStatus: 'Klavyeyi Kapatýr',
8
8
  clearText: 'Sil', clearStatus: 'Ýçerisini Temizler',
@@ -17,5 +17,5 @@
17
17
  isNumeric: $.keypad.isNumeric,
18
18
  toUpper: $.keypad.toUpper,
19
19
  isRTL: false};
20
- $.keypad.setDefaults($.keypad.regional['tr']);
20
+ $.keypad.setDefaults($.keypad.regionalOptions['tr']);
21
21
  })(jQuery);
@@ -1,132 +1,216 @@
1
1
  /* http://keith-wood.name/keypad.html
2
- Keypad field entry extension for jQuery v1.5.1.
2
+ Keypad field entry extension for jQuery v2.0.0.
3
3
  Written by Keith Wood (kbwood{at}iinet.com.au) August 2008.
4
4
  Available under the MIT (https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt) license.
5
5
  Please attribute the author if you use it. */
6
6
 
7
7
  (function($) { // hide the namespace
8
8
 
9
- /* Keypad manager.
10
- Use the singleton instance of this class, $.keypad, to interact with the plugin.
11
- Settings for keypad fields are maintained in instance objects,
12
- allowing multiple different settings on the same page. */
13
- function Keypad() {
14
- this._curInst = null; // The current instance in use
15
- this._disabledFields = []; // List of keypad fields that have been disabled
16
- this._keypadShowing = false; // True if the popup panel is showing , false if not
17
- this._keyCode = 0;
18
- this._specialKeys = [];
19
- this.addKeyDef('CLOSE', 'close', function(inst) {
20
- plugin._curInst = (inst._inline ? inst : plugin._curInst);
21
- plugin._hidePlugin();
22
- });
23
- this.addKeyDef('CLEAR', 'clear', function(inst) { plugin._clearValue(inst); });
24
- this.addKeyDef('BACK', 'back', function(inst) { plugin._backValue(inst); });
25
- this.addKeyDef('SHIFT', 'shift', function(inst) { plugin._shiftKeypad(inst); });
26
- this.addKeyDef('SPACE_BAR', 'spacebar', function(inst) { plugin._selectValue(inst, ' '); }, true);
27
- this.addKeyDef('SPACE', 'space');
28
- this.addKeyDef('HALF_SPACE', 'half-space');
29
- this.addKeyDef('ENTER', 'enter', function(inst) { plugin._selectValue(inst, '\x0D'); }, true);
30
- this.addKeyDef('TAB', 'tab', function(inst) { plugin._selectValue(inst, '\x09'); }, true);
9
+ var pluginName = 'keypad';
10
+
11
+ var layoutStandard = [' BSCECA', '_1_2_3_+@X', '_4_5_6_-@U', '_7_8_9_*@E', '_0_._=_/'];
12
+
13
+ /** Create the keypad plugin.
14
+ <p>Sets an input field to popup a keypad for keystroke entry,
15
+ or creates an inline keypad in a <code>div</code> or <code>span</code>.</p>
16
+ <p>Expects HTML like:</p>
17
+ <pre>&lt;input type="text"> or
18
+ &lt;div&gt;&lt;/div&gt;</pre>
19
+ <p>Provide inline configuration like:</p>
20
+ <pre>&lt;input type="text" data-keypad="name: 'value'"/></pre>
21
+ @module Keypad
22
+ @augments JQPlugin
23
+ @example $(selector).keypad() */
24
+ $.JQPlugin.createPlugin({
25
+
26
+ /** The name of the plugin. */
27
+ name: pluginName,
28
+
29
+ /** Keypad before show callback.
30
+ Triggered before the keypad is shown.
31
+ @callback beforeShowCallback
32
+ @param div {jQuery} The div to be shown.
33
+ @param inst {object} The current instance settings. */
34
+
35
+ /** Keypad on keypress callback.
36
+ Triggered when a key on the keypad is pressed.
37
+ @callback keypressCallback
38
+ @param key {string} The key just pressed.
39
+ @param value {string} The full value entered so far.
40
+ @param inst {object} The current instance settings. */
41
+
42
+ /** Keypad on close callback.
43
+ Triggered when the keypad is closed.
44
+ @callback closeCallback
45
+ @param value {string} The full value entered so far.
46
+ @param inst {object} The current instance settings. */
47
+
48
+ /** Keypad is alphabetic callback.
49
+ Triggered when an alphabetic key needs to be identified.
50
+ @callback isAlphabeticCallback
51
+ @param ch {string} The key to check.
52
+ @return {boolean} True if this key is alphabetic, false if not.
53
+ @example isAlphabetic: function(ch) {
54
+ return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
55
+ } */
56
+
57
+ /** Keypad is numeric callback.
58
+ Triggered when an numeric key needs to be identified.
59
+ @callback isNumericCallback
60
+ @param ch {string} The key to check.
61
+ @return {boolean} True if this key is numeric, false if not.
62
+ @example isNumeric: function(ch) {
63
+ return (ch >= '0' && ch <= '9');
64
+ } */
65
+
66
+ /** Keypad to upper callback.
67
+ Triggered to convert keys to upper case.
68
+ @callback toUpperCallback
69
+ @param ch {string} The key to convert.
70
+ @return {string} The upper case version of this key.
71
+ @example toUpper: function(ch) {
72
+ return ch.toUpperCase();
73
+ } */
74
+
75
+ /** Default settings for the plugin.
76
+ @property [showOn='focus'] {string} 'focus' for popup on focus, 'button' for trigger button, or 'both' for either.
77
+ @property [buttonImage=''] {string} URL for trigger button image.
78
+ @property [buttonImageOnly=false] {boolean} True if the image appears alone, false if it appears on a button.
79
+ @property [showAnim='show'] {string} Name of jQuery animation for popup.
80
+ @property [showOptions=null] {object} Options for enhanced animations.
81
+ @property [duration='normal'] {string|number} Duration of display/closure.
82
+ @property [appendText=''] {string} Display text following the text field, e.g. showing the format.
83
+ @property [useThemeRoller=false] {boolean} True to add ThemeRoller classes.
84
+ @property [keypadClass=''] {string} Additional CSS class for the keypad for an instance.
85
+ @property [prompt=''] {string} Display text at the top of the keypad.
86
+ @property [layout=this.numericLayout] {string} Layout of keys.
87
+ @property [separator=''] {string} Separator character between keys.
88
+ @property [target=null] {string|jQuery|Element} Input target for an inline keypad.
89
+ @property [keypadOnly=true] {boolean} True for entry only via the keypad, false for real keyboard too.
90
+ @property [randomiseAlphabetic=false] {boolean} True to randomise the alphabetic key positions, false to keep in order.
91
+ @property [randomiseNumeric=false] {boolean} True to randomise the numeric key positions, false to keep in order.
92
+ @property [randomiseOther=false] {boolean} True to randomise the other key positions, false to keep in order.
93
+ @property [randomiseAll=false] {boolean} True to randomise all key positions, false to keep in order.
94
+ @property [beforeShow=null] {beforeShowCallback} Callback before showing the keypad.
95
+ @property [onKeypress=null] {keypressCallback} Callback when a key is selected.
96
+ @property [onClose=null] {closeCallback} Callback when the panel is closed. */
97
+ defaultOptions: {
98
+ showOn: 'focus',
99
+ buttonImage: '',
100
+ buttonImageOnly: false,
101
+ showAnim: 'show',
102
+ showOptions: null,
103
+ duration: 'normal',
104
+ appendText: '',
105
+ useThemeRoller: false,
106
+ keypadClass: '',
107
+ prompt: '',
108
+ layout: [], // Set at the end
109
+ separator: '',
110
+ target: null,
111
+ keypadOnly: true,
112
+ randomiseAlphabetic: false,
113
+ randomiseNumeric: false,
114
+ randomiseOther: false,
115
+ randomiseAll: false,
116
+ beforeShow: null,
117
+ onKeypress: null,
118
+ onClose: null
119
+ },
120
+
121
+ /** Localisations for the plugin.
122
+ Entries are objects indexed by the language code ('' being the default US/English).
123
+ Each object has the following attributes.
124
+ @property [buttonText='...'] {string} Display text for trigger button.
125
+ @property [buttonStatus='Open the keypad'] {string} Status text for trigger button.
126
+ @property [closeText='Close'] {string} Display text for close link.
127
+ @property [closeStatus='Close the keypad'] {string} Status text for close link.
128
+ @property [clearText='Clear'] {string} Display text for clear link.
129
+ @property [clearStatus='Erase all the text'] {string} Status text for clear link.
130
+ @property [backText='Back'] {string} Display text for back link.
131
+ @property [backStatus='Erase the previous character'] {string} Status text for back link.
132
+ @property [spacebarText='&nbsp;'] {string} Display text for space bar.
133
+ @property [spacebarStatus='Space'] {string} Status text for space bar.
134
+ @property [enterText='Enter'] {string} Display text for carriage return.
135
+ @property [enterStatus='Carriage return'] {string} Status text for carriage return.
136
+ @property [tabText='→'] {string} Display text for tab.
137
+ @property [tabStatus='Horizontal tab'] {string} Status text for tab.
138
+ @property [shiftText='Shift'] {string} Display text for shift link.
139
+ @property [shiftStatus='Toggle upper/lower case characters'] {string} Status text for shift link.
140
+ @property [alphabeticLayout=this.qwertyAlphabetic] {string} Default layout for alphabetic characters.
141
+ @property [fullLayout=this.qwertyLayout] {string} Default layout for full keyboard.
142
+ @property [isAlphabetic=this.isAlphabetic] {isAlphabeticCallback} Function to determine if character is alphabetic.
143
+ @property [isNumeric=this.isNumeric] {isNumericCallback} Function to determine if character is numeric.
144
+ @property [toUpper=this.toUpper] {toUpperCallback} Function to convert characters to upper case.
145
+ @property [isRTL=false] {boolean} True if right-to-left language, false if left-to-right. */
146
+ regionalOptions: { // Available regional settings, indexed by language/country code
147
+ '': { // Default regional settings - English/US
148
+ buttonText: '...',
149
+ buttonStatus: 'Open the keypad',
150
+ closeText: 'Close',
151
+ closeStatus: 'Close the keypad',
152
+ clearText: 'Clear',
153
+ clearStatus: 'Erase all the text',
154
+ backText: 'Back',
155
+ backStatus: 'Erase the previous character',
156
+ spacebarText: '&nbsp;',
157
+ spacebarStatus: 'Space',
158
+ enterText: 'Enter',
159
+ enterStatus: 'Carriage return',
160
+ tabText: '→',
161
+ tabStatus: 'Horizontal tab',
162
+ shiftText: 'Shift',
163
+ shiftStatus: 'Toggle upper/lower case characters',
164
+ alphabeticLayout: [], // Set at the end
165
+ fullLayout: [],
166
+ isAlphabetic: null,
167
+ isNumeric: null,
168
+ toUpper: null,
169
+ isRTL: false
170
+ }
171
+ },
172
+
173
+ /** Names of getter methods - those that can't be chained. */
174
+ _getters: ['isDisabled'],
175
+
176
+ _curInst: null, // The current instance in use
177
+ _disabledFields: [], // List of keypad fields that have been disabled
178
+ _keypadShowing: false, // True if the popup panel is showing , false if not
179
+ _keyCode: 0,
180
+ _specialKeys: [],
181
+
182
+ _mainDivClass: pluginName + '-popup', // The main keypad division class
183
+ _inlineClass: pluginName + '-inline', // The inline marker class
184
+ _appendClass: pluginName + '-append', // The append marker class
185
+ _triggerClass: pluginName + '-trigger', // The trigger marker class
186
+ _disableClass: pluginName + '-disabled', // The disabled covering marker class
187
+ _inlineEntryClass: pluginName + '-keyentry', // The inline entry marker class
188
+ _rtlClass: pluginName + '-rtl', // The right-to-left marker class
189
+ _rowClass: pluginName + '-row', // The keypad row marker class
190
+ _promptClass: pluginName + '-prompt', // The prompt marker class
191
+ _specialClass: pluginName + '-special', // The special key marker class
192
+ _namePrefixClass: pluginName + '-', // The key name marker class prefix
193
+ _keyClass: pluginName + '-key', // The key marker class
194
+ _keyDownClass: pluginName + '-key-down', // The key down marker class
195
+
31
196
  // Standard US keyboard alphabetic layout
32
- this.qwertyAlphabetic = ['qwertyuiop', 'asdfghjkl', 'zxcvbnm'];
197
+ qwertyAlphabetic: ['qwertyuiop', 'asdfghjkl', 'zxcvbnm'],
33
198
  // Standard US keyboard layout
34
- this.qwertyLayout = ['!@#$%^&*()_=' + this.HALF_SPACE + this.SPACE + this.CLOSE,
199
+ qwertyLayout: ['!@#$%^&*()_=' + this.HALF_SPACE + this.SPACE + this.CLOSE,
35
200
  this.HALF_SPACE + '`~[]{}<>\\|/' + this.SPACE + '789',
36
201
  'qwertyuiop\'"' + this.HALF_SPACE + '456',
37
202
  this.HALF_SPACE + 'asdfghjkl;:' + this.SPACE + '123',
38
203
  this.SPACE + 'zxcvbnm,.?' + this.SPACE + this.HALF_SPACE + '-0+',
39
204
  '' + this.TAB + this.ENTER + this.SPACE_BAR + this.SHIFT +
40
- this.HALF_SPACE + this.BACK + this.CLEAR];
41
- this.regional = []; // Available regional settings, indexed by language code
42
- this.regional[''] = { // Default regional settings
43
- buttonText: '...', // Display text for trigger button
44
- buttonStatus: 'Open the keypad', // Status text for trigger button
45
- closeText: 'Close', // Display text for close link
46
- closeStatus: 'Close the keypad', // Status text for close link
47
- clearText: 'Clear', // Display text for clear link
48
- clearStatus: 'Erase all the text', // Status text for clear link
49
- backText: 'Back', // Display text for back link
50
- backStatus: 'Erase the previous character', // Status text for back link
51
- spacebarText: '&nbsp;', // Display text for space bar
52
- spacebarStatus: 'Space', // Status text for space bar
53
- enterText: 'Enter', // Display text for carriage return
54
- enterStatus: 'Carriage return', // Status text for carriage return
55
- tabText: '→', // Display text for tab
56
- tabStatus: 'Horizontal tab', // Status text for tab
57
- shiftText: 'Shift', // Display text for shift link
58
- shiftStatus: 'Toggle upper/lower case characters', // Status text for shift link
59
- alphabeticLayout: this.qwertyAlphabetic, // Default layout for alphabetic characters
60
- fullLayout: this.qwertyLayout, // Default layout for full keyboard
61
- isAlphabetic: this.isAlphabetic, // Function to determine if character is alphabetic
62
- isNumeric: this.isNumeric, // Function to determine if character is numeric
63
- toUpper: this.toUpper, // Function to convert characters to upper case
64
- isRTL: false // True if right-to-left language, false if left-to-right
65
- };
66
- this._defaults = { // Global defaults for all the keypad instances
67
- showOn: 'focus', // 'focus' for popup on focus,
68
- // 'button' for trigger button, or 'both' for either
69
- buttonImage: '', // URL for trigger button image
70
- buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
71
- showAnim: 'show', // Name of jQuery animation for popup
72
- showOptions: {}, // Options for enhanced animations
73
- duration: 'normal', // Duration of display/closure
74
- appendText: '', // Display text following the text field, e.g. showing the format
75
- useThemeRoller: false, // True to add ThemeRoller classes
76
- keypadClass: '', // Additional CSS class for the keypad for an instance
77
- prompt: '', // Display text at the top of the keypad
78
- layout: ['123' + this.CLOSE, '456' + this.CLEAR, '789' + this.BACK, this.SPACE + '0'], // Layout of keys
79
- separator: '', // Separator character between keys
80
- target: null, // Input target for an inline keypad
81
- keypadOnly: true, // True for entry only via the keypad, false for real keyboard too
82
- randomiseAlphabetic: false, // True to randomise the alphabetic key positions, false to keep in order
83
- randomiseNumeric: false, // True to randomise the numeric key positions, false to keep in order
84
- randomiseOther: false, // True to randomise the other key positions, false to keep in order
85
- randomiseAll: false, // True to randomise all key positions, false to keep in order
86
- beforeShow: null, // Callback before showing the keypad
87
- onKeypress: null, // Callback when a key is selected
88
- onClose: null // Callback when the panel is closed
89
- };
90
- $.extend(this._defaults, this.regional['']);
91
- this.mainDiv = $('<div class="' + this._mainDivClass + '" style="display: none;"></div>');
92
- }
93
-
94
- $.extend(Keypad.prototype, {
95
- /* Class name added to elements to indicate already configured with keypad. */
96
- markerClassName: 'hasKeypad',
97
- /* Name of the data property for instance settings. */
98
- propertyName: 'keypad',
99
-
100
- _mainDivClass: 'keypad-popup', // The main keypad division class
101
- _inlineClass: 'keypad-inline', // The inline marker class
102
- _appendClass: 'keypad-append', // The append marker class
103
- _triggerClass: 'keypad-trigger', // The trigger marker class
104
- _disableClass: 'keypad-disabled', // The disabled covering marker class
105
- _inlineEntryClass: 'keypad-keyentry', // The inline entry marker class
106
- _rtlClass: 'keypad-rtl', // The right-to-left marker class
107
- _rowClass: 'keypad-row', // The keypad row marker class
108
- _promptClass: 'keypad-prompt', // The prompt marker class
109
- _specialClass: 'keypad-special', // The special key marker class
110
- _namePrefixClass: 'keypad-', // The key name marker class prefix
111
- _keyClass: 'keypad-key', // The key marker class
112
- _keyDownClass: 'keypad-key-down', // The key down marker class
113
-
114
- /* Override the default settings for all keypad instances.
115
- @param settings (object) the new settings to use as defaults
116
- @return (Keypad) this object */
117
- setDefaults: function(settings) {
118
- $.extend(this._defaults, settings || {});
119
- return this;
120
- },
121
-
122
- /* Add the definition of a special key.
123
- @param id (string) the identifier for this key - access via $.keypad.<id>
124
- @param name (string) the prefix for localisation strings and
125
- the suffix for a class name
126
- @param action (function) the action performed for this key -
127
- receives inst as a parameter
128
- @param noHighlight (boolean) true to suppress highlight when using ThemeRoller
129
- @return (Keypad) this object */
205
+ this.HALF_SPACE + this.BACK + this.CLEAR],
206
+
207
+ /** Add the definition of a special key.
208
+ @param id {string} The identifier for this key - access via <code>$.keypad.xxx</code>.<id>.
209
+ @param name {string} The prefix for localisation strings and the suffix for a class name.
210
+ @param action {function} The action performed for this key - receives <code>inst</code> as a parameter.
211
+ @param noHighlight {boolean} True to suppress highlight when using ThemeRoller.
212
+ @return {Keypad} The keypad object for chaining further calls.
213
+ @example $.keypad.addKeyDef('CLEAR', 'clear', function(inst) { plugin._clearValue(inst); }); */
130
214
  addKeyDef: function(id, name, action, noHighlight) {
131
215
  if (this._keyCode == 32) {
132
216
  throw 'Only 32 special keys allowed';
@@ -137,59 +221,60 @@ $.extend(Keypad.prototype, {
137
221
  return this;
138
222
  },
139
223
 
140
- /* Attach the keypad to a jQuery selection.
141
- @param target (element) the control to affect
142
- @param options (object) the custom options for this instance */
143
- _attachPlugin: function(target, options) {
144
- target = $(target);
145
- if (target.hasClass(this.markerClassName)) {
146
- return;
147
- }
148
- var inline = !target[0].nodeName.toLowerCase().match(/input|textarea/);
149
- var inst = {options: $.extend({}, this._defaults, options), _inline: inline,
150
- _mainDiv: (inline ? $('<div class="' + this._inlineClass + '"></div>') : plugin.mainDiv),
151
- ucase: false};
152
- this._setInput(target, inst);
153
- this._connectKeypad(target, inst);
154
- if (inline) {
155
- target.append(inst._mainDiv).
156
- bind('click.' + this.propertyName, function() { inst._input.focus(); });
224
+ /** Additional setup for the keypad.
225
+ Create popup div. */
226
+ _init: function() {
227
+ this.mainDiv = $('<div class="' + this._mainDivClass + '" style="display: none;"></div>');
228
+ this._super();
229
+ },
230
+
231
+ _instSettings: function(elem, options) {
232
+ var inline = !elem[0].nodeName.toLowerCase().match(/input|textarea/);
233
+ return {_inline: inline, ucase: false,
234
+ _mainDiv: (inline ? $('<div class="' + this._inlineClass + '"></div>') : plugin.mainDiv)};
235
+ },
236
+
237
+ _postAttach: function(elem, inst) {
238
+ if (inst._inline) {
239
+ elem.append(inst._mainDiv).
240
+ on('click.' + inst.name, function() { inst._input.focus(); });
157
241
  this._updateKeypad(inst);
158
242
  }
159
- else if (target.is(':disabled')) {
160
- this._disablePlugin(target);
243
+ else if (elem.is(':disabled')) {
244
+ this.disable(elem);
161
245
  }
162
246
  },
163
247
 
164
- /* Determine the input field for the keypad.
165
- @param target (jQuery) the target control
166
- @param inst (object) the instance settings */
167
- _setInput: function(target, inst) {
168
- inst._input = $(!inst._inline ? target : inst.options.target ||
169
- '<input type="text" class="' + this._inlineEntryClass + '" disabled="disabled"/>');
248
+ /** Determine the input field for the keypad.
249
+ @private
250
+ @param elem {jQuery} The target control.
251
+ @param inst {object} The instance settings. */
252
+ _setInput: function(elem, inst) {
253
+ inst._input = $(!inst._inline ? elem : inst.options.target ||
254
+ '<input type="text" class="' + this._inlineEntryClass + '" disabled/>');
170
255
  if (inst._inline) {
171
- target.find('input').remove();
256
+ elem.find('input').remove();
172
257
  if (!inst.options.target) {
173
- target.append(inst._input);
258
+ elem.append(inst._input);
174
259
  }
175
260
  }
176
261
  },
177
262
 
178
- /* Attach the keypad to a text field.
179
- @param target (jQuery) the target text field
180
- @param inst (object) the instance settings */
181
- _connectKeypad: function(target, inst) {
182
- target = $(target);
263
+ _optionsChanged: function(elem, inst, options) {
264
+ $.extend(inst.options, options);
265
+ elem.off('.' + inst.name).
266
+ siblings('.' + this._appendClass).remove().end().
267
+ siblings('.' + this._triggerClass).remove();
183
268
  var appendText = inst.options.appendText;
184
269
  if (appendText) {
185
- target[inst.options.isRTL ? 'before' : 'after'](
270
+ elem[inst.options.isRTL ? 'before' : 'after'](
186
271
  '<span class="' + this._appendClass + '">' + appendText + '</span>');
187
272
  }
188
273
  if (!inst._inline) {
189
274
  if (inst.options.showOn == 'focus' || inst.options.showOn == 'both') {
190
275
  // pop-up keypad when in the marked field
191
- target.bind('focus.' + this.propertyName, this._showPlugin).
192
- bind('keydown.' + this.propertyName, this._doKeyDown);
276
+ elem.on('focus.' + inst.name, this.show).
277
+ on('keydown.' + inst.name, this._doKeyDown);
193
278
  }
194
279
  if (inst.options.showOn == 'button' || inst.options.showOn == 'both') {
195
280
  // pop-up keypad when button clicked
@@ -202,124 +287,80 @@ $.extend(Keypad.prototype, {
202
287
  html(buttonImage == '' ? inst.options.buttonText :
203
288
  $('<img src="' + buttonImage + '" alt="' +
204
289
  buttonStatus + '" title="' + buttonStatus + '"/>')));
205
- target[inst.options.isRTL ? 'before' : 'after'](trigger);
290
+ elem[inst.options.isRTL ? 'before' : 'after'](trigger);
206
291
  trigger.addClass(this._triggerClass).click(function() {
207
- if (plugin._keypadShowing && plugin._lastField == target[0]) {
208
- plugin._hidePlugin();
292
+ if (plugin._keypadShowing && plugin._lastField == elem[0]) {
293
+ plugin.hide();
209
294
  }
210
295
  else {
211
- plugin._showPlugin(target[0]);
296
+ plugin.show(elem[0]);
212
297
  }
213
298
  return false;
214
299
  });
215
300
  }
216
301
  }
217
- inst.saveReadonly = target.attr('readonly');
218
- target.addClass(this.markerClassName).
219
- data(this.propertyName, inst)
220
- [inst.options.keypadOnly ? 'attr' : 'removeAttr']('readonly', true).
221
- bind('setData.' + this.propertyName, function(event, key, value) {
302
+ inst.saveReadonly = elem.attr('readonly');
303
+ elem[inst.options.keypadOnly ? 'attr' : 'removeAttr']('readonly', true).
304
+ on('setData.' + inst.name, function(event, key, value) {
222
305
  inst.options[key] = value;
223
- }).bind('getData.' + this.propertyName, function(event, key) {
306
+ }).
307
+ on('getData.' + inst.name, function(event, key) {
224
308
  return inst.options[key];
225
309
  });
226
- },
227
-
228
- /* Retrieve or reconfigure the settings for a control.
229
- @param target (element) the control to affect
230
- @param options (object) the new options for this instance or
231
- (string) an individual property name
232
- @param value (any) the individual property value (omit if options
233
- is an object or to retrieve the value of a setting)
234
- @return (any) if retrieving a value */
235
- _optionPlugin: function(target, options, value) {
236
- target = $(target);
237
- var inst = target.data(this.propertyName);
238
- if (!options || (typeof options == 'string' && value == null)) { // Get option
239
- var name = options;
240
- options = (inst || {}).options;
241
- return (options && name ? options[name] : options);
242
- }
243
-
244
- if (!target.hasClass(this.markerClassName)) {
245
- return;
246
- }
247
- options = options || {};
248
- if (typeof options == 'string') {
249
- var name = options;
250
- options = {};
251
- options[name] = value;
252
- }
253
- if (this._curInst == inst) {
254
- this._hidePlugin();
255
- }
256
- $.extend(inst.options, options);
257
- this._setInput(target, inst);
310
+ this._setInput(elem, inst);
258
311
  this._updateKeypad(inst);
259
312
  },
260
313
 
261
- /* Detach keypad from its control.
262
- @param target (element) the target text field */
263
- _destroyPlugin: function(target) {
264
- target = $(target);
265
- if (!target.hasClass(this.markerClassName)) {
266
- return;
267
- }
268
- var inst = target.data(this.propertyName);
314
+ _preDestroy: function(elem, inst) {
269
315
  if (this._curInst == inst) {
270
- this._hidePlugin();
316
+ this.hide();
271
317
  }
272
- target.siblings('.' + this._appendClass).remove().end().
318
+ elem.siblings('.' + this._appendClass).remove().end().
273
319
  siblings('.' + this._triggerClass).remove().end().
274
320
  prev('.' + this._inlineEntryClass).remove();
275
- target.removeClass(this.markerClassName).empty().
276
- unbind('.' + this.propertyName).
277
- removeData(this.propertyName)
321
+ elem.empty().off('.' + inst.name)
278
322
  [inst.saveReadonly ? 'attr' : 'removeAttr']('readonly', true);
279
- inst._input.removeData(this.propertyName);
323
+ inst._input.removeData(inst.name);
280
324
  },
281
325
 
282
- /* Enable the keypad for a jQuery selection.
283
- @param target (element) the target text field */
284
- _enablePlugin: function(target) {
285
- target = $(target);
286
- if (!target.hasClass(this.markerClassName)) {
326
+ /** Enable the keypad for a jQuery selection.
327
+ @param elem {Element} The target text field.
328
+ @example $(selector).keypad('enable'); */
329
+ enable: function(elem) {
330
+ elem = $(elem);
331
+ if (!elem.hasClass(this._getMarker())) {
287
332
  return;
288
333
  }
289
- var nodeName = target[0].nodeName.toLowerCase();
334
+ var nodeName = elem[0].nodeName.toLowerCase();
290
335
  if (nodeName.match(/input|textarea/)) {
291
- target[0].disabled = false;
292
- target.siblings('button.' + this._triggerClass).
293
- each(function() { this.disabled = false; }).end().
294
- siblings('img.' + this._triggerClass).
295
- css({opacity: '1.0', cursor: ''});
336
+ elem.prop('disabled', false).
337
+ siblings('button.' + this._triggerClass).prop('disabled', false).end().
338
+ siblings('img.' + this._triggerClass).css({opacity: '1.0', cursor: ''});
296
339
  }
297
340
  else if (nodeName.match(/div|span/)) {
298
- target.children('.' + this._disableClass).remove();
299
- var inst = target.data(this.propertyName);
300
- inst._mainDiv.find('button').removeAttr('disabled');
341
+ elem.children('.' + this._disableClass).remove();
342
+ this._getInst(elem)._mainDiv.find('button').prop('disabled', false);
301
343
  }
302
344
  this._disabledFields = $.map(this._disabledFields,
303
- function(value) { return (value == target[0] ? null : value); }); // delete entry
345
+ function(value) { return (value == elem[0] ? null : value); }); // delete entry
304
346
  },
305
347
 
306
- /* Disable the keypad for a jQuery selection.
307
- @param target (element) the target text field */
308
- _disablePlugin: function(target) {
309
- target = $(target);
310
- if (!target.hasClass(this.markerClassName)) {
348
+ /** Disable the keypad for a jQuery selection.
349
+ @param elem {Element} The target text field.
350
+ @example $(selector).keypad('disable'); */
351
+ disable: function(elem) {
352
+ elem = $(elem);
353
+ if (!elem.hasClass(this._getMarker())) {
311
354
  return;
312
355
  }
313
- var nodeName = target[0].nodeName.toLowerCase();
356
+ var nodeName = elem[0].nodeName.toLowerCase();
314
357
  if (nodeName.match(/input|textarea/)) {
315
- target[0].disabled = true;
316
- target.siblings('button.' + this._triggerClass).
317
- each(function() { this.disabled = true; }).end().
318
- siblings('img.' + this._triggerClass).
319
- css({opacity: '0.5', cursor: 'default'});
358
+ elem.prop('disabled', true).
359
+ siblings('button.' + this._triggerClass).prop('disabled', true).end().
360
+ siblings('img.' + this._triggerClass).css({opacity: '0.5', cursor: 'default'});
320
361
  }
321
362
  else if (nodeName.match(/div|span/)) {
322
- var inline = target.children('.' + this._inlineClass);
363
+ var inline = elem.children('.' + this._inlineClass);
323
364
  var offset = inline.offset();
324
365
  var relOffset = {left: 0, top: 0};
325
366
  inline.parents().each(function() {
@@ -328,41 +369,40 @@ $.extend(Keypad.prototype, {
328
369
  return false;
329
370
  }
330
371
  });
331
- target.prepend('<div class="' + this._disableClass + '" style="width: ' +
372
+ elem.prepend('<div class="' + this._disableClass + '" style="width: ' +
332
373
  inline.outerWidth() + 'px; height: ' + inline.outerHeight() +
333
374
  'px; left: ' + (offset.left - relOffset.left) +
334
375
  'px; top: ' + (offset.top - relOffset.top) + 'px;"></div>');
335
- var inst = target.data(this.propertyName);
336
- inst._mainDiv.find('button').attr('disabled', 'disabled');
376
+ this._getInst(elem)._mainDiv.find('button').prop('disabled', true);
337
377
  }
338
378
  this._disabledFields = $.map(this._disabledFields,
339
- function(value) { return (value == target[0] ? null : value); }); // delete entry
340
- this._disabledFields[this._disabledFields.length] = target[0];
341
- },
342
-
343
- /* Is the text field disabled as a keypad?
344
- @param target (element) the target text field
345
- @return (boolean) true if disabled, false if enabled */
346
- _isDisabledPlugin: function(target) {
347
- return (target && $.inArray(target, this._disabledFields) > -1);
348
- },
349
-
350
- /* Pop-up the keypad for a given text field.
351
- @param field (element) the text field attached to the keypad or
352
- (event) if triggered by focus */
353
- _showPlugin: function(field) {
354
- field = field.target || field;
355
- if (plugin._isDisabledPlugin(field) ||
356
- plugin._lastField == field) { // already here
379
+ function(value) { return (value == elem[0] ? null : value); }); // delete entry
380
+ this._disabledFields[this._disabledFields.length] = elem[0];
381
+ },
382
+
383
+ /** Is the text field disabled as a keypad?
384
+ @param elem {Element} The target text field.
385
+ @return {boolean} True if disabled, false if enabled.
386
+ @example var disabled = $(selector).keypad('isDisabled'); */
387
+ isDisabled: function(elem) {
388
+ return (elem && $.inArray(elem, this._disabledFields) > -1);
389
+ },
390
+
391
+ /** Pop-up the keypad for a given text field.
392
+ @param elem {Element|Event} The text field attached to the keypad or event if triggered by focus.
393
+ @example $(selector).keypad('show'); */
394
+ show: function(elem) {
395
+ elem = elem.target || elem;
396
+ if (plugin.isDisabled(elem) || plugin._lastField == elem) { // already here
357
397
  return;
358
398
  }
359
- var inst = $.data(field, plugin.propertyName);
360
- plugin._hidePlugin(null, '');
361
- plugin._lastField = field;
362
- plugin._pos = plugin._findPos(field);
363
- plugin._pos[1] += field.offsetHeight; // add the height
399
+ var inst = plugin._getInst(elem);
400
+ plugin.hide(null, '');
401
+ plugin._lastField = elem;
402
+ plugin._pos = plugin._findPos(elem);
403
+ plugin._pos[1] += elem.offsetHeight; // add the height
364
404
  var isFixed = false;
365
- $(field).parents().each(function() {
405
+ $(elem).parents().each(function() {
366
406
  isFixed |= $(this).css('position') == 'fixed';
367
407
  return !isFixed;
368
408
  });
@@ -388,7 +428,7 @@ $.extend(Keypad.prototype, {
388
428
  }
389
429
  }
390
430
  inst._mainDiv.data(data).show(showAnim,
391
- inst.options.showOptions, duration, postProcess);
431
+ inst.options.showOptions || {}, duration, postProcess);
392
432
  }
393
433
  else {
394
434
  inst._mainDiv[showAnim || 'show']((showAnim ? duration : 0), postProcess);
@@ -399,8 +439,9 @@ $.extend(Keypad.prototype, {
399
439
  plugin._curInst = inst;
400
440
  },
401
441
 
402
- /* Generate the keypad content.
403
- @param inst (object) the instance settings */
442
+ /** Generate the keypad content.
443
+ @private
444
+ @param inst {object} The instance settings. */
404
445
  _updateKeypad: function(inst) {
405
446
  var borders = this._getBorders(inst._mainDiv);
406
447
  inst._mainDiv.empty().append(this._generateHTML(inst)).
@@ -414,9 +455,10 @@ $.extend(Keypad.prototype, {
414
455
  }
415
456
  },
416
457
 
417
- /* Retrieve the size of left and top borders for an element.
418
- @param elem (jQuery object) the element of interest
419
- @return (number[2]) the left and top borders */
458
+ /** Retrieve the size of left and top borders for an element.
459
+ @private
460
+ @param elem {jQuery} The element of interest.
461
+ @return {number[]} The left and top borders. */
420
462
  _getBorders: function(elem) {
421
463
  var convert = function(value) {
422
464
  return {thin: 1, medium: 3, thick: 5}[value] || value;
@@ -425,11 +467,12 @@ $.extend(Keypad.prototype, {
425
467
  parseFloat(convert(elem.css('border-top-width')))];
426
468
  },
427
469
 
428
- /* Check positioning to remain on screen.
429
- @param inst (object) the instance settings
430
- @param offset (object) the current offset
431
- @param isFixed (boolean) true if the text field is fixed in position
432
- @return (object) the updated offset */
470
+ /** Check positioning to remain on screen.
471
+ @private
472
+ @param inst {object} The instance settings.
473
+ @param offset {object} The current offset.
474
+ @param isFixed {boolean} True if the text field is fixed in position.
475
+ @return {object} The updated offset. */
433
476
  _checkOffset: function(inst, offset, isFixed) {
434
477
  var pos = inst._input ? this._findPos(inst._input[0]) : null;
435
478
  var browserWidth = window.innerWidth || document.documentElement.clientWidth;
@@ -463,9 +506,10 @@ $.extend(Keypad.prototype, {
463
506
  return offset;
464
507
  },
465
508
 
466
- /* Find an object's position on the screen.
467
- @param obj (element) the element to find the position for
468
- @return (int[2]) the element's position */
509
+ /** Find an object's position on the screen.
510
+ @private
511
+ @param obj {Element} The element to find the position for.
512
+ @return {number[]} The element's position. */
469
513
  _findPos: function(obj) {
470
514
  while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
471
515
  obj = obj.nextSibling;
@@ -474,19 +518,20 @@ $.extend(Keypad.prototype, {
474
518
  return [position.left, position.top];
475
519
  },
476
520
 
477
- /* Hide the keypad from view.
478
- @param field (element) the text field attached to the keypad
479
- @param duration (string) the duration over which to close the keypad */
480
- _hidePlugin: function(field, duration) {
521
+ /** Hide the keypad from view.
522
+ @param elem {Element} The text field attached to the keypad.
523
+ @param duration {string} The duration over which to close the keypad.
524
+ @example $(selector).keypad('hide') */
525
+ hide: function(elem, duration) {
481
526
  var inst = this._curInst;
482
- if (!inst || (field && inst != $.data(field, this.propertyName))) {
527
+ if (!inst || (elem && inst != $.data(elem, this.propertyName))) {
483
528
  return;
484
529
  }
485
530
  if (this._keypadShowing) {
486
531
  duration = (duration != null ? duration : inst.options.duration);
487
532
  var showAnim = inst.options.showAnim;
488
533
  if ($.effects && ($.effects[showAnim] || ($.effects.effect && $.effects.effect[showAnim]))) {
489
- inst._mainDiv.hide(showAnim, inst.options.showOptions, duration);
534
+ inst._mainDiv.hide(showAnim, inst.options.showOptions || {}, duration);
490
535
  }
491
536
  else {
492
537
  inst._mainDiv[(showAnim == 'slideDown' ? 'slideUp' :
@@ -507,115 +552,112 @@ $.extend(Keypad.prototype, {
507
552
  this._curInst = null;
508
553
  },
509
554
 
510
- /* Handle keystrokes.
511
- @param e (event) the key event */
512
- _doKeyDown: function(e) {
513
- if (e.keyCode == 9) { // Tab out
555
+ /** Handle keystrokes.
556
+ @private
557
+ @param event {Event} The key event. */
558
+ _doKeyDown: function(event) {
559
+ if (event.keyCode == 9) { // Tab out
514
560
  plugin.mainDiv.stop(true, true);
515
- plugin._hidePlugin();
561
+ plugin.hide();
516
562
  }
517
563
  },
518
564
 
519
- /* Close keypad if clicked elsewhere.
520
- @param event (event) the mouseclick details */
565
+ /** Close keypad if clicked elsewhere.
566
+ @private
567
+ @param event {Event} The mouseclick details. */
521
568
  _checkExternalClick: function(event) {
522
569
  if (!plugin._curInst) {
523
570
  return;
524
571
  }
525
572
  var target = $(event.target);
526
- if (!target.parents().andSelf().hasClass(plugin._mainDivClass) &&
527
- !target.hasClass(plugin.markerClassName) &&
528
- !target.parents().andSelf().hasClass(plugin._triggerClass) &&
573
+ if (target.closest('.' + plugin._mainDivClass).length === 0 &&
574
+ !target.hasClass(plugin._getMarker()) &&
575
+ target.closest('.' + plugin._triggerClass).length === 0 &&
529
576
  plugin._keypadShowing) {
530
- plugin._hidePlugin();
577
+ plugin.hide();
531
578
  }
532
579
  },
533
580
 
534
- /* Toggle between upper and lower case.
535
- @param inst (object) the instance settings */
581
+ /** Toggle between upper and lower case.
582
+ @private
583
+ @param inst {object} The instance settings. */
536
584
  _shiftKeypad: function(inst) {
537
585
  inst.ucase = !inst.ucase;
538
586
  this._updateKeypad(inst);
539
587
  inst._input.focus(); // for further typing
540
588
  },
541
589
 
542
- /* Erase the text field.
543
- @param inst (object) the instance settings */
590
+ /** Erase the text field.
591
+ @private
592
+ @param inst {object} The instance settings. */
544
593
  _clearValue: function(inst) {
545
594
  this._setValue(inst, '', 0);
546
595
  this._notifyKeypress(inst, plugin.DEL);
547
596
  },
548
597
 
549
- /* Erase the last character.
550
- @param inst (object) the instance settings */
598
+ /** Erase the last character.
599
+ @private
600
+ @param inst {object} The instance settings. */
551
601
  _backValue: function(inst) {
552
- var field = inst._input[0];
602
+ var elem = inst._input[0];
553
603
  var value = inst._input.val();
554
604
  var range = [value.length, value.length];
555
- if (field.setSelectionRange) { // Mozilla
556
- range = (inst._input.attr('readonly') || inst._input.attr('disabled') ?
557
- range : [field.selectionStart, field.selectionEnd]);
558
- }
559
- else if (field.createTextRange) { // IE
560
- range = (inst._input.attr('readonly') || inst._input.attr('disabled') ?
561
- range : this._getIERange(field));
562
- }
605
+ range = (inst._input.prop('readonly') || inst._input.prop('disabled') ? range :
606
+ (elem.setSelectionRange /* Mozilla */ ? [elem.selectionStart, elem.selectionEnd] :
607
+ (elem.createTextRange /* IE */ ? this._getIERange(elem) : range)));
563
608
  this._setValue(inst, (value.length == 0 ? '' :
564
609
  value.substr(0, range[0] - 1) + value.substr(range[1])), range[0] - 1);
565
610
  this._notifyKeypress(inst, plugin.BS);
566
611
  },
567
612
 
568
- /* Update the text field with the selected value.
569
- @param inst (object) the instance settings
570
- @param value (string) the new character to add */
613
+ /** Update the text field with the selected value.
614
+ @private
615
+ @param inst {object} The instance settings.
616
+ @param value {string} The new character to add. */
571
617
  _selectValue: function(inst, value) {
572
618
  this.insertValue(inst._input[0], value);
573
619
  this._setValue(inst, inst._input.val());
574
620
  this._notifyKeypress(inst, value);
575
621
  },
576
622
 
577
- /* Update the text field with the selected value.
578
- @param input (element) the input field or
579
- (jQuery) jQuery collection
580
- @param value (string) the new character to add */
623
+ /** Update the text field with the selected value.
624
+ @param input {string|Element|jQuery} The jQuery selector, input field, or jQuery collection.
625
+ @param value {string} The new character to add.
626
+ @example $.keypad.insertValue(field, 'abc'); */
581
627
  insertValue: function(input, value) {
582
628
  input = (input.jquery ? input : $(input));
583
- var field = input[0];
629
+ var elem = input[0];
584
630
  var newValue = input.val();
585
631
  var range = [newValue.length, newValue.length];
586
- if (field.setSelectionRange) { // Mozilla
587
- range = (input.attr('readonly') || input.attr('disabled') ?
588
- range : [field.selectionStart, field.selectionEnd]);
589
- }
590
- else if (field.createTextRange) { // IE
591
- range = (input.attr('readonly') || input.attr('disabled') ?
592
- range : this._getIERange(field));
593
- }
632
+ range = (input.attr('readonly') || input.attr('disabled') ? range :
633
+ (elem.setSelectionRange /* Mozilla */ ? [elem.selectionStart, elem.selectionEnd] :
634
+ (elem.createTextRange /* IE */ ? this._getIERange(elem) : range)));
594
635
  input.val(newValue.substr(0, range[0]) + value + newValue.substr(range[1]));
595
636
  pos = range[0] + value.length;
596
637
  if (input.is(':visible')) {
597
638
  input.focus(); // for further typing
598
639
  }
599
- if (field.setSelectionRange) { // Mozilla
640
+ if (elem.setSelectionRange) { // Mozilla
600
641
  if (input.is(':visible')) {
601
- field.setSelectionRange(pos, pos);
642
+ elem.setSelectionRange(pos, pos);
602
643
  }
603
644
  }
604
- else if (field.createTextRange) { // IE
605
- range = field.createTextRange();
645
+ else if (elem.createTextRange) { // IE
646
+ range = elem.createTextRange();
606
647
  range.move('character', pos);
607
648
  range.select();
608
649
  }
609
650
  },
610
651
 
611
- /* Get the coordinates for the selected area in the text field in IE.
612
- @param field (element) the target text field
613
- @return (int[2]) the start and end positions of the selection */
614
- _getIERange: function(field) {
615
- field.focus();
652
+ /** Get the coordinates for the selected area in the text field in IE.
653
+ @private
654
+ @param elem {Element} The target text field.
655
+ @return {number[]} The start and end positions of the selection. */
656
+ _getIERange: function(elem) {
657
+ elem.focus();
616
658
  var selectionRange = document.selection.createRange().duplicate();
617
659
  // Use two ranges: before and selection
618
- var beforeRange = this._getIETextRange(field);
660
+ var beforeRange = this._getIETextRange(elem);
619
661
  beforeRange.setEndPoint('EndToStart', selectionRange);
620
662
  // Check each range for trimmed newlines by shrinking the range by one
621
663
  // character and seeing if the text property has changed. If it has not
@@ -645,22 +687,23 @@ $.extend(Keypad.prototype, {
645
687
  return [beforeText.length, beforeText.length + selectionText.length];
646
688
  },
647
689
 
648
- /* Create an IE text range for the text field.
649
- @param field (element) the target text field
650
- @return (object) the corresponding text range */
651
- _getIETextRange: function(field) {
652
- var isInput = (field.nodeName.toLowerCase() == 'input');
653
- var range = (isInput ? field.createTextRange() : document.body.createTextRange());
690
+ /** Create an IE text range for the text field.
691
+ @private
692
+ @param elem {Element} The target text field.
693
+ @return {object} The corresponding text range. */
694
+ _getIETextRange: function(elem) {
695
+ var isInput = (elem.nodeName.toLowerCase() == 'input');
696
+ var range = (isInput ? elem.createTextRange() : document.body.createTextRange());
654
697
  if (!isInput) {
655
- range.moveToElementText(field); // Selects all the text for a textarea
698
+ range.moveToElementText(elem); // Selects all the text for a textarea
656
699
  }
657
700
  return range;
658
701
  },
659
702
 
660
- /* Set the text field to the selected value,
661
- and trigger any on change event.
662
- @param inst (object) the instance settings
663
- @param value (string) the new value for the text field */
703
+ /** Set the text field to the selected value, and trigger any on change event.
704
+ @private
705
+ @param inst {object} The instance settings.
706
+ @param value {string} The new value for the text field. */
664
707
  _setValue: function(inst, value) {
665
708
  var maxlen = inst._input.attr('maxlength');
666
709
  if (maxlen > -1) {
@@ -672,6 +715,10 @@ $.extend(Keypad.prototype, {
672
715
  }
673
716
  },
674
717
 
718
+ /** Notify clients of a keypress.
719
+ @private
720
+ @param inst {object} The instance settings.
721
+ @param key {string} The character pressed. */
675
722
  _notifyKeypress: function(inst, key) {
676
723
  if ($.isFunction(inst.options.onKeypress)) { // trigger custom callback
677
724
  inst.options.onKeypress.apply((inst._input ? inst._input[0] : null),
@@ -679,9 +726,10 @@ $.extend(Keypad.prototype, {
679
726
  }
680
727
  },
681
728
 
682
- /* Generate the HTML for the current state of the keypad.
683
- @param inst (object) the instance settings
684
- @return (jQuery) the HTML for this keypad */
729
+ /** Generate the HTML for the current state of the keypad.
730
+ @private
731
+ @param inst {object} The instance settings.
732
+ @return {jQuery} The HTML for this keypad. */
685
733
  _generateHTML: function(inst) {
686
734
  var html = (!inst.options.prompt ? '' : '<div class="' + this._promptClass +
687
735
  (inst.options.useThemeRoller ? ' ui-widget-header ui-corner-all' : '') + '">' +
@@ -727,10 +775,10 @@ $.extend(Keypad.prototype, {
727
775
  return html;
728
776
  },
729
777
 
730
- /* Check whether characters should be randomised,
731
- and, if so, produce the randomised layout.
732
- @param inst (object) the instance settings
733
- @return (string[]) the layout with any requested randomisations applied */
778
+ /** Check whether characters should be randomised, and, if so, produce the randomised layout.
779
+ @private
780
+ @param inst {object} The instance settings.
781
+ @return {string[]} The layout with any requested randomisations applied. */
734
782
  _randomiseLayout: function(inst) {
735
783
  if (!inst.options.randomiseNumeric && !inst.options.randomiseAlphabetic &&
736
784
  !inst.options.randomiseOther && !inst.options.randomiseAll) {
@@ -789,35 +837,38 @@ $.extend(Keypad.prototype, {
789
837
  return newLayout;
790
838
  },
791
839
 
792
- /* Is a given character a control character?
793
- @param ch (char) the character to test
794
- @return (boolean) true if a control character, false if not */
840
+ /** Is a given character a control character?
841
+ @private
842
+ @param ch {string} The character to test.
843
+ @return {boolean} True if a control character, false if not. */
795
844
  _isControl: function(ch) {
796
845
  return ch < ' ';
797
846
  },
798
847
 
799
- /* Is a given character alphabetic?
800
- @param ch (char) the character to test
801
- @return (boolean) true if alphabetic, false if not */
848
+ /** Is a given character alphabetic?
849
+ @param ch {string} The character to test.
850
+ @return {boolean} True if alphabetic, false if not. */
802
851
  isAlphabetic: function(ch) {
803
852
  return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
804
853
  },
805
854
 
806
- /* Is a given character numeric?
807
- @param ch (char) the character to test
808
- @return (boolean) true if numeric, false if not */
855
+ /** Is a given character numeric?
856
+ @param ch {string} The character to test.
857
+ @return {boolean} True if numeric, false if not. */
809
858
  isNumeric: function(ch) {
810
859
  return (ch >= '0' && ch <= '9');
811
860
  },
812
861
 
813
- /* Convert a character to upper case.
814
- @param ch (char) the character to convert
815
- @return (char) its uppercase version */
862
+ /** Convert a character to upper case.
863
+ @param ch {string} The character to convert.
864
+ @return {string} Its uppercase version. */
816
865
  toUpper: function(ch) {
817
866
  return ch.toUpperCase();
818
867
  },
819
- /* Randomise the contents of an array.
820
- @param values (string[]) the array to rearrange */
868
+
869
+ /** Randomise the contents of an array.
870
+ @private
871
+ @param values {string[]} The array to rearrange. */
821
872
  _shuffle: function(values) {
822
873
  for (var i = values.length - 1; i > 0; i--) {
823
874
  var j = Math.floor(Math.random() * values.length);
@@ -826,53 +877,41 @@ $.extend(Keypad.prototype, {
826
877
  values[j] = ch;
827
878
  }
828
879
  }
829
- });
830
-
831
- // The list of commands that return values and don't permit chaining
832
- var getters = ['isDisabled'];
833
-
834
- /* Determine whether a command is a getter and doesn't permit chaining.
835
- @param command (string, optional) the command to run
836
- @param otherArgs ([], optional) any other arguments for the command
837
- @return true if the command is a getter, false if not */
838
- function isNotChained(command, otherArgs) {
839
- if (command == 'option' && (otherArgs.length == 0 ||
840
- (otherArgs.length == 1 && typeof otherArgs[0] == 'string'))) {
841
- return true;
842
- }
843
- return $.inArray(command, getters) > -1;
844
- }
845
-
846
- /* Invoke the keypad functionality.
847
- @param options (object) the new settings to use for these instances (optional) or
848
- (string) the command to run (optional)
849
- @return (jQuery) for chaining further calls or
850
- (any) getter value */
851
- $.fn.keypad = function(options) {
852
- var otherArgs = Array.prototype.slice.call(arguments, 1);
853
- if (isNotChained(options, otherArgs)) {
854
- return plugin['_' + options + 'Plugin'].apply(plugin, [this[0]].concat(otherArgs));
855
- }
856
- return this.each(function() {
857
- if (typeof options == 'string') {
858
- if (!plugin['_' + options + 'Plugin']) {
859
- throw 'Unknown command: ' + options;
860
- }
861
- plugin['_' + options + 'Plugin'].apply(plugin, [this].concat(otherArgs));
862
- }
863
- else {
864
- plugin._attachPlugin(this, options || {});
865
- }
866
880
  });
867
- };
868
881
 
869
- /* Initialise the keypad functionality. */
870
- var plugin = $.keypad = new Keypad(); // Singleton instance
882
+ var plugin = $.keypad;
871
883
 
872
- // Add the keypad division and external click check
873
- $(function() {
884
+ // Initialise the key definitions
885
+ plugin.addKeyDef('CLOSE', 'close', function(inst) {
886
+ plugin._curInst = (inst._inline ? inst : plugin._curInst);
887
+ plugin.hide();
888
+ });
889
+ plugin.addKeyDef('CLEAR', 'clear', function(inst) { plugin._clearValue(inst); });
890
+ plugin.addKeyDef('BACK', 'back', function(inst) { plugin._backValue(inst); });
891
+ plugin.addKeyDef('SHIFT', 'shift', function(inst) { plugin._shiftKeypad(inst); });
892
+ plugin.addKeyDef('SPACE_BAR', 'spacebar', function(inst) { plugin._selectValue(inst, ' '); }, true);
893
+ plugin.addKeyDef('SPACE', 'space');
894
+ plugin.addKeyDef('HALF_SPACE', 'half-space');
895
+ plugin.addKeyDef('ENTER', 'enter', function(inst) { plugin._selectValue(inst, '\x0D'); }, true);
896
+ plugin.addKeyDef('TAB', 'tab', function(inst) { plugin._selectValue(inst, '\x09'); }, true);
897
+
898
+ // Initialise the layouts and settings
899
+ plugin.numericLayout = ['123' + plugin.CLOSE, '456' + plugin.CLEAR, '789' + plugin.BACK, plugin.SPACE + '0'];
900
+ plugin.qwertyLayout = ['!@#$%^&*()_=' + plugin.HALF_SPACE + plugin.SPACE + plugin.CLOSE,
901
+ plugin.HALF_SPACE + '`~[]{}<>\\|/' + plugin.SPACE + '789',
902
+ 'qwertyuiop\'"' + plugin.HALF_SPACE + '456',
903
+ plugin.HALF_SPACE + 'asdfghjkl;:' + plugin.SPACE + '123',
904
+ plugin.SPACE + 'zxcvbnm,.?' + plugin.SPACE + plugin.HALF_SPACE + '-0+',
905
+ '' + plugin.TAB + plugin.ENTER + plugin.SPACE_BAR + plugin.SHIFT +
906
+ plugin.HALF_SPACE + plugin.BACK + plugin.CLEAR],
907
+ $.extend(plugin.regionalOptions[''], {alphabeticLayout: plugin.qwertyAlphabetic, fullLayout: plugin.qwertyLayout,
908
+ isAlphabetic: plugin.isAlphabetic, isNumeric: plugin.isNumeric, toUpper: plugin.toUpper});
909
+ plugin.setDefaults($.extend({layout: plugin.numericLayout}, plugin.regionalOptions['']));
910
+
911
+ // Add the keypad division and external click check
912
+ $(function() {
874
913
  $(document.body).append(plugin.mainDiv).
875
914
  mousedown(plugin._checkExternalClick);
876
- });
915
+ });
877
916
 
878
917
  })(jQuery);