autonumeric-rails 1.9.42 → 1.9.43

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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 476453bed29c427d18ee7ad9b9b2a7409d6938d9
4
- data.tar.gz: f67a388acd21538c0af5eec413ca5b503e6a8102
3
+ metadata.gz: 9ed549bef320d06305343a6e57f2fc1d49092eea
4
+ data.tar.gz: 785838c92068d1cc922ac4afc68e15509b54843e
5
5
  SHA512:
6
- metadata.gz: d1c9f5409c82a95dc2c848ca36c1653325d4166990ab8408036b2ca7629a4ed151ea1e1e7d49fd03bc196a1bc45e6908188794c7c089690a679ffcbb2d614eec
7
- data.tar.gz: 29f6f16d8da940d454ca70e24dfd87fe893e87828ce7da19136433e5dba1b28b9ba9987b0557071cec0cef812379f40b11d31afcb9bf4cb679f1f6ef3ef48ccf
6
+ metadata.gz: 37e5cc8999fe10f3cbec6a598f516a901215e9139ae0e9c8d5076d4999b8708e971e7045186e818ecc3b43143185488d50620ad24e21131baa3975dda7bacc61
7
+ data.tar.gz: e537770091e2a11bc4ed0bdf94863655f8b2bf12bf2972c9195d07d802dd0cc80acc108ebafb28cd345e844624d025d52a42dd039656ae8615a35dab0e62aacf
data/.gitignore CHANGED
@@ -17,7 +17,6 @@ spec/reports
17
17
  test/tmp
18
18
  test/version_tmp
19
19
  tmp
20
- .idea
21
20
  .ruby-version
22
21
  .rbenv-gemsets
23
22
  vendor/assets/javascripts/autonumeric_ujs.js.coffee
@@ -1,3 +1,7 @@
1
+ ### 1.9.43
2
+
3
+ - Update autoNumeric v 1.9.43
4
+
1
5
  ### 1.9.42
2
6
 
3
7
  - Update autoNumeric v 1.9.42
@@ -1,5 +1,5 @@
1
1
  module Autonumeric
2
2
  module Rails
3
- VERSION = '1.9.42'
3
+ VERSION = '1.9.43'
4
4
  end
5
5
  end
@@ -13,7 +13,7 @@
13
13
 
14
14
  ActiveRecord::Schema.define(version: 20131227002328) do
15
15
 
16
- create_table "records", force: true do |t|
16
+ create_table "records", force: :cascade do |t|
17
17
  t.decimal "field1", precision: 10, scale: 8
18
18
  t.decimal "field2", precision: 10, scale: 8
19
19
  end
@@ -0,0 +1,6 @@
1
+ def setup_dummy_library(lib)
2
+ path = Rails.root.join 'spec', 'dummy', 'app', 'assets', 'javascripts', 'application.js'
3
+ text = "//= require jquery\n//= require #{lib}\n"
4
+
5
+ File.open(path.to_s, 'w') { |io| io.write text }
6
+ end
@@ -2,7 +2,7 @@
2
2
  * autoNumeric.js
3
3
  * @author: Bob Knothe
4
4
  * @author: Sokolov Yura
5
- * @version: 1.9.42 - 2015-11-20 GMT 3:00 PM / 15:00
5
+ * @version: 1.9.43 - 2015-12-19 GMT 4:00 PM / 16:00
6
6
  *
7
7
  * Created by Robert J. Knothe on 2010-10-25. Please report any bugs to https://github.com/BobKnothe/autoNumeric
8
8
  * Contributor by Sokolov Yura on 2010-11-07
@@ -32,7 +32,18 @@
32
32
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33
33
  * OTHER DEALINGS IN THE SOFTWARE.
34
34
  */
35
- (function ($) {
35
+ (function (factory) {
36
+ if (typeof define === "function" && define.amd) {
37
+ /** AMD. Register as an anonymous module. */
38
+ define(["jquery"], factory);
39
+ } else if (typeof module === "object" && module.exports) {
40
+ /** Node/CommonJS */
41
+ module.exports = factory(require("jquery"));
42
+ } else {
43
+ /** Browser globals */
44
+ factory(window.jQuery);
45
+ }
46
+ }(function ($) {
36
47
  "use strict";
37
48
  /*jslint browser: true*/
38
49
  /*global jQuery: false*/
@@ -42,6 +53,7 @@
42
53
  /**
43
54
  * Cross browser routine for getting selected range/cursor position
44
55
  */
56
+
45
57
  function getElementSelection(that) {
46
58
  var position = {};
47
59
  if (that.selectionStart === undefined) {
@@ -62,6 +74,7 @@
62
74
  /**
63
75
  * Cross browser routine for setting selected range/cursor position
64
76
  */
77
+
65
78
  function setElementSelection(that, start, end) {
66
79
  if (that.selectionStart === undefined) {
67
80
  that.focus();
@@ -82,6 +95,7 @@
82
95
  * - a function, which invoked with jQuery element, parameters and this parameter name and returns parameter value
83
96
  * - a name of function, attached to $(selector).autoNumeric.functionName(){} - which was called previously
84
97
  */
98
+
85
99
  function runCallbacks($this, settings) {
86
100
  /**
87
101
  * loops through the settings object (option array) to find the following
@@ -103,8 +117,9 @@
103
117
  /**
104
118
  * Converts the vMin, vMax & mDec string to numeric value
105
119
  */
120
+
106
121
  function convertKeyToNumber(settings, key) {
107
- if (typeof (settings[key]) === 'string') {
122
+ if (typeof(settings[key]) === 'string') {
108
123
  settings[key] *= 1;
109
124
  }
110
125
  }
@@ -113,6 +128,7 @@
113
128
  * Preparing user defined options for further usage
114
129
  * merge them with defaults appropriately
115
130
  */
131
+
116
132
  function autoCode($this, settings) {
117
133
  runCallbacks($this, settings);
118
134
  settings.tagList = ['b', 'caption', 'cite', 'code', 'dd', 'del', 'div', 'dfn', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ins', 'kdb', 'label', 'li', 'output', 'p', 'q', 's', 'sample', 'span', 'strong', 'td', 'th', 'u', 'var'];
@@ -159,6 +175,7 @@
159
175
  /**
160
176
  * strips all unwanted characters and leave only a number alert
161
177
  */
178
+
162
179
  function autoStrip(s, settings, strip_zero) {
163
180
  if (settings.aSign) { /** remove currency sign */
164
181
  while (s.indexOf(settings.aSign) > -1) {
@@ -198,6 +215,7 @@
198
215
  * places or removes brackets on negative values
199
216
  * works only when with pSign: 'p'
200
217
  */
218
+
201
219
  function negativeBracket(s, settings) {
202
220
  if (settings.pSign === 'p') {
203
221
  var brackets = settings.nBracket.split(',');
@@ -215,6 +233,7 @@
215
233
  /**
216
234
  * function to handle numbers less than 0 that are stored in Exponential notation ex: .0000001 stored as 1e-7
217
235
  */
236
+
218
237
  function checkValue(value, settings) {
219
238
  if (value) {
220
239
  var checkSmall = +value;
@@ -247,6 +266,7 @@
247
266
  /**
248
267
  * prepare number string to be converted to real number
249
268
  */
269
+
250
270
  function fixNumber(s, aDec, aNeg) {
251
271
  if (aDec && aDec !== '.') {
252
272
  s = s.replace(aDec, '.');
@@ -263,6 +283,7 @@
263
283
  /**
264
284
  * prepare real number to be converted to our format
265
285
  */
286
+
266
287
  function presentNumber(s, aDec, aNeg) {
267
288
  if (aNeg && aNeg !== '-') {
268
289
  s = s.replace('-', aNeg);
@@ -276,6 +297,7 @@
276
297
  /**
277
298
  * private function to check for empty value
278
299
  */
300
+
279
301
  function checkEmpty(iv, settings, signOnEmpty) {
280
302
  if (iv === '' || iv === settings.aNeg) {
281
303
  if (settings.wEmpty === 'zero') {
@@ -292,6 +314,7 @@
292
314
  /**
293
315
  * private function that formats our number
294
316
  */
317
+
295
318
  function autoGroup(iv, settings) {
296
319
  iv = autoStrip(iv, settings);
297
320
  var testNeg = iv.replace(',', '.'),
@@ -345,6 +368,7 @@
345
368
  * please note this handled as text - JavaScript math function can return inaccurate values
346
369
  * also this offers multiple rounding methods that are not easily accomplished in JavaScript
347
370
  */
371
+
348
372
  function autoRound(iv, settings) { /** value to string */
349
373
  iv = (iv === '') ? '0' : iv.toString();
350
374
  convertKeyToNumber(settings, 'mDec'); /** set mDec to number needed when mDec set by 'update method */
@@ -354,7 +378,7 @@
354
378
  var ivRounded = '',
355
379
  i = 0,
356
380
  nSign = '',
357
- rDec = (typeof (settings.aPad) === 'boolean' || settings.aPad === null) ? (settings.aPad ? settings.mDec : 0) : +settings.aPad;
381
+ rDec = (typeof(settings.aPad) === 'boolean' || settings.aPad === null) ? (settings.aPad ? settings.mDec : 0) : +settings.aPad;
358
382
  var truncateZeros = function (ivRounded) { /** truncate not needed zeros */
359
383
  var regex = (rDec === 0) ? (/(\.(?:\d*[1-9])?)0*$/) : rDec === 1 ? (/(\.\d(?:\d*[1-9])?)0*$/) : new RegExp('(\\.\\d{' + rDec + '}(?:\\d*[1-9])?)0*$');
360
384
  ivRounded = ivRounded.replace(regex, '$1'); /** If there are no decimal places, we don't need a decimal point at the end */
@@ -464,6 +488,7 @@
464
488
  /**
465
489
  * truncate decimal part of a number
466
490
  */
491
+
467
492
  function truncateDecimal(s, settings, paste) {
468
493
  var aDec = settings.aDec,
469
494
  mDec = settings.mDec;
@@ -489,6 +514,7 @@
489
514
  * and lays between settings.vMin and settings.vMax
490
515
  * and the string length does not exceed the digits in settings.vMin and settings.vMax
491
516
  */
517
+
492
518
  function autoCheck(s, settings) {
493
519
  s = autoStrip(s, settings);
494
520
  s = truncateDecimal(s, settings);
@@ -500,6 +526,7 @@
500
526
  /**
501
527
  * Holder object for field properties
502
528
  */
529
+
503
530
  function AutoNumericHolder(that, settings) {
504
531
  this.settings = settings;
505
532
  this.that = that;
@@ -862,6 +889,7 @@
862
889
  /**
863
890
  * thanks to Anthony & Evan C
864
891
  */
892
+
865
893
  function autoGet(obj) {
866
894
  if (typeof obj === 'string') {
867
895
  obj = obj.replace(/\[/g, "\\[").replace(/\]/g, "\\]");
@@ -876,6 +904,7 @@
876
904
  * function to attach data to the element
877
905
  * and imitate the holder
878
906
  */
907
+
879
908
  function getHolder($that, settings, update) {
880
909
  var data = $that.data('autoNumeric');
881
910
  if (!data) {
@@ -903,8 +932,10 @@
903
932
  init: function (options) {
904
933
  return this.each(function () {
905
934
  var $this = $(this),
906
- settings = $this.data('autoNumeric'), /** attempt to grab 'autoNumeric' settings, if they don't exist returns "undefined". */
907
- tagData = $this.data(), /** attempt to grab HTML5 data, if they don't exist we'll get "undefined".*/
935
+ settings = $this.data('autoNumeric'),
936
+ /** attempt to grab 'autoNumeric' settings, if they don't exist returns "undefined". */
937
+ tagData = $this.data(),
938
+ /** attempt to grab HTML5 data, if they don't exist we'll get "undefined".*/
908
939
  $input = $this.is('input[type=text], input[type=hidden], input[type=tel], input:not([type])');
909
940
  if (typeof settings !== 'object') { /** If we couldn't grab settings, create them from defaults and passed options. */
910
941
  settings = $.extend({}, $.fn.autoNumeric.defaults, tagData, options, {
@@ -1216,10 +1247,14 @@
1216
1247
  formParts = formFields.split('&'),
1217
1248
  formIndex = $('form').index($this),
1218
1249
  allFormElements = $('form:eq(' + formIndex + ')'),
1219
- aiIndex = [], /* all input index */
1220
- scIndex = [], /* successful control index */
1221
- rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, /* from jQuery serialize method */
1222
- rsubmittable = /^(?:input|select|textarea|keygen)/i, /* from jQuery serialize method */
1250
+ aiIndex = [],
1251
+ /* all input index */
1252
+ scIndex = [],
1253
+ /* successful control index */
1254
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
1255
+ /* from jQuery serialize method */
1256
+ rsubmittable = /^(?:input|select|textarea|keygen)/i,
1257
+ /* from jQuery serialize method */
1223
1258
  rcheckableType = /^(?:checkbox|radio)$/i,
1224
1259
  rnonAutoNumericTypes = /^(?:button|checkbox|color|date|datetime|datetime-local|email|file|image|month|number|password|radio|range|reset|search|submit|time|url|week)/i,
1225
1260
  count = 0;
@@ -1280,10 +1315,14 @@
1280
1315
  formFields = $this.serializeArray(),
1281
1316
  formIndex = $('form').index($this),
1282
1317
  allFormElements = $('form:eq(' + formIndex + ')'),
1283
- aiIndex = [], /* all input index */
1284
- scIndex = [], /* successful control index */
1285
- rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, /* from jQuery serialize method */
1286
- rsubmittable = /^(?:input|select|textarea|keygen)/i, /* from jQuery serialize method */
1318
+ aiIndex = [],
1319
+ /* all input index */
1320
+ scIndex = [],
1321
+ /* successful control index */
1322
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
1323
+ /* from jQuery serialize method */
1324
+ rsubmittable = /^(?:input|select|textarea|keygen)/i,
1325
+ /* from jQuery serialize method */
1287
1326
  rcheckableType = /^(?:checkbox|radio)$/i,
1288
1327
  rnonAutoNumericTypes = /^(?:button|checkbox|color|date|datetime|datetime-local|email|file|image|month|number|password|radio|range|reset|search|submit|time|url|week)/i,
1289
1328
  count = 0;
@@ -1462,4 +1501,4 @@
1462
1501
  */
1463
1502
  anDefault: null
1464
1503
  };
1465
- }(jQuery));
1504
+ }));
@@ -0,0 +1,2018 @@
1
+ /**
2
+ * autoNumeric.js
3
+ * @author: Bob Knothe
4
+ * @contributor: Sokolov Yura
5
+ * @version: 2.0-beta - 2015-12-19 GMT 4:00 PM / 16:00
6
+ *
7
+ * Created by Robert J. Knothe on 2009-08-09. Please report any bugs to https://github.com/BobKnothe/autoNumeric
8
+ *
9
+ * Copyright (c) 2009 Robert J. Knothe http://www.decorplanit.com/plugin/
10
+ *
11
+ * The MIT License (http://www.opensource.org/licenses/mit-license.php)
12
+ *
13
+ * Permission is hereby granted, free of charge, to any person
14
+ * obtaining a copy of this software and associated documentation
15
+ * files (the "Software"), to deal in the Software without
16
+ * restriction, including without limitation the rights to use,
17
+ * copy, modify, merge, publish, distribute, sub license, and/or sell
18
+ * copies of the Software, and to permit persons to whom the
19
+ * Software is furnished to do so, subject to the following
20
+ * conditions:
21
+ *
22
+ * The above copyright notice and this permission notice shall be
23
+ * included in all copies or substantial portions of the Software.
24
+ *
25
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
27
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
29
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
30
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
31
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
32
+ * OTHER DEALINGS IN THE SOFTWARE.
33
+ */
34
+ (function (factory) {
35
+ if (typeof define === "function" && define.amd) {
36
+ /** AMD. Register as an anonymous module. */
37
+ define(["jquery"], factory);
38
+ } else if (typeof module === "object" && module.exports) {
39
+ /** Node/CommonJS */
40
+ module.exports = factory(require("jquery"));
41
+ } else {
42
+ /** Browser globals */
43
+ factory(window.jQuery);
44
+ }
45
+ }(function ($) {
46
+ "use strict";
47
+ /*jslint browser: true, bitwise: true*/
48
+ /*global jQuery: false, sessionStorage: false*/
49
+
50
+ /**
51
+ * Cross browser routine for getting selected range/cursor position
52
+ */
53
+ function getElementSelection(that) {
54
+ var position = {};
55
+ if (that.selectionStart === undefined) {
56
+ that.focus();
57
+ var select = document.selection.createRange();
58
+ position.length = select.text.length;
59
+ select.moveStart('character', -that.value.length);
60
+ position.end = select.text.length;
61
+ position.start = position.end - position.length;
62
+ } else {
63
+ position.start = that.selectionStart;
64
+ position.end = that.selectionEnd;
65
+ position.length = position.end - position.start;
66
+ }
67
+ return position;
68
+ }
69
+
70
+ /**
71
+ * Cross browser routine for setting selected range/cursor position
72
+ */
73
+ function setElementSelection(that, start, end) {
74
+ if (that.selectionStart === undefined) {
75
+ that.focus();
76
+ var r = that.createTextRange();
77
+ r.collapse(true);
78
+ r.moveEnd('character', end);
79
+ r.moveStart('character', start);
80
+ r.select();
81
+ } else {
82
+ that.selectionStart = start;
83
+ that.selectionEnd = end;
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Function to handle errors messages
89
+ */
90
+ function throwErr(message, debug) {
91
+ if (debug) {
92
+ var err = new Error(message);
93
+ throw err;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * run callbacks in parameters if any
99
+ * any parameter could be a callback:
100
+ * - a function, which invoked with jQuery element, parameters and this parameter name and returns parameter value
101
+ * - a name of function, attached to $(selector).autoNumeric.functionName(){} - which was called previously
102
+ */
103
+ function runCallbacks($this, settings) {
104
+ /**
105
+ * loops through the settings object (option array) to find the following
106
+ * k = option name example k=aNum
107
+ * val = option value example val=0123456789
108
+ */
109
+ $.each(settings, function (k, val) {
110
+ if (typeof val === 'function') {
111
+ settings[k] = val($this, settings, k);
112
+ } else if (typeof $this.autoNumeric[val] === 'function') {
113
+ /**
114
+ * calls the attached function from the html5 data example: data-a-sign="functionName"
115
+ */
116
+ settings[k] = $this.autoNumeric[val]($this, settings, k);
117
+ }
118
+ });
119
+ }
120
+
121
+ /**
122
+ * Preparing user defined options for further usage
123
+ * merge them with defaults appropriately
124
+ */
125
+ function autoCode($this, settings) {
126
+ runCallbacks($this, settings);
127
+ var vmax = settings.vMax.toString().split('.'),
128
+ vmin = (!settings.vMin && settings.vMin !== 0) ? [] : settings.vMin.toString().split('.');
129
+ settings.aNeg = settings.vMin < 0 ? '-' : '';
130
+ vmax[0] = vmax[0].replace('-', '');
131
+ vmin[0] = vmin[0].replace('-', '');
132
+ settings.mIntPos = Math.max(vmax[0].length, 1);
133
+ settings.mIntNeg = Math.max(vmin[0].length, 1);
134
+ if (settings.mDec === null) {
135
+ var vmaxLength = 0,
136
+ vminLength = 0;
137
+ if (vmax[1]) {
138
+ vmaxLength = vmax[1].length;
139
+ }
140
+ if (vmin[1]) {
141
+ vminLength = vmin[1].length;
142
+ }
143
+ settings.mDec = Math.max(vmaxLength, vminLength);
144
+ settings.oDec = settings.mDec;
145
+ } else {
146
+ settings.mDec = Number(settings.mDec);
147
+ }
148
+ /** set alternative decimal separator key */
149
+ if (settings.altDec === null && settings.mDec > 0) {
150
+ if (settings.aDec === '.' && settings.aSep !== ',') {
151
+ settings.altDec = ',';
152
+ } else if (settings.aDec === ',' && settings.aSep !== '.') {
153
+ settings.altDec = '.';
154
+ }
155
+ }
156
+ /** cache regexps for autoStrip */
157
+ var aNegReg = settings.aNeg ? '([-\\' + settings.aNeg + ']?)' : '(-?)';
158
+ settings.aNegRegAutoStrip = aNegReg;
159
+ settings.skipFirstAutoStrip = new RegExp(aNegReg + '[^-' + (settings.aNeg ? '\\' + settings.aNeg : '') + '\\' + settings.aDec + '\\d]' + '.*?(\\d|\\' + settings.aDec + '\\d)');
160
+ settings.skipLastAutoStrip = new RegExp('(\\d\\' + settings.aDec + '?)[^\\' + settings.aDec + '\\d]\\D*$');
161
+ var allowed = '-' + settings.aNum + '\\' + settings.aDec;
162
+ settings.allowedAutoStrip = new RegExp('[^' + allowed + ']', 'gi');
163
+ settings.numRegAutoStrip = new RegExp(aNegReg + '(?:\\' + settings.aDec + '?(\\d+\\' + settings.aDec + '\\d+)|(\\d*(?:\\' + settings.aDec + '\\d*)?))');
164
+ return settings;
165
+ }
166
+
167
+ /**
168
+ * strip all unwanted characters and leave only a number alert
169
+ */
170
+ function autoStrip(s, settings) {
171
+ if (settings.aSign !== '') { /** remove currency sign */
172
+ s = s.replace(settings.aSign, '');
173
+ }
174
+ if (settings.aSuffix) { /** remove suffix */
175
+ while (s.indexOf(settings.aSuffix) > -1) {
176
+ s = s.replace(settings.aSuffix, '');
177
+ }
178
+ }
179
+ s = s.replace(settings.skipFirstAutoStrip, '$1$2'); /** first replace anything before digits */
180
+ if ((settings.pNeg === 's' || (settings.pSign === 's' && settings.pNeg !== 'p')) && s.indexOf('-') > -1 && s !== '') {
181
+ settings.trailingNegative = true;
182
+ }
183
+ s = s.replace(settings.skipLastAutoStrip, '$1'); /** then replace anything after digits */
184
+ s = s.replace(settings.allowedAutoStrip, ''); /** then remove any uninterested characters */
185
+ if (settings.altDec) {
186
+ s = s.replace(settings.altDec, settings.aDec);
187
+ } /** get only number string */
188
+ var m = s.match(settings.numRegAutoStrip);
189
+ s = m ? [m[1], m[2], m[3]].join('') : '';
190
+ if (settings.lZero === 'allow' || settings.lZero === 'keep') {
191
+ var parts = [],
192
+ nSign = '';
193
+ parts = s.split(settings.aDec);
194
+ if (parts[0].indexOf(settings.aNeg) !== -1) {
195
+ nSign = settings.aNeg;
196
+ parts[0] = parts[0].replace(settings.aNeg, '');
197
+ }
198
+ if (nSign === "" && parts[0].length > settings.mIntPos && parts[0].charAt(0) === '0') { /** strip leading zero if need */
199
+ parts[0] = parts[0].slice(1);
200
+ }
201
+ if (nSign !== '' && parts[0].length > settings.mIntNeg && parts[0].charAt(0) === '0') { /** strip leading zero if need */
202
+ parts[0] = parts[0].slice(1);
203
+ }
204
+ s = nSign + parts.join(settings.aDec);
205
+ }
206
+ if ((settings.onOff && settings.lZero === 'deny') || (settings.lZero === 'allow' && settings.onOff === false)) {
207
+ var strip_reg = '^' + settings.aNegRegAutoStrip + '0*(\\d|$)';
208
+ strip_reg = new RegExp(strip_reg);
209
+ s = s.replace(strip_reg, '$1$2');
210
+ }
211
+ return s;
212
+ }
213
+
214
+ /**
215
+ * places or removes brackets on negative values
216
+ */
217
+ function negativeBracket(s, settings) {
218
+ if ((settings.pSign === 'p' && settings.pNeg === 'l') || (settings.pSign === 's' && settings.pNeg === 'p')) {
219
+ var brackets = settings.nBracket.split(',');
220
+ if (!settings.onOff) {
221
+ s = s.replace(settings.aNeg, '');
222
+ s = brackets[0] + s + brackets[1];
223
+ } else if (settings.onOff && s.charAt(0) === brackets[0]) {
224
+ s = s.replace(brackets[0], settings.aNeg);
225
+ s = s.replace(brackets[1], '');
226
+ }
227
+ }
228
+ return s;
229
+ }
230
+
231
+ /**
232
+ * convert locale format to javaSript numeric string
233
+ * allows locale decimal separator to be a period or comma - no thousand separator allowed of currency signs allowed
234
+ * '1234.56' OK
235
+ * '-1234.56' OK
236
+ * '1234.56-' OK
237
+ * '1234,56' OK
238
+ * '-1234,56' OK
239
+ * '1234,56-' OK
240
+ */
241
+ function convertLocale(s) {
242
+ s = s.replace(',', '.');
243
+ if (s.lastIndexOf('-') !== -1 && s.lastIndexOf('-') === s.length - 1) {
244
+ s = s.replace('-', '');
245
+ s = '-' + s;
246
+ }
247
+ return s;
248
+ }
249
+
250
+ /**
251
+ * prepare number string to be converted to real number
252
+ */
253
+ function fixNumber(s, aDec, aNeg) {
254
+ if (aDec && aDec !== '.') {
255
+ s = s.replace(aDec, '.');
256
+ }
257
+ if (aNeg && aNeg !== '-') {
258
+ s = s.replace(aNeg, '-');
259
+ }
260
+ if (!s.match(/\d/)) {
261
+ s += '0';
262
+ }
263
+ return s;
264
+ }
265
+
266
+ /**
267
+ * prepare real number to be converted to our format
268
+ */
269
+ function presentNumber(s, aDec, aNeg) {
270
+ if (aNeg && aNeg !== '-') {
271
+ s = s.replace('-', aNeg);
272
+ }
273
+ if (aDec && aDec !== '.') {
274
+ s = s.replace('.', aDec);
275
+ }
276
+ return s;
277
+ }
278
+
279
+ /**
280
+ * private function to check for empty value
281
+ */
282
+ function checkEmpty(iv, settings, signOnEmpty) {
283
+ if (iv === '' || iv === settings.aNeg) {
284
+ if (settings.wEmpty === 'always' || signOnEmpty) {
285
+ return (settings.pNeg === 'l') ? iv + settings.aSign + settings.aSuffix : settings.aSign + iv + settings.aSuffix;
286
+ }
287
+ return iv;
288
+ }
289
+ return null;
290
+ }
291
+
292
+ /**
293
+ * private function that formats our number
294
+ */
295
+ function autoGroup(iv, settings) {
296
+ iv = autoStrip(iv, settings);
297
+ if (settings.trailingNegative && iv.indexOf('-') === -1) {
298
+ iv = '-' + iv;
299
+ }
300
+ var empty = checkEmpty(iv, settings, true),
301
+ isNeg = iv.replace(',', '.') < 0;
302
+ if (iv.indexOf('-') > -1 && Number(iv) === 0) {
303
+ isNeg = true;
304
+ }
305
+ if (isNeg) {
306
+ iv = iv.replace('-', '');
307
+ }
308
+ if (empty !== null) {
309
+ return empty;
310
+ }
311
+ var digitalGroup = '';
312
+ settings.dGroup = settings.dGroup.toString();
313
+ if (settings.dGroup === '2') {
314
+ digitalGroup = /(\d)((\d)(\d{2}?)+)$/;
315
+ } else if (settings.dGroup === '2s') {
316
+ digitalGroup = /(\d)((?:\d{2}){0,2}\d{3}(?:(?:\d{2}){2}\d{3})*?)$/;
317
+ } else if (settings.dGroup === '4') {
318
+ digitalGroup = /(\d)((\d{4}?)+)$/;
319
+ } else {
320
+ digitalGroup = /(\d)((\d{3}?)+)$/;
321
+ } /** splits the string at the decimal string */
322
+ var ivSplit = iv.split(settings.aDec);
323
+ if (settings.altDec && ivSplit.length === 1) {
324
+ ivSplit = iv.split(settings.altDec);
325
+ } /** assigns the whole number to the a variable (s) */
326
+ var s = ivSplit[0];
327
+ if (settings.aSep !== '') {
328
+ while (digitalGroup.test(s)) { /** re-inserts the thousand separator via a regular expression */
329
+ s = s.replace(digitalGroup, '$1' + settings.aSep + '$2');
330
+ }
331
+ }
332
+ if (settings.mDec !== 0 && ivSplit.length > 1) {
333
+ if (ivSplit[1].length > settings.mDec) {
334
+ ivSplit[1] = ivSplit[1].substring(0, settings.mDec);
335
+ } /** joins the whole number with the decimal value */
336
+ iv = s + settings.aDec + ivSplit[1];
337
+ } else { /** if whole numbers only */
338
+ iv = s;
339
+ }
340
+ if (settings.pSign === 'p') {
341
+ if (isNeg && settings.pNeg === 'l') {
342
+ iv = settings.aNeg + settings.aSign + iv;
343
+ }
344
+ if (isNeg && settings.pNeg === 'r') {
345
+ iv = settings.aSign + settings.aNeg + iv;
346
+ }
347
+ if (isNeg && settings.pNeg === 's') {
348
+ iv = settings.aSign + iv + settings.aNeg;
349
+ }
350
+ if (!isNeg && !settings.trailingNegative) {
351
+ iv = settings.aSign + iv;
352
+ }
353
+ }
354
+ if (settings.pSign === 's') {
355
+ if (isNeg && settings.pNeg === 'r') {
356
+ iv = iv + settings.aSign + settings.aNeg;
357
+ }
358
+ if (isNeg && settings.pNeg === 'l') {
359
+ iv = iv + settings.aNeg + settings.aSign;
360
+ }
361
+ if (isNeg && settings.pNeg === 'p') {
362
+ iv = settings.aNeg + iv + settings.aSign;
363
+ }
364
+ if (!isNeg) {
365
+ iv = iv + settings.aSign;
366
+ }
367
+ }
368
+ if (settings.rawValue < 0 && settings.nBracket !== null) { /** removes the negative sign and places brackets */
369
+ iv = negativeBracket(iv, settings);
370
+ }
371
+ settings.trailingNegative = false;
372
+ return iv + settings.aSuffix;
373
+ }
374
+
375
+ /**
376
+ * round number after setting by pasting or $().autoNumericSet()
377
+ * private function for round the number
378
+ * please note this handled as text - JavaScript math function can return inaccurate values
379
+ * also this offers multiple rounding methods that are not easily accomplished in JavaScript
380
+ */
381
+ function autoRound(iv, settings) { /** value to string */
382
+ iv = (iv === '') ? '0' : iv.toString();
383
+ if (settings.mRound === 'N05' || settings.mRound === 'U05' || settings.mRound === 'D05') {
384
+ iv = (settings.mRound === 'N05') ? (Math.round(iv * 20) / 20).toString() : (settings.mRound === 'U05') ? (Math.ceil(iv * 20) / 20).toString() : (Math.floor(iv * 20) / 20).toString();
385
+ return (iv.indexOf('.') === -1) ? iv + '.00' : (iv.length - iv.indexOf('.') < 3) ? iv + '0' : iv;
386
+ }
387
+ var ivRounded = '',
388
+ i = 0,
389
+ nSign = '',
390
+ rDec = (typeof (settings.aPad) === 'boolean' || settings.aPad === null) ? (settings.aPad ? settings.mDec : 0) : Number(settings.aPad);
391
+ var truncateZeros = function (ivRounded) { /** truncate not needed zeros */
392
+ var regex = rDec === 0 ? (/(\.(?:\d*[1-9])?)0*$/) : rDec === 1 ? (/(\.\d(?:\d*[1-9])?)0*$/) : new RegExp('(\\.\\d{' + rDec + '}(?:\\d*[1-9])?)0*');
393
+ ivRounded = ivRounded.replace(regex, '$1'); /** If there are no decimal places, we don't need a decimal point at the end */
394
+ if (rDec === 0) {
395
+ ivRounded = ivRounded.replace(/\.$/, '');
396
+ }
397
+ return ivRounded;
398
+ };
399
+ if (iv.charAt(0) === '-') { /** Checks if the iv (input Value)is a negative value */
400
+ nSign = '-';
401
+ iv = iv.replace('-', ''); /** removes the negative sign will be added back later if required */
402
+ }
403
+ if (!iv.match(/^\d/)) { /** append a zero if first character is not a digit (then it is likely to be a dot)*/
404
+ iv = '0' + iv;
405
+ }
406
+ if (nSign === '-' && Number(iv) === 0) { /** determines if the value is zero - if zero no negative sign */
407
+ nSign = '';
408
+ }
409
+ if ((Number(iv) > 0 && settings.lZero !== 'keep') || (iv.length > 0 && settings.lZero === 'allow')) { /** trims leading zero's if needed */
410
+ iv = iv.replace(/^0*(\d)/, '$1');
411
+ }
412
+ var dPos = iv.lastIndexOf('.'),
413
+ /** virtual decimal position */
414
+ vdPos = (dPos === -1) ? iv.length - 1 : dPos,
415
+ /** checks decimal places to determine if rounding is required */
416
+ cDec = (iv.length - 1) - vdPos; /** check if no rounding is required */
417
+ if (cDec <= settings.mDec) {
418
+ ivRounded = iv; /** check if we need to pad with zeros */
419
+ if (cDec < rDec) {
420
+ if (dPos === -1) {
421
+ //ivRounded += '.';
422
+ ivRounded += settings.aDec;
423
+ }
424
+ var zeros = '000000';
425
+ while (cDec < rDec) {
426
+ zeros = zeros.substring(0, rDec - cDec);
427
+ ivRounded += zeros;
428
+ cDec += zeros.length;
429
+ }
430
+ } else if (cDec > rDec) {
431
+ ivRounded = truncateZeros(ivRounded);
432
+ } else if (cDec === 0 && rDec === 0) {
433
+ ivRounded = ivRounded.replace(/\.$/, '');
434
+ }
435
+ return (Number(ivRounded) === 0) ? ivRounded : nSign + ivRounded;
436
+ } /** rounded length of the string after rounding */
437
+ var rLength = dPos + settings.mDec,
438
+ tRound = Number(iv.charAt(rLength + 1)),
439
+ ivArray = iv.substring(0, rLength + 1).split(''),
440
+ odd = (iv.charAt(rLength) === '.') ? (iv.charAt(rLength - 1) % 2) : (iv.charAt(rLength) % 2);
441
+ /*jslint white: true*/
442
+ if ((tRound > 4 && settings.mRound === 'S') || /** Round half up symmetric */
443
+ (tRound > 4 && settings.mRound === 'A' && nSign === '') || /** Round half up asymmetric positive values */
444
+ (tRound > 5 && settings.mRound === 'A' && nSign === '-') || /** Round half up asymmetric negative values */
445
+ (tRound > 5 && settings.mRound === 's') || /** Round half down symmetric */
446
+ (tRound > 5 && settings.mRound === 'a' && nSign === '') || /** Round half down asymmetric positive values */
447
+ (tRound > 4 && settings.mRound === 'a' && nSign === '-') || /** Round half down asymmetric negative values */
448
+ (tRound > 5 && settings.mRound === 'B') || /** Round half even "Banker's Rounding" */
449
+ (tRound === 5 && settings.mRound === 'B' && odd === 1) || /** Round half even "Banker's Rounding" */
450
+ (tRound > 0 && settings.mRound === 'C' && nSign === '') || /** Round to ceiling toward positive infinite */
451
+ (tRound > 0 && settings.mRound === 'F' && nSign === '-') || /** Round to floor toward negative infinite */
452
+ (tRound > 0 && settings.mRound === 'U')) { /** Round up away from zero */
453
+ /*jslint white: false*/
454
+ for (i = (ivArray.length - 1); i >= 0; i -= 1) { /** Round up the last digit if required, and continue until no more 9's are found */
455
+ if (ivArray[i] !== '.') {
456
+ ivArray[i] = +ivArray[i] + 1;
457
+ if (ivArray[i] < 10) {
458
+ break;
459
+ }
460
+ if (i > 0) {
461
+ ivArray[i] = '0';
462
+ }
463
+ }
464
+ }
465
+ }
466
+ ivArray = ivArray.slice(0, rLength + 1); /** Reconstruct the string, converting any 10's to 0's */
467
+ ivRounded = truncateZeros(ivArray.join('')); /** return rounded value */
468
+ return (Number(ivRounded) === 0) ? ivRounded : nSign + ivRounded;
469
+ }
470
+
471
+ /**
472
+ * truncate decimal part of a number
473
+ */
474
+ function truncateDecimal(s, settings, paste) {
475
+ var aDec = settings.aDec,
476
+ mDec = settings.mDec;
477
+ s = (paste === 'paste') ? autoRound(s, settings) : s;
478
+ if (aDec && mDec) {
479
+ var parts = s.split(aDec);
480
+ /** truncate decimal part to satisfying length
481
+ * cause we would round it anyway */
482
+ if (parts[1] && parts[1].length > mDec) {
483
+ if (mDec > 0) {
484
+ parts[1] = parts[1].substring(0, mDec);
485
+ s = parts.join(aDec);
486
+ } else {
487
+ s = parts[0];
488
+ }
489
+ }
490
+ }
491
+ return s;
492
+ }
493
+
494
+ /**
495
+ * Function to parse vMin, vMax & the input value to prepare for testing to determine if the value falls within the min / max range
496
+ * Return an object example: vMin: "999999999999999.99" returns the following "{s: -1, e: 12, c: Array[15]}"
497
+ * This function is adapted from Big.js https://github.com/MikeMcl/big.js/
498
+ * Many thanks to Mike
499
+ */
500
+ function parseStr(n) {
501
+ var x = {},
502
+ e,
503
+ i,
504
+ nL,
505
+ j;
506
+ /** Minus zero? */
507
+ if (n === 0 && 1 / n < 0) {
508
+ n = '-0';
509
+ }
510
+ /** Determine sign. 1 positive, -1 negative */
511
+ if (n.charAt(0) === '-') {
512
+ n = n.slice(1);
513
+ x.s = -1;
514
+ } else {
515
+ x.s = 1;
516
+ }
517
+ /** Decimal point? */
518
+ e = n.indexOf('.');
519
+ if (e > -1) {
520
+ n = n.replace('.', '');
521
+ }
522
+ /** length of string if no decimal character */
523
+ if (e < 0) {
524
+ /** Integer. */
525
+ e = n.length;
526
+ }
527
+ /** Determine leading zeros. */
528
+ i = (n.search(/[1-9]/i) === -1) ? n.length : n.search(/[1-9]/i);
529
+ nL = n.length;
530
+ if (i === nL) {
531
+ /** Zero. */
532
+ x.e = 0;
533
+ x.c = [0];
534
+ } else {
535
+ /** Determine trailing zeros. */
536
+ for (j = nL - 1; n.charAt(j) === '0'; j -= 1) {
537
+ nL -= 1;
538
+ }
539
+ nL -= 1;
540
+ /** Decimal location. */
541
+ x.e = e - i - 1;
542
+ x.c = [];
543
+ /** Convert string to array of digits without leading/trailing zeros. */
544
+ for (e = 0; i <= nL; i += 1) {
545
+ x.c[e] = +n.charAt(i);
546
+ e += 1;
547
+ }
548
+ }
549
+ return x;
550
+ }
551
+
552
+ /**
553
+ * Function to test if the input value falls with the Min / Max settings
554
+ * This uses the parsed strings for the above parseStr function
555
+ * This function is adapted from Big.js https://github.com/MikeMcl/big.js/
556
+ * Many thanks to Mike
557
+ */
558
+ function testMinMax(y, x) {
559
+ var xNeg,
560
+ xc = x.c,
561
+ yc = y.c,
562
+ i = x.s,
563
+ j = y.s,
564
+ k = x.e,
565
+ l = y.e;
566
+ /** Either zero? */
567
+ if (!xc[0] || !yc[0]) {
568
+ return !xc[0] ? !yc[0] ? 0 : -j : i;
569
+ }
570
+ /** Signs differ? */
571
+ if (i !== j) {
572
+ return i;
573
+ }
574
+ xNeg = i < 0;
575
+ /** Compare exponents. */
576
+ if (k !== l) {
577
+ return k > l ^ xNeg ? 1 : -1;
578
+ }
579
+ i = -1;
580
+ k = xc.length;
581
+ l = yc.length;
582
+ j = (k < l) ? k : l;
583
+ /** Compare digit by digit. */
584
+ for (i += 1; i < j; i += 1) {
585
+ if (xc[i] !== yc[i]) {
586
+ return xc[i] > yc[i] ^ xNeg ? 1 : -1;
587
+ }
588
+ }
589
+ /** Compare lengths */
590
+ return k === l ? 0 : k > l ^ xNeg ? 1 : -1;
591
+ }
592
+
593
+ /**
594
+ * checking that number satisfy format conditions
595
+ * and lays between settings.vMin and settings.vMax
596
+ * and the string length does not exceed the digits in settings.vMin and settings.vMax
597
+ */
598
+ function autoCheck(s, settings) {
599
+ s = s.replace(',', '.');
600
+ var minParse = parseStr(settings.vMin),
601
+ maxParse = parseStr(settings.vMax),
602
+ valParse = parseStr(s);
603
+ return testMinMax(minParse, valParse) > -1 && testMinMax(maxParse, valParse) < 1;
604
+ }
605
+
606
+ /**
607
+ * Holder object for field properties
608
+ */
609
+ function AutoNumericHolder(that, settings) {
610
+ this.settings = settings;
611
+ this.that = that;
612
+ this.$that = $(that);
613
+ this.formatted = false;
614
+ this.settingsClone = autoCode(this.$that, this.settings);
615
+ this.value = that.value;
616
+ }
617
+ AutoNumericHolder.prototype = {
618
+ init: function (e) {
619
+ this.value = this.that.value;
620
+ this.settingsClone = autoCode(this.$that, this.settings);
621
+ this.ctrlKey = e.ctrlKey;
622
+ this.cmdKey = e.metaKey;
623
+ this.shiftKey = e.shiftKey;
624
+ this.selection = getElementSelection(this.that); /** keypress event overwrites meaningful value of e.keyCode */
625
+ if (e.type === 'keydown' || e.type === 'keyup') {
626
+ this.kdCode = e.keyCode;
627
+ }
628
+ this.which = e.which;
629
+ this.processed = false;
630
+ this.formatted = false;
631
+ },
632
+ setSelection: function (start, end, setReal) {
633
+ start = Math.max(start, 0);
634
+ end = Math.min(end, this.that.value.length);
635
+ this.selection = {
636
+ start: start,
637
+ end: end,
638
+ length: end - start
639
+ };
640
+ if (setReal === undefined || setReal) {
641
+ setElementSelection(this.that, start, end);
642
+ }
643
+ },
644
+ setPosition: function (pos, setReal) {
645
+ this.setSelection(pos, pos, setReal);
646
+ },
647
+ getBeforeAfter: function () {
648
+ var value = this.value,
649
+ left = value.substring(0, this.selection.start),
650
+ right = value.substring(this.selection.end, value.length);
651
+ return [left, right];
652
+ },
653
+ getBeforeAfterStriped: function () {
654
+ var settingsClone = this.settingsClone,
655
+ parts = this.getBeforeAfter();
656
+ parts[0] = autoStrip(parts[0], this.settingsClone);
657
+ parts[1] = autoStrip(parts[1], this.settingsClone);
658
+ if (settingsClone.trailingNegative && parts[0].indexOf('-') === -1) {
659
+ parts[0] = '-' + parts[0];
660
+ parts[1] = (parts[1] === '-') ? '' : parts[1];
661
+ }
662
+ settingsClone.trailingNegative = false;
663
+ return parts;
664
+ },
665
+
666
+ /**
667
+ * strip parts from excess characters and leading zeroes
668
+ */
669
+ normalizeParts: function (left, right) {
670
+ var settingsClone = this.settingsClone;
671
+ left = autoStrip(left, settingsClone); /** prevents multiple leading zeros from being entered */
672
+ right = autoStrip(right, settingsClone); /** if right is not empty and first character is not aDec, */
673
+ if (settingsClone.trailingNegative && left.indexOf('-') === -1) {
674
+ left = '-' + left;
675
+ settingsClone.trailingNegative = false;
676
+ }
677
+ if ((left === '' || left === settingsClone.aNeg) && settingsClone.lZero === 'deny') {
678
+ if (right > '') {
679
+ right = right.replace(/^0*(\d)/, '$1');
680
+ }
681
+ }
682
+ var new_value = left + right; /** insert zero if has leading dot */
683
+ if (settingsClone.aDec) {
684
+ var m = new_value.match(new RegExp('^' + settingsClone.aNegRegAutoStrip + '\\' + settingsClone.aDec));
685
+ if (m) {
686
+ left = left.replace(m[1], m[1] + '0');
687
+ new_value = left + right;
688
+ }
689
+ }
690
+ return [left, right];
691
+ },
692
+
693
+ /**
694
+ * set part of number to value keeping position of cursor
695
+ */
696
+ setValueParts: function (left, right, paste) {
697
+ var settingsClone = this.settingsClone,
698
+ parts = this.normalizeParts(left, right),
699
+ new_value = parts.join(''),
700
+ position = parts[0].length;
701
+ if (autoCheck(new_value, settingsClone)) {
702
+ new_value = truncateDecimal(new_value, settingsClone, paste);
703
+ var test_value = (new_value.indexOf(',') !== -1) ? new_value.replace(',', '.') : new_value,
704
+ text_value = test_value;
705
+ if (test_value === '' || test_value === settingsClone.aNeg) {
706
+ settingsClone.rawValue = '';
707
+ } else {
708
+ settingsClone.rawValue = text_value;
709
+ }
710
+ if (position > new_value.length) {
711
+ position = new_value.length;
712
+ }
713
+ this.value = new_value;
714
+ this.setPosition(position, false);
715
+ return true;
716
+ }
717
+ return false;
718
+ },
719
+
720
+ /**
721
+ * helper function for expandSelectionOnSign
722
+ * returns sign position of a formatted value
723
+ */
724
+ signPosition: function () {
725
+ var settingsClone = this.settingsClone,
726
+ aSign = settingsClone.aSign,
727
+ that = this.that;
728
+ if (aSign) {
729
+ var aSignLen = aSign.length;
730
+ if (settingsClone.pSign === 'p') {
731
+ var hasNeg = settingsClone.aNeg && that.value && that.value.charAt(0) === settingsClone.aNeg;
732
+ return hasNeg ? [1, aSignLen + 1] : [0, aSignLen];
733
+ }
734
+ var valueLen = that.value.length;
735
+ return [valueLen - aSignLen, valueLen];
736
+ }
737
+ return [1000, -1];
738
+ },
739
+
740
+ /**
741
+ * expands selection to cover whole sign
742
+ * prevents partial deletion/copying/overwriting of a sign
743
+ */
744
+ expandSelectionOnSign: function (setReal) {
745
+ var sign_position = this.signPosition(),
746
+ selection = this.selection;
747
+ if (selection.start < sign_position[1] && selection.end > sign_position[0]) { /** if selection catches something except sign and catches only space from sign */
748
+ if ((selection.start < sign_position[0] || selection.end > sign_position[1]) && this.value.substring(Math.max(selection.start, sign_position[0]), Math.min(selection.end, sign_position[1])).match(/^\s*$/)) { /** then select without empty space */
749
+ if (selection.start < sign_position[0]) {
750
+ this.setSelection(selection.start, sign_position[0], setReal);
751
+ } else {
752
+ this.setSelection(sign_position[1], selection.end, setReal);
753
+ }
754
+ } else { /** else select with whole sign */
755
+ this.setSelection(Math.min(selection.start, sign_position[0]), Math.max(selection.end, sign_position[1]), setReal);
756
+ }
757
+ }
758
+ },
759
+
760
+ /**
761
+ * try to strip pasted value to digits
762
+ */
763
+ checkPaste: function () {
764
+ if (this.valuePartsBeforePaste !== undefined) {
765
+ var parts = this.getBeforeAfter(),
766
+ oldParts = this.valuePartsBeforePaste;
767
+ delete this.valuePartsBeforePaste; /** try to strip pasted value first */
768
+ parts[0] = parts[0].substr(0, oldParts[0].length) + autoStrip(parts[0].substr(oldParts[0].length), this.settingsClone);
769
+ if (!this.setValueParts(parts[0], parts[1], 'paste')) {
770
+ this.value = oldParts.join('');
771
+ this.setPosition(oldParts[0].length, false);
772
+ }
773
+ }
774
+ },
775
+
776
+ /**
777
+ * process pasting, cursor moving and skipping of not interesting keys
778
+ * if returns true, further processing is not performed
779
+ */
780
+ skipAllways: function (e) {
781
+ var kdCode = this.kdCode,
782
+ which = this.which,
783
+ ctrlKey = this.ctrlKey,
784
+ cmdKey = this.cmdKey,
785
+ shiftKey = this.shiftKey; /** catch the ctrl up on ctrl-v */
786
+ if (((ctrlKey || cmdKey) && e.type === 'keyup' && this.valuePartsBeforePaste !== undefined) || (shiftKey && kdCode === 45)) {
787
+ this.checkPaste();
788
+ return false;
789
+ }
790
+ /** codes are taken from http://www.cambiaresearch.com/c4/702b8cd1-e5b0-42e6-83ac-25f0306e3e25/Javascript-Char-Codes-Key-Codes.aspx
791
+ * skip Fx keys, windows keys, other special keys
792
+ */
793
+ if ((kdCode >= 112 && kdCode <= 123) || (kdCode >= 91 && kdCode <= 93) || (kdCode >= 9 && kdCode <= 31) || (kdCode < 8 && (which === 0 || which === kdCode)) || kdCode === 144 || kdCode === 145 || kdCode === 45 || kdCode === 224) {
794
+ return true;
795
+ }
796
+ if ((ctrlKey || cmdKey) && kdCode === 65) { /** if select all (a=65)*/
797
+ if (this.settings.sNumber) {
798
+ e.preventDefault();
799
+ var valueLen = this.that.value.length,
800
+ aSignLen = this.settings.aSign.length,
801
+ negLen = (this.that.value.indexOf('-') === -1) ? 0 : 1,
802
+ aSuffixLen = this.settings.aSuffix.length,
803
+ pSign = this.settings.pSign,
804
+ pNeg = this.settings.pNeg,
805
+ start = (pSign === 's') ? 0 : (pNeg === 'l' && negLen === 1 && aSignLen > 0) ? aSignLen + 1 : aSignLen,
806
+ end = (pSign === 'p') ? valueLen - aSuffixLen : (pNeg === 'l') ? valueLen - (aSuffixLen + aSignLen) : (pNeg === 'r') ? (aSignLen > 0) ? valueLen - (aSignLen + negLen + aSuffixLen) : valueLen - (aSignLen + aSuffixLen) : valueLen - (aSignLen + aSuffixLen);
807
+ setElementSelection(this.that, start, end);
808
+ }
809
+ return true;
810
+ }
811
+ if ((ctrlKey || cmdKey) && (kdCode === 67 || kdCode === 86 || kdCode === 88)) { /** if copy (c=67) paste (v=86) or cut (x=88) */
812
+ if (e.type === 'keydown') {
813
+ this.expandSelectionOnSign();
814
+ }
815
+ if (kdCode === 86 || kdCode === 45) { /** try to prevent wrong paste */
816
+ if (e.type === 'keydown' || e.type === 'keypress') {
817
+ if (this.valuePartsBeforePaste === undefined) {
818
+ this.valuePartsBeforePaste = this.getBeforeAfter();
819
+ }
820
+ } else {
821
+ this.checkPaste();
822
+ }
823
+ }
824
+ return e.type === 'keydown' || e.type === 'keypress' || kdCode === 67;
825
+ }
826
+ if (ctrlKey || cmdKey) {
827
+ return true;
828
+ }
829
+ if (kdCode === 37 || kdCode === 39) { /** jump over thousand separator */
830
+ var aSep = this.settingsClone.aSep,
831
+ aDec = this.settingsClone.aDec,
832
+ startJump = this.selection.start,
833
+ value = this.that.value;
834
+ if (e.type === 'keydown' && !this.shiftKey) {
835
+ if (kdCode === 37 && (value.charAt(startJump - 2) === aSep || value.charAt(startJump - 2) === aDec)) {
836
+ this.setPosition(startJump - 1);
837
+ } else if (kdCode === 39 && (value.charAt(startJump + 1) === aSep || value.charAt(startJump + 1) === aDec)) {
838
+ this.setPosition(startJump + 1);
839
+ }
840
+ }
841
+ return true;
842
+ }
843
+ if (kdCode >= 34 && kdCode <= 40) {
844
+ return true;
845
+ }
846
+ return false;
847
+ },
848
+
849
+ /**
850
+ * process deletion of characters when the minus sign is to the right of the numeric characters
851
+ */
852
+ processTrailing: function (parts) {
853
+ var settingsClone = this.settingsClone;
854
+ if (settingsClone.pSign === 'p' && settingsClone.pNeg === 's') {
855
+ if (this.kdCode === 8) {
856
+ settingsClone.caretFix = (this.selection.start >= this.value.indexOf(settingsClone.aSuffix) && settingsClone.aSuffix !== '') ? true : false;
857
+ if (this.value.charAt(this.selection.start - 1) === '-') {
858
+ parts[0] = parts[0].substring(1);
859
+ } else if (this.selection.start <= this.value.length - settingsClone.aSuffix.length) {
860
+ parts[0] = parts[0].substring(0, parts[0].length - 1);
861
+ }
862
+ } else {
863
+ settingsClone.caretFix = (this.selection.start >= this.value.indexOf(settingsClone.aSuffix) && settingsClone.aSuffix !== '') ? true : false;
864
+ if (this.selection.start >= this.value.indexOf(settingsClone.aSign) + settingsClone.aSign.length) {
865
+ parts[1] = parts[1].substring(1, parts[1].length);
866
+ }
867
+ if (parts[0].indexOf('-') > -1 && this.value.charAt(this.selection.start) === '-') {
868
+ parts[0] = parts[0].substring(1);
869
+ }
870
+ }
871
+ }
872
+ if (settingsClone.pSign === 's' && settingsClone.pNeg === 'l') {
873
+ settingsClone.caretFix = (this.selection.start >= this.value.indexOf(settingsClone.aNeg) + settingsClone.aNeg.length) ? true : false;
874
+ if (this.kdCode === 8) {
875
+ if (this.selection.start === (this.value.indexOf(settingsClone.aNeg) + settingsClone.aNeg.length) && this.value.indexOf(settingsClone.aNeg) !== -1) {
876
+ parts[0] = parts[0].substring(1);
877
+ } else if (parts[0] !== '-' && ((this.selection.start <= this.value.indexOf(settingsClone.aNeg)) || this.value.indexOf(settingsClone.aNeg) === -1)) {
878
+ parts[0] = parts[0].substring(0, parts[0].length - 1);
879
+ }
880
+ } else {
881
+ if (parts[0][0] === '-') {
882
+ parts[1] = parts[1].substring(1);
883
+ }
884
+ if (this.selection.start === this.value.indexOf(settingsClone.aNeg) && this.value.indexOf(settingsClone.aNeg) !== -1) {
885
+ parts[0] = parts[0].substring(1);
886
+ }
887
+ }
888
+ }
889
+ if (settingsClone.pSign === 's' && settingsClone.pNeg === 'r') {
890
+ settingsClone.caretFix = (this.selection.start >= this.value.indexOf(settingsClone.aNeg) + settingsClone.aNeg.length) ? true : false;
891
+ if (this.kdCode === 8) {
892
+ if (this.selection.start === (this.value.indexOf(settingsClone.aNeg) + settingsClone.aNeg.length)) {
893
+ parts[0] = parts[0].substring(1);
894
+ } else if (parts[0] !== '-' && this.selection.start <= (this.value.indexOf(settingsClone.aNeg) - settingsClone.aSign.length)) {
895
+ parts[0] = parts[0].substring(0, parts[0].length - 1);
896
+ } else if (parts[0] !== '' && this.value.indexOf(settingsClone.aNeg) === -1) {
897
+ parts[0] = parts[0].substring(0, parts[0].length - 1);
898
+ }
899
+ } else {
900
+ settingsClone.caretFix = (this.selection.start >= this.value.indexOf(settingsClone.aSign) && settingsClone.aSign !== '') ? true : false;
901
+ if (this.selection.start === this.value.indexOf(settingsClone.aNeg)) {
902
+ parts[0] = parts[0].substring(1);
903
+ }
904
+ parts[1] = parts[1].substring(1);
905
+ }
906
+ }
907
+ return parts;
908
+ },
909
+
910
+ /**
911
+ * process deletion of characters
912
+ * returns true if processing performed
913
+ */
914
+ processAllways: function () {
915
+ var settingsClone = this.settingsClone,
916
+ parts = [];
917
+ if (this.kdCode === 8 || this.kdCode === 46) {
918
+ if (!this.selection.length) {
919
+ parts = this.getBeforeAfterStriped();
920
+ if (parts[0] === '' && parts[1] === '') {
921
+ settingsClone.throwInput = false;
922
+ }
923
+ if ((settingsClone.pSign === 'p' && settingsClone.pNeg === 's') || (settingsClone.pSign === 's' && settingsClone.pNeg !== 'p')) {
924
+ parts = this.processTrailing(parts);
925
+ } else {
926
+ if (this.kdCode === 8) {
927
+ parts[0] = parts[0].substring(0, parts[0].length - 1);
928
+ } else {
929
+ parts[1] = parts[1].substring(1, parts[1].length);
930
+ }
931
+ }
932
+ this.setValueParts(parts[0], parts[1]);
933
+ } else {
934
+ this.expandSelectionOnSign(false);
935
+ parts = this.getBeforeAfterStriped();
936
+ this.setValueParts(parts[0], parts[1]);
937
+ }
938
+ return true;
939
+ }
940
+ return false;
941
+ },
942
+
943
+ /**
944
+ * process insertion of characters
945
+ * returns true if processing performed
946
+ */
947
+ processKeypress: function () {
948
+ var settingsClone = this.settingsClone,
949
+ cCode = String.fromCharCode(this.which),
950
+ parts = this.getBeforeAfterStriped(),
951
+ left = parts[0],
952
+ right = parts[1];
953
+ settingsClone.throwInput = true;
954
+ /** start rules when the decimal character key is pressed always use numeric pad dot to insert decimal separator */
955
+ if (cCode === settingsClone.aDec || (settingsClone.altDec && cCode === settingsClone.altDec) || ((cCode === '.' || cCode === ',') && this.kdCode === 110)) { /** do not allow decimal character if no decimal part allowed */
956
+ if (!settingsClone.mDec || !settingsClone.aDec) {
957
+ return true;
958
+ } /** do not allow decimal character before aNeg character */
959
+ if (settingsClone.aNeg && right.indexOf(settingsClone.aNeg) > -1) {
960
+ return true;
961
+ } /** do not allow decimal character if other decimal character present */
962
+ if (left.indexOf(settingsClone.aDec) > -1) {
963
+ return true;
964
+ }
965
+ if (right.indexOf(settingsClone.aDec) > 0) {
966
+ return true;
967
+ }
968
+ if (right.indexOf(settingsClone.aDec) === 0) {
969
+ right = right.substr(1);
970
+ }
971
+ this.setValueParts(left + settingsClone.aDec, right, null);
972
+ return true;
973
+ }
974
+ if (cCode === '-' || cCode === '+') { /** prevent minus if not allowed */
975
+ if (!settingsClone) {
976
+ return true;
977
+ } /** caret is always after minus */
978
+ if ((settingsClone.pSign === 'p' && settingsClone.pNeg === 's') || (settingsClone.pSign === 's' && settingsClone.pNeg !== 'p')) {
979
+ if (left === '' && right.indexOf(settingsClone.aNeg) > -1) {
980
+ left = settingsClone.aNeg;
981
+ right = right.substring(1, right.length);
982
+ } /** change sign of number, remove part if should */
983
+ if (left.charAt(0) === '-' || left.indexOf(settingsClone.aNeg) !== -1) {
984
+ left = left.substring(1, left.length);
985
+ } else {
986
+ left = (cCode === '-') ? settingsClone.aNeg + left : left;
987
+ }
988
+ } else {
989
+ if (left === '' && right.indexOf(settingsClone.aNeg) > -1) {
990
+ left = settingsClone.aNeg;
991
+ right = right.substring(1, right.length);
992
+ } /** change sign of number, remove part if should */
993
+ if (left.charAt(0) === settingsClone.aNeg) {
994
+ left = left.substring(1, left.length);
995
+ } else {
996
+ left = (cCode === '-') ? settingsClone.aNeg + left : left;
997
+ }
998
+ }
999
+ this.setValueParts(left, right, null);
1000
+ return true;
1001
+ }
1002
+ if (cCode >= '0' && cCode <= '9') { /** if try to insert digit before minus */
1003
+ if (settingsClone.aNeg && left === '' && right.indexOf(settingsClone.aNeg) > -1) {
1004
+ left = settingsClone.aNeg;
1005
+ right = right.substring(1, right.length);
1006
+ }
1007
+ if (settingsClone.vMax <= 0 && settingsClone.vMin < settingsClone.vMax && this.value.indexOf(settingsClone.aNeg) === -1 && cCode !== '0') {
1008
+ left = settingsClone.aNeg + left;
1009
+ }
1010
+ this.setValueParts(left + cCode, right, null);
1011
+ return true;
1012
+ } /** prevent any other character */
1013
+ settingsClone.throwInput = false;
1014
+ return true;
1015
+ },
1016
+
1017
+ /**
1018
+ * formatting of just processed value with keeping of cursor position
1019
+ */
1020
+ formatQuick: function (e) {
1021
+ var settingsClone = this.settingsClone,
1022
+ parts = this.getBeforeAfterStriped(),
1023
+ leftLength = this.value,
1024
+ kuCode = e.keyCode;
1025
+ /** no grouping separator and no currency sign */
1026
+ if ((settingsClone.aSep === '' || (settingsClone.aSep !== '' && leftLength.indexOf(settingsClone.aSep) === -1)) && (settingsClone.aSign === '' || (settingsClone.aSign !== '' && leftLength.indexOf(settingsClone.aSign) === -1))) {
1027
+ var subParts = [],
1028
+ nSign = '';
1029
+ subParts = leftLength.split(settingsClone.aDec);
1030
+ if (subParts[0].indexOf('-') > -1) {
1031
+ nSign = '-';
1032
+ subParts[0] = subParts[0].replace('-', '');
1033
+ parts[0] = parts[0].replace('-', '');
1034
+ }
1035
+ if (nSign === '' && subParts[0].length > settingsClone.mIntPos && parts[0].charAt(0) === '0') { /** strip leading zero on positive value if need */
1036
+ parts[0] = parts[0].slice(1);
1037
+ }
1038
+ if (nSign === '-' && subParts[0].length > settingsClone.mIntNeg && parts[0].charAt(0) === '0') { /** strip leading zero on negative value if need */
1039
+ parts[0] = parts[0].slice(1);
1040
+ }
1041
+ parts[0] = nSign + parts[0];
1042
+ }
1043
+ var value = autoGroup(this.value, this.settingsClone);
1044
+ var position = value.length;
1045
+ if (value) {
1046
+ /** prepare regexp which searches for cursor position from unformatted left part */
1047
+ var left_ar = parts[0].split(''),
1048
+ i = 0;
1049
+ /** fixes caret position with trailing minus sign */
1050
+ if ((settingsClone.pNeg === 's' || (settingsClone.pSign === 's' && settingsClone.pNeg !== 'p')) && left_ar[0] === '-' && settingsClone.aNeg !== '') {
1051
+ left_ar.shift();
1052
+ if (settingsClone.pSign === 's' && settingsClone.pNeg === 'l' && (kuCode === 8 || this.kdCode === 8 || kuCode === 46 || this.kdCode === 46) && settingsClone.caretFix) {
1053
+ left_ar.push('-');
1054
+ settingsClone.caretFix = (e.type === 'keydown') ? true : false;
1055
+ }
1056
+ if (settingsClone.pSign === 'p' && settingsClone.pNeg === 's' && (kuCode === 8 || this.kdCode === 8 || kuCode === 46 || this.kdCode === 46) && settingsClone.caretFix) {
1057
+ left_ar.push('-');
1058
+ settingsClone.caretFix = (e.type === 'keydown') ? true : false;
1059
+ }
1060
+ if (settingsClone.pSign === 's' && settingsClone.pNeg === 'r' && (kuCode === 8 || this.kdCode === 8 || kuCode === 46 || this.kdCode === 46) && settingsClone.caretFix) {
1061
+ var signParts = settingsClone.aSign.split(''),
1062
+ escapeChr = ['\\', '^', '$', '.', '|', '?', '*', '+', '(', ')', '['],
1063
+ escapedParts = [],
1064
+ escapedSign = '';
1065
+ $.each(signParts, function (i, miniParts) {
1066
+ miniParts = signParts[i];
1067
+ if ($.inArray(miniParts, escapeChr) !== -1) {
1068
+ escapedParts.push('\\' + miniParts);
1069
+ } else {
1070
+ escapedParts.push(miniParts);
1071
+ }
1072
+ });
1073
+ if (kuCode === 8 || this.kdCode === 8) {
1074
+ escapedParts.push('-');
1075
+ }
1076
+ escapedSign = escapedParts.join('');
1077
+ left_ar.push(escapedSign);
1078
+ settingsClone.caretFix = (e.type === 'keydown') ? true : false;
1079
+ }
1080
+ }
1081
+ for (i; i < left_ar.length; i += 1) { /** thanks Peter Kovari */
1082
+ if (!left_ar[i].match('\\d')) {
1083
+ left_ar[i] = '\\' + left_ar[i];
1084
+ }
1085
+ }
1086
+ var leftReg = new RegExp('^.*?' + left_ar.join('.*?')),
1087
+ newLeft = value.match(leftReg); /** search cursor position in formatted value */
1088
+ if (newLeft) {
1089
+ position = newLeft[0].length;
1090
+ /** if we are just before sign which is in prefix position */
1091
+ if (((position === 0 && value.charAt(0) !== settingsClone.aNeg) || (position === 1 && value.charAt(0) === settingsClone.aNeg)) && settingsClone.aSign && settingsClone.pSign === 'p') {
1092
+ /** place caret after prefix sign */
1093
+ position = this.settingsClone.aSign.length + (value.charAt(0) === '-' ? 1 : 0);
1094
+ }
1095
+ } else {
1096
+ if (settingsClone.aSign && settingsClone.pSign === 's') {
1097
+ /** if we could not find a place for cursor and have a sign as a suffix */
1098
+ /** place caret before suffix currency sign */
1099
+ position -= settingsClone.aSign.length;
1100
+ }
1101
+ if (settingsClone.aSuffix) {
1102
+ /** if we could not find a place for cursor and have a suffix */
1103
+ /** place caret before suffix */
1104
+ position -= settingsClone.aSuffix.length;
1105
+ }
1106
+ }
1107
+ }
1108
+ this.that.value = value;
1109
+ this.setPosition(position);
1110
+ this.formatted = true;
1111
+ }
1112
+ };
1113
+
1114
+ /**
1115
+ * thanks to Anthony & Evan C
1116
+ */
1117
+ function autoGet(obj) {
1118
+ if (typeof obj === 'string') {
1119
+ obj = obj.replace(/\[/g, "\\[").replace(/\]/g, "\\]");
1120
+ obj = '#' + obj.replace(/(:|\.)/g, '\\$1');
1121
+ /** obj = '#' + obj.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1'); */
1122
+ /** possible modification to replace the above 2 lines */
1123
+ }
1124
+ return $(obj);
1125
+ }
1126
+
1127
+ /**
1128
+ * function to attach data to the element
1129
+ * and imitate the holder
1130
+ */
1131
+ function getHolder($that, settings, update) {
1132
+ var data = $that.data('autoNumeric');
1133
+ if (!data) {
1134
+ data = {};
1135
+ $that.data('autoNumeric', data);
1136
+ }
1137
+ var holder = data.holder;
1138
+ if ((holder === undefined && settings) || update) {
1139
+ holder = new AutoNumericHolder($that.get(0), settings);
1140
+ data.holder = holder;
1141
+ }
1142
+ return holder;
1143
+ }
1144
+
1145
+ /**
1146
+ * original settings saved for use when eDec & nSep options are being used
1147
+ */
1148
+ function originalSettings(settings) {
1149
+ settings.oDec = settings.mDec;
1150
+ settings.oPad = settings.aPad;
1151
+ settings.oBracket = settings.nBracket;
1152
+ settings.oSep = settings.aSep;
1153
+ settings.oSign = settings.aSign;
1154
+ return settings;
1155
+ }
1156
+
1157
+ /**
1158
+ * original settings saved for use when eDec & nSep options are being used
1159
+ * taken from Quirksmode
1160
+ */
1161
+ function readCookie(name) {
1162
+ var nameEQ = name + "=",
1163
+ ca = document.cookie.split(';'),
1164
+ i = 0,
1165
+ c = '';
1166
+ for (i; i < ca.length; i += 1) {
1167
+ c = ca[i];
1168
+ while (c.charAt(0) === ' ') {
1169
+ c = c.substring(1, c.length);
1170
+ }
1171
+ if (c.indexOf(nameEQ) === 0) {
1172
+ return c.substring(nameEQ.length, c.length);
1173
+ }
1174
+ }
1175
+ return null;
1176
+ }
1177
+
1178
+ /**
1179
+ * Test if sessionStorage is supported - taken from moderizr
1180
+ */
1181
+ function storageTest() {
1182
+ var mod = 'modernizr';
1183
+ try {
1184
+ sessionStorage.setItem(mod, mod);
1185
+ sessionStorage.removeItem(mod);
1186
+ return true;
1187
+ } catch (e) {
1188
+ return false;
1189
+ }
1190
+ }
1191
+
1192
+ /**
1193
+ * creates or removes sessionStorage or cookie depending on browser support
1194
+ */
1195
+ function autoSave($this, settings, toDo) {
1196
+ if (settings.aStor) {
1197
+ var storedName = ($this[0].name !== '' && $this[0].name !== undefined) ? 'AUTO_' + decodeURIComponent($this[0].name) : 'AUTO_' + $this[0].id;
1198
+ if (storageTest() === false) { /** sets cookie for browser that do not support sessionStorage IE 6 & ie7 */
1199
+ if (toDo === 'get') {
1200
+ return readCookie(storedName);
1201
+ }
1202
+ if (toDo === 'set') {
1203
+ document.cookie = storedName + '=' + settings.rawValue + '; expires= ; path=/';
1204
+ }
1205
+ if (toDo === 'wipe') {
1206
+ var date = new Date();
1207
+ date.setTime(date.getTime() + (-1 * 24 * 60 * 60 * 1000));
1208
+ var expires = "; expires=" + date.toGMTString();
1209
+ document.cookie = storedName + '="" ;' + expires + '; path=/';
1210
+ }
1211
+ } else {
1212
+ if (toDo === 'get') {
1213
+ return sessionStorage.getItem(storedName);
1214
+ }
1215
+ if (toDo === 'set') {
1216
+ sessionStorage.setItem(storedName, settings.rawValue);
1217
+ }
1218
+ if (toDo === 'wipe') {
1219
+ sessionStorage.removeItem(storedName);
1220
+ }
1221
+ }
1222
+ }
1223
+ return;
1224
+ }
1225
+
1226
+ /**
1227
+ * Methods supported by autoNumeric
1228
+ */
1229
+ var methods = {
1230
+
1231
+ /**
1232
+ * Method to initiate autoNumeric and attached the settings (default and options passed as a parameter
1233
+ * $(someSelector).autoNumeric('init'); // initiate autoNumeric with defaults
1234
+ * $(someSelector).autoNumeric('init', {option}); // initiate autoNumeric with options
1235
+ * $(someSelector).autoNumeric(); // initiate autoNumeric with defaults
1236
+ * $(someSelector).autoNumeric({option}); // initiate autoNumeric with options
1237
+ * options passes as a parameter example '{aSep: '.', aDec: ',', aSign: '€ '}
1238
+ */
1239
+ init: function (options) {
1240
+ return this.each(function () {
1241
+ var $this = $(this),
1242
+ /** attempt to grab 'autoNumeric' settings, if they don't exist returns "undefined". */
1243
+ settings = $this.data('autoNumeric'),
1244
+ /** attempt to grab HTML5 data, if they don't exist we'll get "undefined".*/
1245
+ tagData = $this.data(),
1246
+ /** supported input types*/
1247
+ $input = $this.is('input[type=text], input[type=hidden], input[type=tel], input:not([type])');
1248
+ $.each(tagData, function (key, value) {
1249
+ if (typeof value === 'number') {
1250
+ tagData[key] = value.toString();
1251
+ }
1252
+ });
1253
+ if (typeof settings !== 'object') { /** If we couldn't grab settings, create them from defaults and passed options. */
1254
+ settings = $.extend({}, $.fn.autoNumeric.defaults, tagData, options, {
1255
+ aNum: '0123456789',
1256
+ onOff: false,
1257
+ runOnce: false,
1258
+ rawValue: '',
1259
+ trailingNegative: false,
1260
+ caretFix: false,
1261
+ throwInput: true,
1262
+ tagList: ['b', 'caption', 'cite', 'code', 'dd', 'del', 'div', 'dfn', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ins', 'kdb', 'label', 'li', 'option', 'output', 'p', 'q', 's', 'sample', 'span', 'strong', 'td', 'th', 'u', 'var']
1263
+ }); /** Merge defaults, tagData and options */
1264
+ if (settings.aDec === settings.aSep) {
1265
+ throwErr('autoNumeric will not function properly when the decimal character aDec: "' + settings.aDec + '" and thousand separator aSep: "' + settings.aSep + '" are the same character', settings.debug);
1266
+ }
1267
+ $.each(settings, function (key, value) {
1268
+ if (value === 'true' || value === 'false') {
1269
+ settings[key] = (value === 'true') ? true : false;
1270
+ }
1271
+ });
1272
+ $this.data('autoNumeric', settings); /** Save our new settings */
1273
+ } else {
1274
+ return this;
1275
+ }
1276
+ settings = originalSettings(settings); /** original settings saved for use when eDec & nSep options are being used */
1277
+ var holder = getHolder($this, settings);
1278
+ if (!$input && $this.prop('tagName').toLowerCase() === 'input') { /** checks for non-supported input types */
1279
+ throwErr('The input type "' + $this.prop('type') + '" is not supported by autoNumeric()', settings.debug);
1280
+ }
1281
+ if ($.inArray($this.prop('tagName').toLowerCase(), settings.tagList) === -1 && $this.prop('tagName').toLowerCase() !== 'input') { /** checks for non-supported tags */
1282
+ throwErr('The "<' + $this.prop('tagName').toLowerCase() + '>" is not supported by autoNumeric()', settings.debug);
1283
+ }
1284
+ if (settings.aDec === settings.aSep) { /** checks if the decimal and thousand are characters are the same */
1285
+ throwErr('autoNumeric will not function properly when the decimal character aDec: "' + settings.aDec + '" and thousand separator aSep: "' + settings.aSep + '" are the same character', settings.debug);
1286
+ }
1287
+ if (settings.eDec < settings.mDec && settings.eDec !== null) { /** checks the extended decimal places "eDec" is greater than the normal decimal places "mDec" */
1288
+ throwErr('autoNumeric will not function properly when the extended decimal places "eDec: ' + settings.eDec + '" is greater than mDec: "' + settings.mDec + '" value', settings.debug);
1289
+ }
1290
+ /** routine to format default value on page load */
1291
+ if (settings.runOnce === false && settings.aForm) {
1292
+ var setValue = true;
1293
+ if ($input) {
1294
+ /** checks for page reload from back button
1295
+ * also checks for ASP.net form post back
1296
+ * the following HTML data attribute is REQUIRED (data-an-default="same value as the value attribute")
1297
+ * example: <asp:TextBox runat="server" id="someID" text="1234.56" data-an-default="1234.56">
1298
+ */
1299
+ if ((settings.anDefault !== null && settings.anDefault.toString() !== $this.val()) || (settings.anDefault === null && $this.val() !== '' && $this.val() !== $this.attr('value')) || ($this.val() !== '' && $this.attr('type') === 'hidden' && !$.isNumeric($this.val().replace(',', '.')))) {
1300
+ if (settings.eDec !== null && settings.aStor) {
1301
+ settings.rawValue = autoSave($this, settings, 'get');
1302
+ }
1303
+ if (!settings.aStor) {
1304
+ var toStrip = '';
1305
+ if (settings.nBracket !== null && settings.aNeg !== '') {
1306
+ settings.onOff = true;
1307
+ toStrip = negativeBracket($this.val(), settings);
1308
+ } else {
1309
+ toStrip = $this.val();
1310
+ }
1311
+ settings.rawValue = ((settings.pNeg === 's' || (settings.pSign === 's' && settings.pNeg !== 'p')) && settings.aNeg !== '' && $this.val().indexOf('-') > -1) ? '-' + autoStrip(toStrip, settings) : autoStrip(toStrip, settings);
1312
+ }
1313
+ setValue = false;
1314
+ }
1315
+ if ($this.val() === '' && settings.wEmpty === 'focus') {
1316
+ setValue = false;
1317
+ }
1318
+ if ($this.val() === '' && settings.wEmpty === 'always') {
1319
+ $this.val(settings.aSign);
1320
+ setValue = false;
1321
+ }
1322
+ if (setValue && $this.val() !== '' && $this.val() === $this.attr('value')) {
1323
+ $this.autoNumeric('set', $this.val());
1324
+ }
1325
+ }
1326
+ if ($.inArray($this.prop('tagName').toLowerCase(), settings.tagList) !== -1 && $this.text() !== '') {
1327
+ if (settings.anDefault !== null) {
1328
+ if (settings.anDefault === $this.text()) {
1329
+ $this.autoNumeric('set', $this.text());
1330
+ }
1331
+ } else {
1332
+ $this.autoNumeric('set', $this.text());
1333
+ }
1334
+ }
1335
+ }
1336
+ settings.runOnce = true;
1337
+ if ($input) { /**input types supported "text", "hidden", "tel" and no type*/
1338
+ $this.on('focusin.autoNumeric', function () {
1339
+ holder = getHolder($this);
1340
+ var $settings = holder.settingsClone;
1341
+ $settings.onOff = true;
1342
+ if ($settings.nBracket !== null && $settings.aNeg !== '') {
1343
+ $this.val(negativeBracket($this.val(), $settings));
1344
+ }
1345
+ if ($settings.nSep === true) {
1346
+ $settings.aSep = '';
1347
+ $settings.aSign = '';
1348
+ }
1349
+ if ($settings.eDec !== null) {
1350
+ $settings.mDec = $settings.eDec;
1351
+ $this.autoNumeric('set', $settings.rawValue);
1352
+ } else {
1353
+ $this.autoNumeric('set', $settings.rawValue);
1354
+ }
1355
+ holder.inVal = $this.val();
1356
+ holder.lastVal = $this.val();
1357
+ var onEmpty = checkEmpty(holder.inVal, $settings, true);
1358
+ if ((onEmpty !== null && onEmpty !== '') && $settings.wEmpty === 'focus') {
1359
+ $this.val(onEmpty);
1360
+ }
1361
+ });
1362
+ $this.on('keydown.autoNumeric', function (e) {
1363
+ holder = getHolder($this);
1364
+ if (holder.that.readOnly) {
1365
+ holder.processed = true;
1366
+ return true;
1367
+ }
1368
+ /** The below streamed code / comment allows the "enter" keydown to throw a change() event */
1369
+ /** if (e.keyCode === 13 && holder.inVal !== $this.val()){
1370
+ $this.change();
1371
+ holder.inVal = $this.val();
1372
+ }*/
1373
+ holder.init(e);
1374
+ if (holder.skipAllways(e)) {
1375
+ holder.processed = true;
1376
+ return true;
1377
+ }
1378
+ if (holder.processAllways()) {
1379
+ holder.processed = true;
1380
+ holder.formatQuick(e);
1381
+ if (($this.val() !== holder.lastVal) && holder.settingsClone.throwInput) {
1382
+ $this.trigger('input'); /** throws input event in deletion character */
1383
+ }
1384
+ holder.lastVal = $this.val();
1385
+ holder.settingsClone.throwInput = true;
1386
+ e.preventDefault();
1387
+ return false;
1388
+ }
1389
+ holder.formatted = false;
1390
+ return true;
1391
+ });
1392
+ $this.on('keypress.autoNumeric', function (e) {
1393
+ if (e.shiftKey && e.keyCode === 45) { /** FF fix for Shift && insert paste event */
1394
+ return;
1395
+ }
1396
+ holder = getHolder($this);
1397
+ var processed = holder.processed;
1398
+ holder.init(e);
1399
+ if (holder.skipAllways(e)) {
1400
+ return true;
1401
+ }
1402
+ if (processed) {
1403
+ e.preventDefault();
1404
+ return false;
1405
+ }
1406
+ if (holder.processAllways() || holder.processKeypress()) {
1407
+ holder.formatQuick(e);
1408
+ if (($this.val() !== holder.lastVal) && holder.settingsClone.throwInput) {
1409
+ $this.trigger('input'); /** throws input event on adding character */
1410
+ }
1411
+ holder.lastVal = $this.val();
1412
+ holder.settingsClone.throwInput = true;
1413
+ e.preventDefault();
1414
+ return;
1415
+ }
1416
+ holder.formatted = false;
1417
+ });
1418
+ $this.on('keyup.autoNumeric', function (e) {
1419
+ holder = getHolder($this);
1420
+ holder.init(e);
1421
+ var skip = holder.skipAllways(e);
1422
+ holder.kdCode = 0;
1423
+ delete holder.valuePartsBeforePaste;
1424
+ if ($this[0].value === holder.settingsClone.aSign) { /** added to properly place the caret when only the currency sign is present */
1425
+ if (holder.settingsClone.pSign === 's') {
1426
+ setElementSelection(this, 0, 0);
1427
+ } else {
1428
+ setElementSelection(this, holder.settingsClone.aSign.length, holder.settingsClone.aSign.length);
1429
+ }
1430
+ }
1431
+ if ($this[0].value === holder.settingsClone.aSuffix) {
1432
+ setElementSelection(this, 0, 0);
1433
+ }
1434
+ if (holder.settingsClone.rawValue === '' && holder.settingsClone.aSign !== '' && holder.settingsClone.aSuffix !== '') {
1435
+ setElementSelection(this, 0, 0);
1436
+ }
1437
+ if (holder.settingsClone.eDec !== null && holder.settingsClone.aStor) { /** saves the extended decimal to preserve the data when navigating away from the page */
1438
+ autoSave($this, settings, 'set');
1439
+ }
1440
+ if (skip) {
1441
+ return true;
1442
+ }
1443
+ if (this.value === '') {
1444
+ return true;
1445
+ }
1446
+ if (!holder.formatted) {
1447
+ holder.formatQuick(e);
1448
+ }
1449
+ });
1450
+ $this.on('focusout.autoNumeric', function () {
1451
+ holder = getHolder($this);
1452
+ var value = $this.val(),
1453
+ origValue = value,
1454
+ $settings = holder.settingsClone;
1455
+ $settings.onOff = false;
1456
+ if ($settings.aStor) {
1457
+ autoSave($this, $settings, 'set');
1458
+ }
1459
+ if ($settings.nSep === true) {
1460
+ $settings.aSep = $settings.oSep;
1461
+ $settings.aSign = $settings.oSign;
1462
+ }
1463
+ if ($settings.eDec !== null) {
1464
+ $settings.mDec = $settings.oDec;
1465
+ $settings.aPad = $settings.oPad;
1466
+ $settings.nBracket = $settings.oBracket;
1467
+ }
1468
+ if (value !== '') {
1469
+ value = autoStrip(value, $settings);
1470
+ if ($settings.trailingNegative) {
1471
+ value = '-' + value;
1472
+ $settings.trailingNegative = false;
1473
+ }
1474
+ if (checkEmpty(value, $settings) === null && autoCheck(value, $settings, $this[0])) {
1475
+ value = fixNumber(value, $settings.aDec, $settings.aNeg);
1476
+ $settings.rawValue = value;
1477
+ value = autoRound(value, $settings);
1478
+ value = presentNumber(value, $settings.aDec, $settings.aNeg);
1479
+ } else {
1480
+ value = '';
1481
+ $settings.rawValue = '';
1482
+ }
1483
+ } else {
1484
+ $settings.rawValue = '';
1485
+ }
1486
+ var groupedValue = checkEmpty(value, $settings, false);
1487
+ if (groupedValue === null) {
1488
+ groupedValue = autoGroup(value, $settings);
1489
+ }
1490
+ if (groupedValue !== origValue) {
1491
+ $this.val(groupedValue);
1492
+ }
1493
+ if (groupedValue !== holder.inVal) {
1494
+ $this.change();
1495
+ delete holder.inVal;
1496
+ }
1497
+ });
1498
+ $this.on('paste.autoNumeric', function (e) {
1499
+ holder = getHolder($this);
1500
+ var clipboardData = e.clipboardData || e.originalEvent.clipboardData || window.clipboardData,
1501
+ pastedData = clipboardData.getData('text');
1502
+ if (pastedData !== holder.lastVal) {
1503
+ $this.trigger('input'); /** throws input event on adding character */
1504
+ holder.lastVal = window.setTimeout( function() {
1505
+ $this.val();
1506
+ }, 100);
1507
+ }
1508
+ });
1509
+ $this.closest('form').on('submit.autoNumeric', function () {
1510
+ holder = getHolder($this);
1511
+ var $settings = holder.settingsClone;
1512
+ if ($settings.unSetOnSubmit) {
1513
+ $this.val($settings.rawValue);
1514
+ }
1515
+
1516
+ });
1517
+ }
1518
+ });
1519
+ },
1520
+
1521
+ /**
1522
+ * method to remove settings and stop autoNumeric() - does not remove the formatting
1523
+ * $(someSelector).autoNumeric('destroy'); // destroys autoNumeric
1524
+ * no parameters accepted
1525
+ */
1526
+ destroy: function () {
1527
+ return $(this).each(function () {
1528
+ var $this = autoGet($(this)),
1529
+ settings = $this.data('autoNumeric');
1530
+ if (typeof settings === 'object') {
1531
+ $this.val('');
1532
+ autoSave($this, settings, 'wipe');
1533
+ $this.off('.autoNumeric');
1534
+ $this.removeData('autoNumeric');
1535
+ }
1536
+ });
1537
+ },
1538
+
1539
+ /**
1540
+ * method to clear the value and sessionStorage or cookie depending on browser supports
1541
+ * $(someSelector).autoNumeric('wipe'); // removes session storage and cookies from memory
1542
+ * no parameters accepted
1543
+ */
1544
+ wipe: function () {
1545
+ return $(this).each(function () {
1546
+ var $this = autoGet($(this)),
1547
+ settings = $this.data('autoNumeric');
1548
+ if (typeof settings === 'object') {
1549
+ $this.val('');
1550
+ settings.rawValue = '';
1551
+ autoSave($this, settings, 'wipe');
1552
+ }
1553
+ });
1554
+ },
1555
+
1556
+ /**
1557
+ * method to update settings - can be call as many times
1558
+ * $(someSelector).autoNumeric('update', {options}); // updates the settings
1559
+ * options passed as a parameter example '{aSep: '.', aDec: ',', aSign: '€ '}
1560
+ */
1561
+ update: function (options) {
1562
+ return $(this).each(function () {
1563
+ var $this = autoGet($(this)),
1564
+ settings = $this.data('autoNumeric');
1565
+ if (typeof settings !== 'object') {
1566
+ throwErr('Initializing autoNumeric is required prior to calling the "update" method', true);
1567
+ }
1568
+ var strip = $this.autoNumeric('get');
1569
+ settings = $.extend(settings, options);
1570
+ settings = originalSettings(settings);
1571
+ getHolder($this, settings, true);
1572
+ if (settings.aDec === settings.aSep) {
1573
+ throwErr('autoNumeric will not function properly when the decimal character aDec: "' + settings.aDec + '" and thousand separator aSep: "' + settings.aSep + '" are the same character', settings.debug);
1574
+ }
1575
+ $this.data('autoNumeric', settings);
1576
+ if ($this.val() !== '' || $this.text() !== '') {
1577
+ return $this.autoNumeric('set', strip);
1578
+ }
1579
+ return;
1580
+ });
1581
+ },
1582
+
1583
+ /**
1584
+ * method to format value sent as a parameter ""
1585
+ * $(someSelector).autoNumeric('set', 'value'}); // formats the value being passed
1586
+ * value passed as a string - can be a integer '1234' or double '1234.56789'
1587
+ * must contain only numbers and one decimal (period) character
1588
+ */
1589
+ set: function (valueIn) {
1590
+ return $(this).each(function () {
1591
+ if (valueIn === null) {
1592
+ return;
1593
+ }
1594
+ var $this = autoGet($(this)),
1595
+ settings = $this.data('autoNumeric'),
1596
+ value = valueIn.toString(),
1597
+ $input = $this.is('input[type=text], input[type=hidden], input[type=tel], input:not([type])');
1598
+ if (typeof settings !== 'object') {
1599
+ throwErr('Initializing autoNumeric is required prior to calling the "set" method', true);
1600
+ }
1601
+ /** allows locale decimal separator to be a comma - no thousand separator allowed */
1602
+ value = convertLocale(value);
1603
+ /** Throws an error if the value being set is not numeric */
1604
+ if (!$.isNumeric(Number(value))) {
1605
+ throwErr('The value "' + value + '" being "set" is not numeric and has caused a error to be thrown', settings.debug);
1606
+ }
1607
+ if (value !== '') {
1608
+ if (autoCheck(value, settings)) {
1609
+ if ($input && settings.eDec !== null) {
1610
+ settings.rawValue = value;
1611
+ }
1612
+ if ($input || $.inArray($this.prop('tagName').toLowerCase(), settings.tagList) !== -1) { /** checks if the value falls within the min max range */
1613
+ value = autoRound(value, settings);
1614
+ if (settings.eDec === null) {
1615
+ settings.rawValue = value;
1616
+ }
1617
+ value = presentNumber(value, settings.aDec, settings.aNeg);
1618
+ value = autoGroup(value, settings);
1619
+ }
1620
+ if (settings.aStor && settings.eDec !== null) {
1621
+ autoSave($this, settings, 'set');
1622
+ }
1623
+ } else {
1624
+ settings.rawValue = '';
1625
+ autoSave($this, settings, 'wipe');
1626
+ value = '';
1627
+ throwErr('The value being set falls outside the min: "' + settings.vMin + ' max: "' + settings.vMax + '" ) settings for this element', settings.debug);
1628
+ return '';
1629
+ }
1630
+ } else {
1631
+ return '';
1632
+ }
1633
+ if ($input) {
1634
+ return $this.val(value);
1635
+ }
1636
+ if ($.inArray($this.prop('tagName').toLowerCase(), settings.tagList) !== -1) {
1637
+ return $this.text(value);
1638
+ }
1639
+ return false;
1640
+ });
1641
+ },
1642
+
1643
+ /**
1644
+ * method to un-format inputs - handy to use right before form submission
1645
+ * $(someSelector).autoNumeric('unSet'); // parameter optional
1646
+ * $(someSelector).autoNumeric('unSet', 'komma'); // returns string '1234,56' with a komma as the decimal character
1647
+ * $(someSelector).autoNumeric('unSet', 'checkOptions'); // returns string '1234.56' or '1234.56' depending of the format setting for the input
1648
+ */
1649
+ unSet: function (outPut) {
1650
+ return $(this).each(function () {
1651
+ var $this = autoGet($(this)),
1652
+ settings = $this.data('autoNumeric');
1653
+ if (typeof settings === 'object') {
1654
+ settings.onOff = true;
1655
+ $this.val($this.autoNumeric('get', outPut));
1656
+ }
1657
+ });
1658
+ },
1659
+
1660
+ /**
1661
+ * method to re-format inputs - handy to use right after form submission
1662
+ * $(someSelector).autoNumeric('reSet'); // no parameters accepted
1663
+ * this is called after the 'unSet' method to reformat the input
1664
+ */
1665
+ reSet: function () {
1666
+ return $(this).each(function () {
1667
+ var $this = autoGet($(this)),
1668
+ settings = $this.data('autoNumeric');
1669
+ if (typeof settings === 'object') {
1670
+ $this.autoNumeric('set', $this.val());
1671
+ }
1672
+ });
1673
+ },
1674
+
1675
+ /**
1676
+ * method to get the unformatted that accepts up to one parameter
1677
+ * $(someSelector).autoNumeric('get'); no parameter used - values returned as ISO numeric string "1234.56" where the decimal character is a period
1678
+ * $(someSelector).autoNumeric('get', 'asKomma'); values returned as strings "nnnn,nn" where the comma / komma is the decimal character
1679
+ * $(someSelector).autoNumeric('get', 'checkOptions'); values returned as strings - either as "nnnn.nn" or "nnnn,mm" depending of the format setting for the input
1680
+ * only the first element in the selector is returned
1681
+ */
1682
+ get: function (outPut) {
1683
+ var $this = autoGet($(this)),
1684
+ settings = $this.data('autoNumeric'),
1685
+ $input = $this.is('input[type=text], input[type=hidden], input[type=tel], input:not([type])');
1686
+ if (typeof settings !== 'object') {
1687
+ throwErr('Initializing autoNumeric is required prior to calling the "get" method', true);
1688
+ }
1689
+ var getValue = '';
1690
+ /** determine the element type then use .eq(0) selector to grab the value of the first element in selector */
1691
+ if ($input) {
1692
+ getValue = $this.eq(0).val();
1693
+ } else if ($.inArray($this.prop('tagName').toLowerCase(), settings.tagList) !== -1) {
1694
+ getValue = $this.eq(0).text();
1695
+ } else {
1696
+ throwErr('The "<' + $this.prop('tagName').toLowerCase() + '>" is not supported by autoNumeric()', settings.debug);
1697
+ }
1698
+ if (settings.rawValue !== '') {
1699
+ getValue = settings.rawValue;
1700
+ }
1701
+ if (((!/\d/).test(getValue) || Number(getValue) === 0) && settings.wEmpty === 'focus') {
1702
+ return '';
1703
+ }
1704
+ if (getValue !== '' && settings.nBracket !== null) {
1705
+ settings.onOff = true;
1706
+ getValue = negativeBracket(getValue, settings);
1707
+ }
1708
+ getValue = fixNumber(getValue, settings.aDec, settings.aNeg);
1709
+ if (Number(getValue) === 0 && settings.lZero !== 'keep') {
1710
+ getValue = '0';
1711
+ }
1712
+ if (outPut === ',') {
1713
+ getValue = getValue.replace('.', ',');
1714
+ }
1715
+ if (outPut === '.-' && getValue.indexOf('-') > -1) {
1716
+ getValue = getValue.replace('-', '') + '-';
1717
+ }
1718
+ if (outPut === ',-' && getValue.indexOf('-') > -1) {
1719
+ getValue = getValue.replace('.', ',').replace('-', '') + '-';
1720
+ }
1721
+ return getValue; /** returned Numeric String */
1722
+ },
1723
+
1724
+ /**
1725
+ * The 'getString' method used jQuerys .serialize() method that creates a text string in standard URL-encoded notation
1726
+ * it then loops through the string and un-formats the inputs with autoNumeric
1727
+ * $(someSelector).autoNumeric('getString'); no parameter used - values returned as ISO numeric string "1234.56" where the decimal character is a period
1728
+ * $(someSelector).autoNumeric('getString', 'asKomma'); values returned as strings "nnnn,nn" where the comma / komma is the decimal character
1729
+ * $(someSelector).autoNumeric('getString', 'checkOptions'); values returned as strings - either as "nnnn.nn" or "nnnn,mm" depending of the format setting for the input
1730
+ */
1731
+ getString: function (outPut) {
1732
+ var $this = autoGet($(this)),
1733
+ formFields = $this.serialize(),
1734
+ formParts = formFields.split('&'),
1735
+ formIndex = $('form').index($this),
1736
+ allFormElements = $('form:eq(' + formIndex + ')'),
1737
+ aiIndex = [], /** all input index */
1738
+ scIndex = [], /** successful control index */
1739
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, /* from jQuery serialize method */
1740
+ rsubmittable = /^(?:input|select|textarea|keygen)/i, /* from jQuery serialize method */
1741
+ rcheckableType = /^(?:checkbox|radio)$/i,
1742
+ rnonAutoNumericTypes = /^(?:button|checkbox|color|date|datetime|datetime-local|email|file|image|month|number|password|radio|range|reset|search|submit|time|url|week)/i,
1743
+ count = 0;
1744
+ /*jslint unparam: true*/
1745
+ /** index of successful elements */
1746
+ $.each(allFormElements[0], function (i, field) {
1747
+ if (field.name !== '' && rsubmittable.test(field.localName) && !rsubmitterTypes.test(field.type) && !field.disabled && (field.checked || !rcheckableType.test(field.type))) {
1748
+ scIndex.push(count);
1749
+ count = count + 1;
1750
+ } else {
1751
+ scIndex.push(-1);
1752
+ }
1753
+ });
1754
+ /** index of all inputs tags except checkbox */
1755
+ count = 0;
1756
+ $.each(allFormElements[0], function (i, field) {
1757
+ if (field.localName === 'input' && (field.type === '' || field.type === 'text' || field.type === 'hidden' || field.type === 'tel')) {
1758
+ aiIndex.push(count);
1759
+ count = count + 1;
1760
+ } else {
1761
+ aiIndex.push(-1);
1762
+ if (field.localName === 'input' && rnonAutoNumericTypes.test(field.type)) {
1763
+ count = count + 1;
1764
+ }
1765
+ }
1766
+ });
1767
+ $.each(formParts, function (i, miniParts) {
1768
+ miniParts = formParts[i].split('=');
1769
+ var scElement = $.inArray(i, scIndex);
1770
+ if (scElement > -1 && aiIndex[scElement] > -1) {
1771
+ var testInput = $('form:eq(' + formIndex + ') input:eq(' + aiIndex[scElement] + ')'),
1772
+ settings = testInput.data('autoNumeric');
1773
+ if (typeof settings === 'object') {
1774
+ if (miniParts[1] !== null) {
1775
+ miniParts[1] = $('form:eq(' + formIndex + ') input:eq(' + aiIndex[scElement] + ')').autoNumeric('get', outPut).toString();
1776
+ formParts[i] = miniParts.join('=');
1777
+ }
1778
+ }
1779
+ }
1780
+ });
1781
+ /*jslint unparam: false*/
1782
+ return formParts.join('&');
1783
+ },
1784
+
1785
+ /**
1786
+ * The 'getString' method used jQuerys .serializeArray() method that creates array or objects that can be encoded as a JSON string
1787
+ * it then loops through the string and un-formats the inputs with autoNumeric
1788
+ * $(someSelector).autoNumeric('getArray'); no parameter used - values returned as ISO numeric string "1234.56" where the decimal character is a period
1789
+ * $(someSelector).autoNumeric('getArray', 'asKomma'); values returned as strings "nnnn,nn" where the comma / komma is the decimal character
1790
+ * $(someSelector).autoNumeric('getArray', 'checkOptions'); values returned as strings - either as "nnnn.nn" or "nnnn,mm" depending of the format setting for the input
1791
+ */
1792
+ getArray: function (outPut) {
1793
+ var $this = autoGet($(this)),
1794
+ formFields = $this.serializeArray(),
1795
+ formIndex = $('form').index($this),
1796
+ allFormElements = $('form:eq(' + formIndex + ')'),
1797
+ aiIndex = [], /* all input index */
1798
+ scIndex = [], /* successful control index */
1799
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, /* from jQuery serialize method */
1800
+ rsubmittable = /^(?:input|select|textarea|keygen)/i, /* from jQuery serialize method */
1801
+ rcheckableType = /^(?:checkbox|radio)$/i,
1802
+ rnonAutoNumericTypes = /^(?:button|checkbox|color|date|datetime|datetime-local|email|file|image|month|number|password|radio|range|reset|search|submit|time|url|week)/i,
1803
+ count = 0;
1804
+ /*jslint unparam: true*/
1805
+ /* index of successful elements */
1806
+ $.each(allFormElements[0], function (i, field) {
1807
+ if (field.name !== '' && rsubmittable.test(field.localName) && !rsubmitterTypes.test(field.type) && !field.disabled && (field.checked || !rcheckableType.test(field.type))) {
1808
+ scIndex.push(count);
1809
+ count = count + 1;
1810
+ } else {
1811
+ scIndex.push(-1);
1812
+ }
1813
+ });
1814
+ /* index of all inputs tags */
1815
+ count = 0;
1816
+ $.each(allFormElements[0], function (i, field) {
1817
+ if (field.localName === 'input' && (field.type === '' || field.type === 'text' || field.type === 'hidden' || field.type === 'tel')) {
1818
+ aiIndex.push(count);
1819
+ count = count + 1;
1820
+ } else {
1821
+ aiIndex.push(-1);
1822
+ if (field.localName === 'input' && rnonAutoNumericTypes.test(field.type)) {
1823
+ count = count + 1;
1824
+ }
1825
+ }
1826
+ });
1827
+ $.each(formFields, function (i, field) {
1828
+ var scElement = $.inArray(i, scIndex);
1829
+ if (scElement > -1 && aiIndex[scElement] > -1) {
1830
+ var testInput = $('form:eq(' + formIndex + ') input:eq(' + aiIndex[scElement] + ')'),
1831
+ settings = testInput.data('autoNumeric');
1832
+ if (typeof settings === 'object') {
1833
+ field.value = $('form:eq(' + formIndex + ') input:eq(' + aiIndex[scElement] + ')').autoNumeric('get', outPut).toString();
1834
+ }
1835
+ }
1836
+ });
1837
+ /*jslint unparam: false*/
1838
+ return formFields;
1839
+ },
1840
+
1841
+ /**
1842
+ * The 'getSteetings returns the object with autoNumeric settings for those who need to look under the hood
1843
+ * $(someSelector).autoNumeric('getSettings'); // no parameters accepted
1844
+ * $(someSelector).autoNumeric('getSettings').aDec; // return the aDec setting as a string - ant valid setting can be used
1845
+ */
1846
+ getSettings: function () {
1847
+ var $this = autoGet($(this));
1848
+ return $this.eq(0).data('autoNumeric');
1849
+ }
1850
+ };
1851
+
1852
+ /**
1853
+ * autoNumeric function
1854
+ */
1855
+ $.fn.autoNumeric = function (method) {
1856
+ if (methods[method]) {
1857
+ return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
1858
+ }
1859
+ if (typeof method === 'object' || !method) {
1860
+ return methods.init.apply(this, arguments);
1861
+ }
1862
+ throwErr('Method "' + method + '" is not supported by autoNumeric()', true);
1863
+ };
1864
+
1865
+ /**
1866
+ * Defaults are public - these can be overridden by the following:
1867
+ * HTML5 data attributes
1868
+ * Options passed by the 'init' or 'update' methods
1869
+ * Use jQuery's $.extend method for global changes - also a great way to pass ASP.NET current culture settings
1870
+ */
1871
+ $.fn.autoNumeric.defaults = {
1872
+ /** allowed thousand separator characters
1873
+ * comma = ','
1874
+ * period "full stop" = '.'
1875
+ * apostrophe is escaped = '\''
1876
+ * space = ' '
1877
+ * none = ''
1878
+ * NOTE: do not use numeric characters
1879
+ */
1880
+ aSep: ',',
1881
+ /** when true => when the input has focus only the decimal character is visible
1882
+ */
1883
+ nSep: false,
1884
+ /** digital grouping for the thousand separator used in Format
1885
+ * dGroup: '2', results in 99,99,99,999 India's lakhs
1886
+ * dGroup: '2s', results in 99,999,99,99,999 India's lakhs scaled
1887
+ * dGroup: '3', results in 999,999,999 default
1888
+ * dGroup: '4', results in 9999,9999,9999 used in some Asian countries
1889
+ */
1890
+ dGroup: '3',
1891
+ /** allowed decimal separator characters
1892
+ * period "full stop" = '.'
1893
+ * comma = ','
1894
+ */
1895
+ aDec: '.',
1896
+ /** allow to declare alternative decimal separator which is automatically replaced by aDec
1897
+ * developed for countries the use a comma ',' as the decimal character
1898
+ * and have keyboards\numeric pads that have a period 'full stop' as the decimal characters (Spain is an example)
1899
+ */
1900
+ altDec: null,
1901
+ /** aSign = allowed currency symbol
1902
+ * Must be in quotes aSign: '$'
1903
+ * space to the right of the currency symbol aSign: '$ '
1904
+ * space to the left of the currency symbol aSign: ' $'
1905
+ */
1906
+ aSign: '',
1907
+ /** pSign = placement of currency sign as a p=prefix or s=suffix
1908
+ * for prefix pSign: 'p' (default)
1909
+ * for suffix pSign: 's'
1910
+ */
1911
+ pSign: 'p',
1912
+ /** placement of negative sign relative to the aSign option l=left, r=right, p=prefix & s=suffix
1913
+ * -1,234.56 => defaults no options required
1914
+ * 1,234.56- => {pNeg: 's'}
1915
+ * -$1,234.56 => {aSign: '$'}
1916
+ * $-1,234.56 => {aSign: '$', pNeg: 'r'}
1917
+ * $1,234.56- => {aSign: '$', pNeg: 's'}
1918
+ * 1,234.56-$ => {aSign: '$', pSign: 's'}
1919
+ * 1,234.56$- => {aSign: '$', pSign: 's', pNeg: 'r'}
1920
+ * -1,234.56$ => {aSign: '$', pSign: 's', pNeg: 'p'}
1921
+ */
1922
+ pNeg: 'l',
1923
+ /** Additional suffix
1924
+ * Must be in quotes aSuffix: 'gross', a space is allowed aSuffix: ' dollars'
1925
+ * Numeric characters and negative sign not allowed'
1926
+ */
1927
+ aSuffix: '',
1928
+ /** maximum possible value
1929
+ * value must be enclosed in quotes and use the period for the decimal point
1930
+ * value must be larger than vMin
1931
+ */
1932
+ vMax: '9999999999999.99',
1933
+ /** minimum possible value
1934
+ * value must be enclosed in quotes and use the period for the decimal point
1935
+ * value must be smaller than vMax
1936
+ */
1937
+ vMin: '-9999999999999.99',
1938
+ /** Maximum number of decimal places = used to override decimal places set by the vMin & vMax values
1939
+ * value must be enclosed in quotes example mDec: '3',
1940
+ */
1941
+ mDec: null,
1942
+ /** Expanded decimal places visible when input has focus
1943
+ * value must be enclosed in quotes example mDec: '3',
1944
+ */
1945
+ eDec: null,
1946
+ /** Set to true to allow the eDec value to be saved with sessionStorage
1947
+ * if ie 6 or 7 the value will be saved as a session cookie
1948
+ */
1949
+ aStor: false,
1950
+ /** method used for rounding
1951
+ * mRound: 'S', Round-Half-Up Symmetric (default)
1952
+ * mRound: 'A', Round-Half-Up Asymmetric
1953
+ * mRound: 's', Round-Half-Down Symmetric (lower case s)
1954
+ * mRound: 'a', Round-Half-Down Asymmetric (lower case a)
1955
+ * mRound: 'B', Round-Half-Even "Bankers Rounding"
1956
+ * mRound: 'U', Round Up "Round-Away-From-Zero"
1957
+ * mRound: 'D', Round Down "Round-Toward-Zero" - same as truncate
1958
+ * mRound: 'C', Round to Ceiling "Toward Positive Infinity"
1959
+ * mRound: 'F', Round to Floor "Toward Negative Infinity"
1960
+ * mRound: 'N05' Rounds to the nearest .05
1961
+ * mRound: 'U05' Rounds up to next .05
1962
+ * mRound: 'D05' Rounds down to next .05
1963
+ */
1964
+ mRound: 'S',
1965
+ /** controls decimal padding
1966
+ * aPad: true - always Pad decimals with zeros
1967
+ * aPad: false - does not pad with zeros.
1968
+ * aPad: `some number` - pad decimals with zero to number different from mDec
1969
+ * thanks to Jonas Johansson for the suggestion
1970
+ */
1971
+ aPad: true,
1972
+ /** places brackets on negative value -$ 999.99 to (999.99)
1973
+ * visible only when the field does NOT have focus the left and right symbols should be enclosed in quotes and separated by a comma
1974
+ * nBracket: null - (default)
1975
+ * nBracket: '(,)', nBracket: '[,]', nBracket: '<,>' or nBracket: '{,}'
1976
+ */
1977
+ nBracket: null,
1978
+ /** Displayed on empty string ""
1979
+ * wEmpty: 'focus' - (default) currency sign displayed and the input receives focus
1980
+ * wEmpty: 'press' - currency sign displays on any key being pressed
1981
+ * wEmpty: 'always' - always displays the currency sign
1982
+ */
1983
+ wEmpty: 'focus',
1984
+ /** controls leading zero behavior
1985
+ * lZero: 'allow', - allows leading zeros to be entered. Zeros will be truncated when entering additional digits. On focusout zeros will be deleted.
1986
+ * lZero: 'deny', - allows only one leading zero on values less than one
1987
+ * lZero: 'keep', - allows leading zeros to be entered. on focusout zeros will be retained.
1988
+ */
1989
+ lZero: 'allow',
1990
+ /** determine if the default value will be formatted on page ready.
1991
+ * true = automatically formats the default value on page ready
1992
+ * false = will not format the default value
1993
+ */
1994
+ aForm: true,
1995
+ /** determine if the select all keyboard command will select
1996
+ * the complete input text or only the input numeric value
1997
+ * if the currency symbol is between the numeric value and the negative sign only the numeric value will selected
1998
+ */
1999
+ sNumber: false,
2000
+ /** helper option for ASP.NET postback
2001
+ * should be the value of the unformatted default value
2002
+ * examples:
2003
+ * no default value='' {anDefault: ''}
2004
+ * value=1234.56 {anDefault: '1234.56'}
2005
+ */
2006
+ anDefault: null,
2007
+ /** removes formatting on submit event
2008
+ * this output format: positive nnnn.nn, negative -nnnn.nn
2009
+ * review the 'unSet' method for other formats
2010
+ */
2011
+ unSetOnSubmit: false,
2012
+ /** error handling function
2013
+ * true => all errors are thrown - helpful in site development
2014
+ * false => throws errors when calling methods prior to the supported element has been initialized be autoNumeric
2015
+ */
2016
+ debug: true
2017
+ };
2018
+ }));