jquery-inputmask-rails 2.0.1 → 2.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ae89110e71f88ab05d14ddef77c04fdd42ebd754
4
+ data.tar.gz: 22e209a41b45cb097d9f382e68fb00f09d547412
5
+ SHA512:
6
+ metadata.gz: bc17ced2ce15653409fe1003aac3b4ff4deb29c998f6339416533ead45d3907938afe259872ab16bf5ccfb44f0b15153acd60bf96cffb9f5d152de11a0842158
7
+ data.tar.gz: 768046dc6db59d732a977c7aa69ae7d25ecd2c34ff22a9a321da30914021f0aaf27f16ecc813864f47217ea86c46a7966a388b0ad3b97bc91e0d01457ae3dafe
@@ -1,7 +1,7 @@
1
1
  module Jquery
2
2
  module Inputmask
3
3
  module Rails
4
- VERSION = "2.0.1"
4
+ VERSION = "2.5.5"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,2727 @@
1
+ /**
2
+ * @license Input Mask plugin for jquery
3
+ * http://github.com/RobinHerbots/jquery.inputmask
4
+ * Copyright (c) 2010 - 2014 Robin Herbots
5
+ * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
6
+ * Version: 2.5.5
7
+ */
8
+
9
+ (function ($) {
10
+ if ($.fn.inputmask === undefined) {
11
+ //helper functions
12
+ function isInputEventSupported(eventName) {
13
+ var el = document.createElement('input'),
14
+ eventName = 'on' + eventName,
15
+ isSupported = (eventName in el);
16
+ if (!isSupported) {
17
+ el.setAttribute(eventName, 'return;');
18
+ isSupported = typeof el[eventName] == 'function';
19
+ }
20
+ el = null;
21
+ return isSupported;
22
+ }
23
+ function resolveAlias(aliasStr, options, opts) {
24
+ var aliasDefinition = opts.aliases[aliasStr];
25
+ if (aliasDefinition) {
26
+ if (aliasDefinition.alias) resolveAlias(aliasDefinition.alias, undefined, opts); //alias is another alias
27
+ $.extend(true, opts, aliasDefinition); //merge alias definition in the options
28
+ $.extend(true, opts, options); //reapply extra given options
29
+ return true;
30
+ }
31
+ return false;
32
+ }
33
+ function generateMaskSets(opts) {
34
+ var ms = [];
35
+ var genmasks = []; //used to keep track of the masks that where processed, to avoid duplicates
36
+ function getMaskTemplate(mask) {
37
+ if (opts.numericInput) {
38
+ mask = mask.split('').reverse().join('');
39
+ }
40
+ var escaped = false, outCount = 0, greedy = opts.greedy, repeat = opts.repeat;
41
+ if (repeat == "*") greedy = false;
42
+ //if (greedy == true && opts.placeholder == "") opts.placeholder = " ";
43
+ if (mask.length == 1 && greedy == false && repeat != 0) { opts.placeholder = ""; } //hide placeholder with single non-greedy mask
44
+ var singleMask = $.map(mask.split(""), function (element, index) {
45
+ var outElem = [];
46
+ if (element == opts.escapeChar) {
47
+ escaped = true;
48
+ }
49
+ else if ((element != opts.optionalmarker.start && element != opts.optionalmarker.end) || escaped) {
50
+ var maskdef = opts.definitions[element];
51
+ if (maskdef && !escaped) {
52
+ for (var i = 0; i < maskdef.cardinality; i++) {
53
+ outElem.push(opts.placeholder.charAt((outCount + i) % opts.placeholder.length));
54
+ }
55
+ } else {
56
+ outElem.push(element);
57
+ escaped = false;
58
+ }
59
+ outCount += outElem.length;
60
+ return outElem;
61
+ }
62
+ });
63
+
64
+ //allocate repetitions
65
+ var repeatedMask = singleMask.slice();
66
+ for (var i = 1; i < repeat && greedy; i++) {
67
+ repeatedMask = repeatedMask.concat(singleMask.slice());
68
+ }
69
+
70
+ return { "mask": repeatedMask, "repeat": repeat, "greedy": greedy };
71
+ }
72
+ //test definition => {fn: RegExp/function, cardinality: int, optionality: bool, newBlockMarker: bool, offset: int, casing: null/upper/lower, def: definitionSymbol}
73
+ function getTestingChain(mask) {
74
+ if (opts.numericInput) {
75
+ mask = mask.split('').reverse().join('');
76
+ }
77
+ var isOptional = false, escaped = false;
78
+ var newBlockMarker = false; //indicates wheter the begin/ending of a block should be indicated
79
+
80
+ return $.map(mask.split(""), function (element, index) {
81
+ var outElem = [];
82
+
83
+ if (element == opts.escapeChar) {
84
+ escaped = true;
85
+ } else if (element == opts.optionalmarker.start && !escaped) {
86
+ isOptional = true;
87
+ newBlockMarker = true;
88
+ }
89
+ else if (element == opts.optionalmarker.end && !escaped) {
90
+ isOptional = false;
91
+ newBlockMarker = true;
92
+ }
93
+ else {
94
+ var maskdef = opts.definitions[element];
95
+ if (maskdef && !escaped) {
96
+ var prevalidators = maskdef["prevalidator"], prevalidatorsL = prevalidators ? prevalidators.length : 0;
97
+ for (var i = 1; i < maskdef.cardinality; i++) {
98
+ var prevalidator = prevalidatorsL >= i ? prevalidators[i - 1] : [], validator = prevalidator["validator"], cardinality = prevalidator["cardinality"];
99
+ outElem.push({ fn: validator ? typeof validator == 'string' ? new RegExp(validator) : new function () { this.test = validator; } : new RegExp("."), cardinality: cardinality ? cardinality : 1, optionality: isOptional, newBlockMarker: isOptional == true ? newBlockMarker : false, offset: 0, casing: maskdef["casing"], def: maskdef["definitionSymbol"] || element });
100
+ if (isOptional == true) //reset newBlockMarker
101
+ newBlockMarker = false;
102
+ }
103
+ outElem.push({ fn: maskdef.validator ? typeof maskdef.validator == 'string' ? new RegExp(maskdef.validator) : new function () { this.test = maskdef.validator; } : new RegExp("."), cardinality: maskdef.cardinality, optionality: isOptional, newBlockMarker: newBlockMarker, offset: 0, casing: maskdef["casing"], def: maskdef["definitionSymbol"] || element });
104
+ } else {
105
+ outElem.push({ fn: null, cardinality: 0, optionality: isOptional, newBlockMarker: newBlockMarker, offset: 0, casing: null, def: element });
106
+ escaped = false;
107
+ }
108
+ //reset newBlockMarker
109
+ newBlockMarker = false;
110
+ return outElem;
111
+ }
112
+ });
113
+ }
114
+ function markOptional(maskPart) { //needed for the clearOptionalTail functionality
115
+ return opts.optionalmarker.start + maskPart + opts.optionalmarker.end;
116
+ }
117
+ function splitFirstOptionalEndPart(maskPart) {
118
+ var optionalStartMarkers = 0, optionalEndMarkers = 0, mpl = maskPart.length;
119
+ for (var i = 0; i < mpl; i++) {
120
+ if (maskPart.charAt(i) == opts.optionalmarker.start) {
121
+ optionalStartMarkers++;
122
+ }
123
+ if (maskPart.charAt(i) == opts.optionalmarker.end) {
124
+ optionalEndMarkers++;
125
+ }
126
+ if (optionalStartMarkers > 0 && optionalStartMarkers == optionalEndMarkers)
127
+ break;
128
+ }
129
+ var maskParts = [maskPart.substring(0, i)];
130
+ if (i < mpl) {
131
+ maskParts.push(maskPart.substring(i + 1, mpl));
132
+ }
133
+ return maskParts;
134
+ }
135
+ function splitFirstOptionalStartPart(maskPart) {
136
+ var mpl = maskPart.length;
137
+ for (var i = 0; i < mpl; i++) {
138
+ if (maskPart.charAt(i) == opts.optionalmarker.start) {
139
+ break;
140
+ }
141
+ }
142
+ var maskParts = [maskPart.substring(0, i)];
143
+ if (i < mpl) {
144
+ maskParts.push(maskPart.substring(i + 1, mpl));
145
+ }
146
+ return maskParts;
147
+ }
148
+ function generateMask(maskPrefix, maskPart, metadata) {
149
+ var maskParts = splitFirstOptionalEndPart(maskPart);
150
+ var newMask, maskTemplate;
151
+
152
+ var masks = splitFirstOptionalStartPart(maskParts[0]);
153
+ if (masks.length > 1) {
154
+ newMask = maskPrefix + masks[0] + markOptional(masks[1]) + (maskParts.length > 1 ? maskParts[1] : "");
155
+ if ($.inArray(newMask, genmasks) == -1 && newMask != "") {
156
+ genmasks.push(newMask);
157
+ maskTemplate = getMaskTemplate(newMask);
158
+ ms.push({
159
+ "mask": newMask,
160
+ "_buffer": maskTemplate["mask"],
161
+ "buffer": maskTemplate["mask"].slice(),
162
+ "tests": getTestingChain(newMask),
163
+ "lastValidPosition": -1,
164
+ "greedy": maskTemplate["greedy"],
165
+ "repeat": maskTemplate["repeat"],
166
+ "metadata": metadata
167
+ });
168
+ }
169
+ newMask = maskPrefix + masks[0] + (maskParts.length > 1 ? maskParts[1] : "");
170
+ if ($.inArray(newMask, genmasks) == -1 && newMask != "") {
171
+ genmasks.push(newMask);
172
+ maskTemplate = getMaskTemplate(newMask);
173
+ ms.push({
174
+ "mask": newMask,
175
+ "_buffer": maskTemplate["mask"],
176
+ "buffer": maskTemplate["mask"].slice(),
177
+ "tests": getTestingChain(newMask),
178
+ "lastValidPosition": -1,
179
+ "greedy": maskTemplate["greedy"],
180
+ "repeat": maskTemplate["repeat"],
181
+ "metadata": metadata
182
+ });
183
+ }
184
+ if (splitFirstOptionalStartPart(masks[1]).length > 1) { //optional contains another optional
185
+ generateMask(maskPrefix + masks[0], masks[1] + maskParts[1], metadata);
186
+ }
187
+ if (maskParts.length > 1 && splitFirstOptionalStartPart(maskParts[1]).length > 1) {
188
+ generateMask(maskPrefix + masks[0] + markOptional(masks[1]), maskParts[1], metadata);
189
+ generateMask(maskPrefix + masks[0], maskParts[1], metadata);
190
+ }
191
+ }
192
+ else {
193
+ newMask = maskPrefix + maskParts;
194
+ if ($.inArray(newMask, genmasks) == -1 && newMask != "") {
195
+ genmasks.push(newMask);
196
+ maskTemplate = getMaskTemplate(newMask);
197
+ ms.push({
198
+ "mask": newMask,
199
+ "_buffer": maskTemplate["mask"],
200
+ "buffer": maskTemplate["mask"].slice(),
201
+ "tests": getTestingChain(newMask),
202
+ "lastValidPosition": -1,
203
+ "greedy": maskTemplate["greedy"],
204
+ "repeat": maskTemplate["repeat"],
205
+ "metadata": metadata
206
+ });
207
+ }
208
+ }
209
+
210
+ }
211
+
212
+ if ($.isFunction(opts.mask)) { //allow mask to be a preprocessing fn - should return a valid mask
213
+ opts.mask = opts.mask.call(this, opts);
214
+ }
215
+ if ($.isArray(opts.mask)) {
216
+ $.each(opts.mask, function (ndx, msk) {
217
+ if (msk["mask"] != undefined) {
218
+ generateMask("", msk["mask"].toString(), msk);
219
+ } else
220
+ generateMask("", msk.toString());
221
+ });
222
+ } else generateMask("", opts.mask.toString());
223
+
224
+ return opts.greedy ? ms : ms.sort(function (a, b) { return a["mask"].length - b["mask"].length; });
225
+ }
226
+
227
+ var msie1x = typeof ScriptEngineMajorVersion === "function"
228
+ ? ScriptEngineMajorVersion() //IE11 detection
229
+ : new Function("/*@cc_on return @_jscript_version; @*/")() >= 10, //conditional compilation from mickeysoft trick
230
+ ua = navigator.userAgent,
231
+ iphone = ua.match(new RegExp("iphone", "i")) !== null,
232
+ android = ua.match(new RegExp("android.*safari.*", "i")) !== null,
233
+ androidchrome = ua.match(new RegExp("android.*chrome.*", "i")) !== null,
234
+ androidfirefox = ua.match(new RegExp("android.*firefox.*", "i")) !== null,
235
+ kindle = /Kindle/i.test(ua) || /Silk/i.test(ua) || /KFTT/i.test(ua) || /KFOT/i.test(ua) || /KFJWA/i.test(ua) || /KFJWI/i.test(ua) || /KFSOWI/i.test(ua) || /KFTHWA/i.test(ua) || /KFTHWI/i.test(ua) || /KFAPWA/i.test(ua) || /KFAPWI/i.test(ua),
236
+ PasteEventType = isInputEventSupported('paste') ? 'paste' : isInputEventSupported('input') ? 'input' : "propertychange";
237
+
238
+ //if (androidchrome) {
239
+ // var browser = navigator.userAgent.match(new RegExp("chrome.*", "i")),
240
+ // version = parseInt(new RegExp(/[0-9]+/).exec(browser));
241
+ // androidchrome32 = (version == 32);
242
+ //}
243
+
244
+ //masking scope
245
+ //actionObj definition see below
246
+ function maskScope(masksets, activeMasksetIndex, opts, actionObj) {
247
+ var isRTL = false,
248
+ valueOnFocus = getActiveBuffer().join(''),
249
+ $el,
250
+ skipKeyPressEvent = false, //Safari 5.1.x - modal dialog fires keypress twice workaround
251
+ skipInputEvent = false, //skip when triggered from within inputmask
252
+ ignorable = false;
253
+
254
+
255
+ //maskset helperfunctions
256
+
257
+ function getActiveMaskSet() {
258
+ return masksets[activeMasksetIndex];
259
+ }
260
+
261
+ function getActiveTests() {
262
+ return getActiveMaskSet()['tests'];
263
+ }
264
+
265
+ function getActiveBufferTemplate() {
266
+ return getActiveMaskSet()['_buffer'];
267
+ }
268
+
269
+ function getActiveBuffer() {
270
+ return getActiveMaskSet()['buffer'];
271
+ }
272
+
273
+ function isValid(pos, c, strict) { //strict true ~ no correction or autofill
274
+ strict = strict === true; //always set a value to strict to prevent possible strange behavior in the extensions
275
+
276
+ function _isValid(position, activeMaskset, c, strict) {
277
+ var testPos = determineTestPosition(position), loopend = c ? 1 : 0, chrs = '', buffer = activeMaskset["buffer"];
278
+ for (var i = activeMaskset['tests'][testPos].cardinality; i > loopend; i--) {
279
+ chrs += getBufferElement(buffer, testPos - (i - 1));
280
+ }
281
+
282
+ if (c) {
283
+ chrs += c;
284
+ }
285
+
286
+ //return is false or a json object => { pos: ??, c: ??} or true
287
+ return activeMaskset['tests'][testPos].fn != null ?
288
+ activeMaskset['tests'][testPos].fn.test(chrs, buffer, position, strict, opts)
289
+ : (c == getBufferElement(activeMaskset['_buffer'].slice(), position, true) || c == opts.skipOptionalPartCharacter) ?
290
+ { "refresh": true, c: getBufferElement(activeMaskset['_buffer'].slice(), position, true), pos: position }
291
+ : false;
292
+ }
293
+
294
+ function PostProcessResults(maskForwards, results) {
295
+ var hasValidActual = false;
296
+ $.each(results, function (ndx, rslt) {
297
+ hasValidActual = $.inArray(rslt["activeMasksetIndex"], maskForwards) == -1 && rslt["result"] !== false;
298
+ if (hasValidActual) return false;
299
+ });
300
+ if (hasValidActual) { //strip maskforwards
301
+ results = $.map(results, function (rslt, ndx) {
302
+ if ($.inArray(rslt["activeMasksetIndex"], maskForwards) == -1) {
303
+ return rslt;
304
+ } else {
305
+ masksets[rslt["activeMasksetIndex"]]["lastValidPosition"] = actualLVP;
306
+ }
307
+ });
308
+ } else { //keep maskforwards with the least forward
309
+ var lowestPos = -1, lowestIndex = -1, rsltValid;
310
+ $.each(results, function (ndx, rslt) {
311
+ if ($.inArray(rslt["activeMasksetIndex"], maskForwards) != -1 && rslt["result"] !== false & (lowestPos == -1 || lowestPos > rslt["result"]["pos"])) {
312
+ lowestPos = rslt["result"]["pos"];
313
+ lowestIndex = rslt["activeMasksetIndex"];
314
+ }
315
+ });
316
+ results = $.map(results, function (rslt, ndx) {
317
+ if ($.inArray(rslt["activeMasksetIndex"], maskForwards) != -1) {
318
+ if (rslt["result"]["pos"] == lowestPos) {
319
+ return rslt;
320
+ } else if (rslt["result"] !== false) {
321
+ for (var i = pos; i < lowestPos; i++) {
322
+ rsltValid = _isValid(i, masksets[rslt["activeMasksetIndex"]], masksets[lowestIndex]["buffer"][i], true);
323
+ if (rsltValid === false) {
324
+ masksets[rslt["activeMasksetIndex"]]["lastValidPosition"] = lowestPos - 1;
325
+ break;
326
+ } else {
327
+ setBufferElement(masksets[rslt["activeMasksetIndex"]]["buffer"], i, masksets[lowestIndex]["buffer"][i], true);
328
+ masksets[rslt["activeMasksetIndex"]]["lastValidPosition"] = i;
329
+ }
330
+ }
331
+ //also check check for the lowestpos with the new input
332
+ rsltValid = _isValid(lowestPos, masksets[rslt["activeMasksetIndex"]], c, true);
333
+ if (rsltValid !== false) {
334
+ setBufferElement(masksets[rslt["activeMasksetIndex"]]["buffer"], lowestPos, c, true);
335
+ masksets[rslt["activeMasksetIndex"]]["lastValidPosition"] = lowestPos;
336
+ }
337
+ //console.log("ndx " + rslt["activeMasksetIndex"] + " validate " + masksets[rslt["activeMasksetIndex"]]["buffer"].join('') + " lv " + masksets[rslt["activeMasksetIndex"]]['lastValidPosition']);
338
+ return rslt;
339
+ }
340
+ }
341
+ });
342
+ }
343
+ return results;
344
+ }
345
+
346
+ if (strict) {
347
+ var result = _isValid(pos, getActiveMaskSet(), c, strict); //only check validity in current mask when validating strict
348
+ if (result === true) {
349
+ result = { "pos": pos }; //always take a possible corrected maskposition into account
350
+ }
351
+ return result;
352
+ }
353
+
354
+ var results = [], result = false, currentActiveMasksetIndex = activeMasksetIndex,
355
+ actualBuffer = getActiveBuffer().slice(), actualLVP = getActiveMaskSet()["lastValidPosition"],
356
+ actualPrevious = seekPrevious(pos),
357
+ maskForwards = [];
358
+ $.each(masksets, function (index, value) {
359
+ if (typeof (value) == "object") {
360
+ activeMasksetIndex = index;
361
+
362
+ var maskPos = pos;
363
+ var lvp = getActiveMaskSet()['lastValidPosition'],
364
+ rsltValid;
365
+ if (lvp == actualLVP) {
366
+ if ((maskPos - actualLVP) > 1) {
367
+ for (var i = lvp == -1 ? 0 : lvp; i < maskPos; i++) {
368
+ rsltValid = _isValid(i, getActiveMaskSet(), actualBuffer[i], true);
369
+ if (rsltValid === false) {
370
+ break;
371
+ } else {
372
+ setBufferElement(getActiveBuffer(), i, actualBuffer[i], true);
373
+ if (rsltValid === true) {
374
+ rsltValid = { "pos": i }; //always take a possible corrected maskposition into account
375
+ }
376
+ var newValidPosition = rsltValid.pos || i;
377
+ if (getActiveMaskSet()['lastValidPosition'] < newValidPosition)
378
+ getActiveMaskSet()['lastValidPosition'] = newValidPosition; //set new position from isValid
379
+ }
380
+ }
381
+ }
382
+ //does the input match on a further position?
383
+ if (!isMask(maskPos) && !_isValid(maskPos, getActiveMaskSet(), c, strict)) {
384
+ var maxForward = seekNext(maskPos) - maskPos;
385
+ for (var fw = 0; fw < maxForward; fw++) {
386
+ if (_isValid(++maskPos, getActiveMaskSet(), c, strict) !== false)
387
+ break;
388
+ }
389
+ maskForwards.push(activeMasksetIndex);
390
+ //console.log('maskforward ' + activeMasksetIndex + " pos " + pos + " maskPos " + maskPos);
391
+ }
392
+ }
393
+
394
+ if (getActiveMaskSet()['lastValidPosition'] >= actualLVP || activeMasksetIndex == currentActiveMasksetIndex) {
395
+ if (maskPos >= 0 && maskPos < getMaskLength()) {
396
+ result = _isValid(maskPos, getActiveMaskSet(), c, strict);
397
+ if (result !== false) {
398
+ if (result === true) {
399
+ result = { "pos": maskPos }; //always take a possible corrected maskposition into account
400
+ }
401
+ var newValidPosition = result.pos || maskPos;
402
+ if (getActiveMaskSet()['lastValidPosition'] < newValidPosition)
403
+ getActiveMaskSet()['lastValidPosition'] = newValidPosition; //set new position from isValid
404
+ }
405
+ //console.log("pos " + pos + " ndx " + activeMasksetIndex + " validate " + getActiveBuffer().join('') + " lv " + getActiveMaskSet()['lastValidPosition']);
406
+ results.push({ "activeMasksetIndex": index, "result": result });
407
+ }
408
+ }
409
+ }
410
+ });
411
+ activeMasksetIndex = currentActiveMasksetIndex; //reset activeMasksetIndex
412
+
413
+ return PostProcessResults(maskForwards, results); //return results of the multiple mask validations
414
+ }
415
+
416
+ function determineActiveMasksetIndex() {
417
+ var currentMasksetIndex = activeMasksetIndex,
418
+ highestValid = { "activeMasksetIndex": 0, "lastValidPosition": -1, "next": -1 };
419
+ $.each(masksets, function (index, value) {
420
+ if (typeof (value) == "object") {
421
+ activeMasksetIndex = index;
422
+ if (getActiveMaskSet()['lastValidPosition'] > highestValid['lastValidPosition']) {
423
+ highestValid["activeMasksetIndex"] = index;
424
+ highestValid["lastValidPosition"] = getActiveMaskSet()['lastValidPosition'];
425
+ highestValid["next"] = seekNext(getActiveMaskSet()['lastValidPosition']);
426
+ } else if (getActiveMaskSet()['lastValidPosition'] == highestValid['lastValidPosition'] &&
427
+ (highestValid['next'] == -1 || highestValid['next'] > seekNext(getActiveMaskSet()['lastValidPosition']))) {
428
+ highestValid["activeMasksetIndex"] = index;
429
+ highestValid["lastValidPosition"] = getActiveMaskSet()['lastValidPosition'];
430
+ highestValid["next"] = seekNext(getActiveMaskSet()['lastValidPosition']);
431
+ }
432
+ }
433
+ });
434
+
435
+ activeMasksetIndex = highestValid["lastValidPosition"] != -1 && masksets[currentMasksetIndex]["lastValidPosition"] == highestValid["lastValidPosition"] ? currentMasksetIndex : highestValid["activeMasksetIndex"];
436
+ if (currentMasksetIndex != activeMasksetIndex) {
437
+ clearBuffer(getActiveBuffer(), seekNext(highestValid["lastValidPosition"]), getMaskLength());
438
+ getActiveMaskSet()["writeOutBuffer"] = true;
439
+ }
440
+ $el.data('_inputmask')['activeMasksetIndex'] = activeMasksetIndex; //store the activeMasksetIndex
441
+ }
442
+
443
+ function isMask(pos) {
444
+ var testPos = determineTestPosition(pos);
445
+ var test = getActiveTests()[testPos];
446
+
447
+ return test != undefined ? test.fn : false;
448
+ }
449
+
450
+ function determineTestPosition(pos) {
451
+ return pos % getActiveTests().length;
452
+ }
453
+
454
+ function getMaskLength() {
455
+ var buffer=getActiveBufferTemplate(), greedy=getActiveMaskSet()['greedy'], repeat=getActiveMaskSet()['repeat'], currentBuffer=getActiveBuffer();
456
+
457
+ if($.isFunction(opts.getMaskLength)) return opts.getMaskLength(buffer, greedy, repeat, currentBuffer, opts);
458
+
459
+ var calculatedLength = buffer.length;
460
+ if (!greedy) {
461
+ if (repeat == "*") {
462
+ calculatedLength = currentBuffer.length + 1;
463
+ } else if (repeat > 1) {
464
+ calculatedLength += (buffer.length * (repeat - 1));
465
+ }
466
+ }
467
+ return calculatedLength;
468
+ }
469
+
470
+ //pos: from position
471
+
472
+ function seekNext(pos) {
473
+ var maskL = getMaskLength();
474
+ if (pos >= maskL) return maskL;
475
+ var position = pos;
476
+ while (++position < maskL && !isMask(position)) {
477
+ }
478
+ return position;
479
+ }
480
+
481
+ //pos: from position
482
+
483
+ function seekPrevious(pos) {
484
+ var position = pos;
485
+ if (position <= 0) return 0;
486
+
487
+ while (--position > 0 && !isMask(position)) {
488
+ }
489
+ ;
490
+ return position;
491
+ }
492
+
493
+ function setBufferElement(buffer, position, element, autoPrepare) {
494
+ if (autoPrepare) position = prepareBuffer(buffer, position);
495
+
496
+ var test = getActiveTests()[determineTestPosition(position)];
497
+ var elem = element;
498
+ if (elem != undefined && test != undefined) {
499
+ switch (test.casing) {
500
+ case "upper":
501
+ elem = element.toUpperCase();
502
+ break;
503
+ case "lower":
504
+ elem = element.toLowerCase();
505
+ break;
506
+ }
507
+ }
508
+
509
+ buffer[position] = elem;
510
+ }
511
+
512
+ function getBufferElement(buffer, position, autoPrepare) {
513
+ if (autoPrepare) position = prepareBuffer(buffer, position);
514
+ return buffer[position];
515
+ }
516
+
517
+ //needed to handle the non-greedy mask repetitions
518
+
519
+ function prepareBuffer(buffer, position) {
520
+ var j;
521
+ while (buffer[position] == undefined && buffer.length < getMaskLength()) {
522
+ j = 0;
523
+ while (getActiveBufferTemplate()[j] !== undefined) { //add a new buffer
524
+ buffer.push(getActiveBufferTemplate()[j++]);
525
+ }
526
+ }
527
+
528
+ return position;
529
+ }
530
+
531
+ function writeBuffer(input, buffer, caretPos) {
532
+ input._valueSet(buffer.join(''));
533
+ if (caretPos != undefined) {
534
+ caret(input, caretPos);
535
+ }
536
+ }
537
+
538
+ function clearBuffer(buffer, start, end, stripNomasks) {
539
+ for (var i = start, maskL = getMaskLength() ; i < end && i < maskL; i++) {
540
+ if (stripNomasks === true) {
541
+ if (!isMask(i))
542
+ setBufferElement(buffer, i, "");
543
+ } else
544
+ setBufferElement(buffer, i, getBufferElement(getActiveBufferTemplate().slice(), i, true));
545
+ }
546
+ }
547
+
548
+ function setReTargetPlaceHolder(buffer, pos) {
549
+ var testPos = determineTestPosition(pos);
550
+ setBufferElement(buffer, pos, getBufferElement(getActiveBufferTemplate(), testPos));
551
+ }
552
+
553
+ function getPlaceHolder(pos) {
554
+ return opts.placeholder.charAt(pos % opts.placeholder.length);
555
+ }
556
+
557
+ function checkVal(input, writeOut, strict, nptvl, intelliCheck) {
558
+ var inputValue = nptvl != undefined ? nptvl.slice() : truncateInput(input._valueGet()).split('');
559
+
560
+ $.each(masksets, function (ndx, ms) {
561
+ if (typeof (ms) == "object") {
562
+ ms["buffer"] = ms["_buffer"].slice();
563
+ ms["lastValidPosition"] = -1;
564
+ ms["p"] = -1;
565
+ }
566
+ });
567
+ if (strict !== true) activeMasksetIndex = 0;
568
+ if (writeOut) input._valueSet(""); //initial clear
569
+ var ml = getMaskLength();
570
+ $.each(inputValue, function (ndx, charCode) {
571
+ if (intelliCheck === true) {
572
+ var p = getActiveMaskSet()["p"], lvp = p == -1 ? p : seekPrevious(p),
573
+ pos = lvp == -1 ? ndx : seekNext(lvp);
574
+ if ($.inArray(charCode, getActiveBufferTemplate().slice(lvp + 1, pos)) == -1) {
575
+ keypressEvent.call(input, undefined, true, charCode.charCodeAt(0), writeOut, strict, ndx);
576
+ }
577
+ } else {
578
+ keypressEvent.call(input, undefined, true, charCode.charCodeAt(0), writeOut, strict, ndx);
579
+ strict = strict || (ndx > 0 && ndx > getActiveMaskSet()["p"]);
580
+ }
581
+ });
582
+
583
+ if (strict === true && getActiveMaskSet()["p"] != -1) {
584
+ getActiveMaskSet()["lastValidPosition"] = seekPrevious(getActiveMaskSet()["p"]);
585
+ }
586
+ }
587
+
588
+ function escapeRegex(str) {
589
+ return $.inputmask.escapeRegex.call(this, str);
590
+ }
591
+
592
+ function truncateInput(inputValue) {
593
+ return inputValue.replace(new RegExp("(" + escapeRegex(getActiveBufferTemplate().join('')) + ")*$"), "");
594
+ }
595
+
596
+ function clearOptionalTail(input) {
597
+ var buffer = getActiveBuffer(), tmpBuffer = buffer.slice(), testPos, pos;
598
+ for (var pos = tmpBuffer.length - 1; pos >= 0; pos--) {
599
+ var testPos = determineTestPosition(pos);
600
+ if (getActiveTests()[testPos].optionality) {
601
+ if (!isMask(pos) || !isValid(pos, buffer[pos], true))
602
+ tmpBuffer.pop();
603
+ else break;
604
+ } else break;
605
+ }
606
+ writeBuffer(input, tmpBuffer);
607
+ }
608
+
609
+ function unmaskedvalue($input, skipDatepickerCheck) {
610
+ if (getActiveTests() && (skipDatepickerCheck === true || !$input.hasClass('hasDatepicker'))) {
611
+ var umValue = $.map(getActiveBuffer(), function (element, index) {
612
+ return isMask(index) && isValid(index, element, true) ? element : null;
613
+ });
614
+ var unmaskedValue = (isRTL ? umValue.reverse() : umValue).join('');
615
+ return $.isFunction(opts.onUnMask) ? opts.onUnMask.call($input, getActiveBuffer().join(''), unmaskedValue, opts) : unmaskedValue;
616
+ } else {
617
+ return $input[0]._valueGet();
618
+ }
619
+ }
620
+
621
+ function TranslatePosition(pos) {
622
+ if (isRTL && typeof pos == 'number' && (!opts.greedy || opts.placeholder != "")) {
623
+ var bffrLght = getActiveBuffer().length;
624
+ pos = bffrLght - pos;
625
+ }
626
+ return pos;
627
+ }
628
+
629
+ function caret(input, begin, end) {
630
+ var npt = input.jquery && input.length > 0 ? input[0] : input, range;
631
+ if (typeof begin == 'number') {
632
+ begin = TranslatePosition(begin);
633
+ end = TranslatePosition(end);
634
+ if (!$(npt).is(':visible')) {
635
+ return;
636
+ }
637
+ end = (typeof end == 'number') ? end : begin;
638
+ npt.scrollLeft = npt.scrollWidth;
639
+ if (opts.insertMode == false && begin == end) end++; //set visualization for insert/overwrite mode
640
+ if (npt.setSelectionRange) {
641
+ npt.selectionStart = begin;
642
+ npt.selectionEnd = end;
643
+
644
+ } else if (npt.createTextRange) {
645
+ range = npt.createTextRange();
646
+ range.collapse(true);
647
+ range.moveEnd('character', end);
648
+ range.moveStart('character', begin);
649
+ range.select();
650
+ }
651
+ } else {
652
+ if (!$(input).is(':visible')) {
653
+ return { "begin": 0, "end": 0 };
654
+ }
655
+ if (npt.setSelectionRange) {
656
+ begin = npt.selectionStart;
657
+ end = npt.selectionEnd;
658
+ } else if (document.selection && document.selection.createRange) {
659
+ range = document.selection.createRange();
660
+ begin = 0 - range.duplicate().moveStart('character', -100000);
661
+ end = begin + range.text.length;
662
+ }
663
+ begin = TranslatePosition(begin);
664
+ end = TranslatePosition(end);
665
+ return { "begin": begin, "end": end };
666
+ }
667
+ }
668
+
669
+ function isComplete(buffer) { //return true / false / undefined (repeat *)
670
+ if($.isFunction(opts.isComplete)) return opts.isComplete.call($el, buffer, opts);
671
+ if (opts.repeat == "*") return undefined;
672
+ var complete = false, highestValidPosition = 0, currentActiveMasksetIndex = activeMasksetIndex;
673
+ $.each(masksets, function (ndx, ms) {
674
+ if (typeof (ms) == "object") {
675
+ activeMasksetIndex = ndx;
676
+ var aml = seekPrevious(getMaskLength());
677
+ if (ms["lastValidPosition"] >= highestValidPosition && ms["lastValidPosition"] == aml) {
678
+ var msComplete = true;
679
+ for (var i = 0; i <= aml; i++) {
680
+ var mask = isMask(i), testPos = determineTestPosition(i);
681
+ if ((mask && (buffer[i] == undefined || buffer[i] == getPlaceHolder(i))) || (!mask && buffer[i] != getActiveBufferTemplate()[testPos])) {
682
+ msComplete = false;
683
+ break;
684
+ }
685
+ }
686
+ complete = complete || msComplete;
687
+ if (complete) //break loop
688
+ return false;
689
+ }
690
+ highestValidPosition = ms["lastValidPosition"];
691
+ }
692
+ });
693
+ activeMasksetIndex = currentActiveMasksetIndex; //reset activeMaskset
694
+ return complete;
695
+ }
696
+
697
+ function isSelection(begin, end) {
698
+ return isRTL ? (begin - end) > 1 || ((begin - end) == 1 && opts.insertMode) :
699
+ (end - begin) > 1 || ((end - begin) == 1 && opts.insertMode);
700
+ }
701
+
702
+
703
+ //private functions
704
+ function installEventRuler(npt) {
705
+ var events = $._data(npt).events;
706
+
707
+ $.each(events, function (eventType, eventHandlers) {
708
+ $.each(eventHandlers, function (ndx, eventHandler) {
709
+ if (eventHandler.namespace == "inputmask") {
710
+ if (eventHandler.type != "setvalue") {
711
+ var handler = eventHandler.handler;
712
+ eventHandler.handler = function (e) {
713
+ if (this.readOnly || this.disabled)
714
+ e.preventDefault;
715
+ else
716
+ return handler.apply(this, arguments);
717
+ };
718
+ }
719
+ }
720
+ });
721
+ });
722
+ }
723
+
724
+ function patchValueProperty(npt) {
725
+ function PatchValhook(type) {
726
+ if ($.valHooks[type] == undefined || $.valHooks[type].inputmaskpatch != true) {
727
+ var valueGet = $.valHooks[type] && $.valHooks[type].get ? $.valHooks[type].get : function (elem) { return elem.value; };
728
+ var valueSet = $.valHooks[type] && $.valHooks[type].set ? $.valHooks[type].set : function (elem, value) {
729
+ elem.value = value;
730
+ return elem;
731
+ };
732
+
733
+ $.valHooks[type] = {
734
+ get: function (elem) {
735
+ var $elem = $(elem);
736
+ if ($elem.data('_inputmask')) {
737
+ if ($elem.data('_inputmask')['opts'].autoUnmask)
738
+ return $elem.inputmask('unmaskedvalue');
739
+ else {
740
+ var result = valueGet(elem),
741
+ inputData = $elem.data('_inputmask'), masksets = inputData['masksets'],
742
+ activeMasksetIndex = inputData['activeMasksetIndex'];
743
+ return result != masksets[activeMasksetIndex]['_buffer'].join('') ? result : '';
744
+ }
745
+ } else return valueGet(elem);
746
+ },
747
+ set: function (elem, value) {
748
+ var $elem = $(elem);
749
+ var result = valueSet(elem, value);
750
+ if ($elem.data('_inputmask')) $elem.triggerHandler('setvalue.inputmask');
751
+ return result;
752
+ },
753
+ inputmaskpatch: true
754
+ };
755
+ }
756
+ }
757
+ var valueProperty;
758
+ if (Object.getOwnPropertyDescriptor)
759
+ valueProperty = Object.getOwnPropertyDescriptor(npt, "value");
760
+ if (valueProperty && valueProperty.get) {
761
+ if (!npt._valueGet) {
762
+ var valueGet = valueProperty.get;
763
+ var valueSet = valueProperty.set;
764
+ npt._valueGet = function () {
765
+ return isRTL ? valueGet.call(this).split('').reverse().join('') : valueGet.call(this);
766
+ };
767
+ npt._valueSet = function (value) {
768
+ valueSet.call(this, isRTL ? value.split('').reverse().join('') : value);
769
+ };
770
+
771
+ Object.defineProperty(npt, "value", {
772
+ get: function () {
773
+ var $self = $(this), inputData = $(this).data('_inputmask'), masksets = inputData['masksets'],
774
+ activeMasksetIndex = inputData['activeMasksetIndex'];
775
+ return inputData && inputData['opts'].autoUnmask ? $self.inputmask('unmaskedvalue') : valueGet.call(this) != masksets[activeMasksetIndex]['_buffer'].join('') ? valueGet.call(this) : '';
776
+ },
777
+ set: function (value) {
778
+ valueSet.call(this, value);
779
+ $(this).triggerHandler('setvalue.inputmask');
780
+ }
781
+ });
782
+ }
783
+ } else if (document.__lookupGetter__ && npt.__lookupGetter__("value")) {
784
+ if (!npt._valueGet) {
785
+ var valueGet = npt.__lookupGetter__("value");
786
+ var valueSet = npt.__lookupSetter__("value");
787
+ npt._valueGet = function () {
788
+ return isRTL ? valueGet.call(this).split('').reverse().join('') : valueGet.call(this);
789
+ };
790
+ npt._valueSet = function (value) {
791
+ valueSet.call(this, isRTL ? value.split('').reverse().join('') : value);
792
+ };
793
+
794
+ npt.__defineGetter__("value", function () {
795
+ var $self = $(this), inputData = $(this).data('_inputmask'), masksets = inputData['masksets'],
796
+ activeMasksetIndex = inputData['activeMasksetIndex'];
797
+ return inputData && inputData['opts'].autoUnmask ? $self.inputmask('unmaskedvalue') : valueGet.call(this) != masksets[activeMasksetIndex]['_buffer'].join('') ? valueGet.call(this) : '';
798
+ });
799
+ npt.__defineSetter__("value", function (value) {
800
+ valueSet.call(this, value);
801
+ $(this).triggerHandler('setvalue.inputmask');
802
+ });
803
+ }
804
+ } else {
805
+ if (!npt._valueGet) {
806
+ npt._valueGet = function () { return isRTL ? this.value.split('').reverse().join('') : this.value; };
807
+ npt._valueSet = function (value) { this.value = isRTL ? value.split('').reverse().join('') : value; };
808
+ }
809
+ PatchValhook(npt.type);
810
+ }
811
+ }
812
+
813
+ //shift chars to left from start to end and put c at end position if defined
814
+ function shiftL(start, end, c, maskJumps) {
815
+ var buffer = getActiveBuffer();
816
+ if (maskJumps !== false) //jumping over nonmask position
817
+ while (!isMask(start) && start - 1 >= 0) start--;
818
+ for (var i = start; i < end && i < getMaskLength() ; i++) {
819
+ if (isMask(i)) {
820
+ setReTargetPlaceHolder(buffer, i);
821
+ var j = seekNext(i);
822
+ var p = getBufferElement(buffer, j);
823
+ if (p != getPlaceHolder(j)) {
824
+ if (j < getMaskLength() && isValid(i, p, true) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def) {
825
+ setBufferElement(buffer, i, p, true);
826
+ } else {
827
+ if (isMask(i))
828
+ break;
829
+ }
830
+ }
831
+ } else {
832
+ setReTargetPlaceHolder(buffer, i);
833
+ }
834
+ }
835
+ if (c != undefined)
836
+ setBufferElement(buffer, seekPrevious(end), c);
837
+
838
+ if (getActiveMaskSet()["greedy"] == false) {
839
+ var trbuffer = truncateInput(buffer.join('')).split('');
840
+ buffer.length = trbuffer.length;
841
+ for (var i = 0, bl = buffer.length; i < bl; i++) {
842
+ buffer[i] = trbuffer[i];
843
+ }
844
+ if (buffer.length == 0) getActiveMaskSet()["buffer"] = getActiveBufferTemplate().slice();
845
+ }
846
+ return start; //return the used start position
847
+ }
848
+
849
+ function shiftR(start, end, c) {
850
+ var buffer = getActiveBuffer();
851
+ if (getBufferElement(buffer, start, true) != getPlaceHolder(start)) {
852
+ for (var i = seekPrevious(end) ; i > start && i >= 0; i--) {
853
+ if (isMask(i)) {
854
+ var j = seekPrevious(i);
855
+ var t = getBufferElement(buffer, j);
856
+ if (t != getPlaceHolder(j)) {
857
+ if (isValid(i, t, true) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def) {
858
+ setBufferElement(buffer, i, t, true);
859
+ setReTargetPlaceHolder(buffer, j);
860
+ } //else break;
861
+ }
862
+ } else
863
+ setReTargetPlaceHolder(buffer, i);
864
+ }
865
+ }
866
+ if (c != undefined && getBufferElement(buffer, start) == getPlaceHolder(start))
867
+ setBufferElement(buffer, start, c);
868
+ var lengthBefore = buffer.length;
869
+ if (getActiveMaskSet()["greedy"] == false) {
870
+ var trbuffer = truncateInput(buffer.join('')).split('');
871
+ buffer.length = trbuffer.length;
872
+ for (var i = 0, bl = buffer.length; i < bl; i++) {
873
+ buffer[i] = trbuffer[i];
874
+ }
875
+ if (buffer.length == 0) getActiveMaskSet()["buffer"] = getActiveBufferTemplate().slice();
876
+ }
877
+ return end - (lengthBefore - buffer.length); //return new start position
878
+ }
879
+
880
+ ;
881
+
882
+
883
+ function HandleRemove(input, k, pos) {
884
+ if (opts.numericInput || isRTL) {
885
+ switch (k) {
886
+ case opts.keyCode.BACKSPACE:
887
+ k = opts.keyCode.DELETE;
888
+ break;
889
+ case opts.keyCode.DELETE:
890
+ k = opts.keyCode.BACKSPACE;
891
+ break;
892
+ }
893
+ if (isRTL) {
894
+ var pend = pos.end;
895
+ pos.end = pos.begin;
896
+ pos.begin = pend;
897
+ }
898
+ }
899
+
900
+ var isSelection = true;
901
+ if (pos.begin == pos.end) {
902
+ var posBegin = k == opts.keyCode.BACKSPACE ? pos.begin - 1 : pos.begin;
903
+ if (opts.isNumeric && opts.radixPoint != "" && getActiveBuffer()[posBegin] == opts.radixPoint) {
904
+ pos.begin = (getActiveBuffer().length - 1 == posBegin) /* radixPoint is latest? delete it */ ? pos.begin : k == opts.keyCode.BACKSPACE ? posBegin : seekNext(posBegin);
905
+ pos.end = pos.begin;
906
+ }
907
+ isSelection = false;
908
+ if (k == opts.keyCode.BACKSPACE)
909
+ pos.begin--;
910
+ else if (k == opts.keyCode.DELETE)
911
+ pos.end++;
912
+ } else if (pos.end - pos.begin == 1 && !opts.insertMode) {
913
+ isSelection = false;
914
+ if (k == opts.keyCode.BACKSPACE)
915
+ pos.begin--;
916
+ }
917
+
918
+ clearBuffer(getActiveBuffer(), pos.begin, pos.end);
919
+
920
+ var ml = getMaskLength();
921
+ if (opts.greedy == false && (isNaN(opts.repeat) || opts.repeat > 0)) {
922
+ shiftL(pos.begin, ml, undefined, !isRTL && (k == opts.keyCode.BACKSPACE && !isSelection));
923
+ } else {
924
+ var newpos = pos.begin;
925
+ for (var i = pos.begin; i < pos.end; i++) { //seeknext to skip placeholders at start in selection
926
+ if (isMask(i) || !isSelection)
927
+ newpos = shiftL(pos.begin, ml, undefined, !isRTL && (k == opts.keyCode.BACKSPACE && !isSelection));
928
+ }
929
+ if (!isSelection) pos.begin = newpos;
930
+ }
931
+ var firstMaskPos = seekNext(-1);
932
+ clearBuffer(getActiveBuffer(), pos.begin, pos.end, true);
933
+ checkVal(input, false, false, getActiveBuffer());
934
+ if (getActiveMaskSet()['lastValidPosition'] < firstMaskPos) {
935
+ getActiveMaskSet()["lastValidPosition"] = -1;
936
+ getActiveMaskSet()["p"] = firstMaskPos;
937
+ } else {
938
+ getActiveMaskSet()["p"] = pos.begin;
939
+ }
940
+ }
941
+
942
+ function keydownEvent(e) {
943
+ //Safari 5.1.x - modal dialog fires keypress twice workaround
944
+ skipKeyPressEvent = false;
945
+ var input = this, $input = $(input), k = e.keyCode, pos = caret(input);
946
+
947
+ //backspace, delete, and escape get special treatment
948
+ if (k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE || (iphone && k == 127) || e.ctrlKey && k == 88) { //backspace/delete
949
+ e.preventDefault(); //stop default action but allow propagation
950
+ if (k == 88) valueOnFocus = getActiveBuffer().join('');
951
+ HandleRemove(input, k, pos);
952
+ determineActiveMasksetIndex();
953
+ writeBuffer(input, getActiveBuffer(), getActiveMaskSet()["p"]);
954
+ if (input._valueGet() == getActiveBufferTemplate().join(''))
955
+ $input.trigger('cleared');
956
+
957
+ if (opts.showTooltip) { //update tooltip
958
+ $input.prop("title", getActiveMaskSet()["mask"]);
959
+ }
960
+ } else if (k == opts.keyCode.END || k == opts.keyCode.PAGE_DOWN) { //when END or PAGE_DOWN pressed set position at lastmatch
961
+ setTimeout(function () {
962
+ var caretPos = seekNext(getActiveMaskSet()["lastValidPosition"]);
963
+ if (!opts.insertMode && caretPos == getMaskLength() && !e.shiftKey) caretPos--;
964
+ caret(input, e.shiftKey ? pos.begin : caretPos, caretPos);
965
+ }, 0);
966
+ } else if ((k == opts.keyCode.HOME && !e.shiftKey) || k == opts.keyCode.PAGE_UP) { //Home or page_up
967
+ caret(input, 0, e.shiftKey ? pos.begin : 0);
968
+ } else if (k == opts.keyCode.ESCAPE || (k == 90 && e.ctrlKey)) { //escape && undo
969
+ checkVal(input, true, false, valueOnFocus.split(''));
970
+ $input.click();
971
+ } else if (k == opts.keyCode.INSERT && !(e.shiftKey || e.ctrlKey)) { //insert
972
+ opts.insertMode = !opts.insertMode;
973
+ caret(input, !opts.insertMode && pos.begin == getMaskLength() ? pos.begin - 1 : pos.begin);
974
+ } else if (opts.insertMode == false && !e.shiftKey) {
975
+ if (k == opts.keyCode.RIGHT) {
976
+ setTimeout(function () {
977
+ var caretPos = caret(input);
978
+ caret(input, caretPos.begin);
979
+ }, 0);
980
+ } else if (k == opts.keyCode.LEFT) {
981
+ setTimeout(function () {
982
+ var caretPos = caret(input);
983
+ caret(input, caretPos.begin - 1);
984
+ }, 0);
985
+ }
986
+ }
987
+
988
+ var currentCaretPos = caret(input);
989
+ if (opts.onKeyDown.call(this, e, getActiveBuffer(), opts) === true) //extra stuff to execute on keydown
990
+ caret(input, currentCaretPos.begin, currentCaretPos.end);
991
+ ignorable = $.inArray(k, opts.ignorables) != -1;
992
+ }
993
+
994
+
995
+ function keypressEvent(e, checkval, k, writeOut, strict, ndx) {
996
+ //Safari 5.1.x - modal dialog fires keypress twice workaround
997
+ if (k == undefined && skipKeyPressEvent) return false;
998
+ skipKeyPressEvent = true;
999
+
1000
+ var input = this, $input = $(input);
1001
+
1002
+ e = e || window.event;
1003
+ var k = checkval ? k : (e.which || e.charCode || e.keyCode);
1004
+
1005
+ if (checkval !== true && (!(e.ctrlKey && e.altKey) && (e.ctrlKey || e.metaKey || ignorable))) {
1006
+ return true;
1007
+ } else {
1008
+ if (k) {
1009
+ //special treat the decimal separator
1010
+ if (checkval !== true && k == 46 && e.shiftKey == false && opts.radixPoint == ",") k = 44;
1011
+
1012
+ var pos, results, result, c = String.fromCharCode(k);
1013
+ if (checkval) {
1014
+ var pcaret = strict ? ndx : getActiveMaskSet()["lastValidPosition"] + 1;
1015
+ pos = { begin: pcaret, end: pcaret };
1016
+ } else {
1017
+ pos = caret(input);
1018
+ }
1019
+
1020
+ //should we clear a possible selection??
1021
+ var isSlctn = isSelection(pos.begin, pos.end),
1022
+ initialIndex = activeMasksetIndex;
1023
+ if (isSlctn) {
1024
+ $.each(masksets, function (ndx, lmnt) { //init undobuffer for recovery when not valid
1025
+ if (typeof (lmnt) == "object") {
1026
+ activeMasksetIndex = ndx;
1027
+ getActiveMaskSet()["undoBuffer"] = getActiveBuffer().join('');
1028
+ }
1029
+ });
1030
+ activeMasksetIndex = initialIndex; //restore index
1031
+ HandleRemove(input, opts.keyCode.DELETE, pos);
1032
+ if (!opts.insertMode) { //preserve some space
1033
+ $.each(masksets, function (ndx, lmnt) {
1034
+ if (typeof (lmnt) == "object") {
1035
+ activeMasksetIndex = ndx;
1036
+ shiftR(pos.begin, getMaskLength());
1037
+ getActiveMaskSet()["lastValidPosition"] = seekNext(getActiveMaskSet()["lastValidPosition"]);
1038
+ }
1039
+ });
1040
+ }
1041
+ activeMasksetIndex = initialIndex; //restore index
1042
+ }
1043
+
1044
+ var radixPosition = getActiveBuffer().join('').indexOf(opts.radixPoint);
1045
+ if (opts.isNumeric && checkval !== true && radixPosition != -1) {
1046
+ if (opts.greedy && pos.begin <= radixPosition) {
1047
+ pos.begin = seekPrevious(pos.begin);
1048
+ pos.end = pos.begin;
1049
+ } else if (c == opts.radixPoint) {
1050
+ pos.begin = radixPosition;
1051
+ pos.end = pos.begin;
1052
+ }
1053
+ }
1054
+
1055
+
1056
+ var p = pos.begin;
1057
+ results = isValid(p, c, strict);
1058
+ if (strict === true) results = [{ "activeMasksetIndex": activeMasksetIndex, "result": results }];
1059
+ var minimalForwardPosition = -1;
1060
+ $.each(results, function (index, result) {
1061
+ activeMasksetIndex = result["activeMasksetIndex"];
1062
+ getActiveMaskSet()["writeOutBuffer"] = true;
1063
+ var np = result["result"];
1064
+ if (np !== false) {
1065
+ var refresh = false, buffer = getActiveBuffer();
1066
+ if (np !== true) {
1067
+ refresh = np["refresh"]; //only rewrite buffer from isValid
1068
+ p = np.pos != undefined ? np.pos : p; //set new position from isValid
1069
+ c = np.c != undefined ? np.c : c; //set new char from isValid
1070
+ }
1071
+ if (refresh !== true) {
1072
+ if (opts.insertMode == true) {
1073
+ var lastUnmaskedPosition = getMaskLength();
1074
+ var bfrClone = buffer.slice();
1075
+ while (getBufferElement(bfrClone, lastUnmaskedPosition, true) != getPlaceHolder(lastUnmaskedPosition) && lastUnmaskedPosition >= p) {
1076
+ lastUnmaskedPosition = lastUnmaskedPosition == 0 ? -1 : seekPrevious(lastUnmaskedPosition);
1077
+ }
1078
+ if (lastUnmaskedPosition >= p) {
1079
+ shiftR(p, getMaskLength(), c);
1080
+ //shift the lvp if needed
1081
+ var lvp = getActiveMaskSet()["lastValidPosition"], nlvp = seekNext(lvp);
1082
+ if (nlvp != getMaskLength() && lvp >= p && (getBufferElement(getActiveBuffer().slice(), nlvp, true) != getPlaceHolder(nlvp))) {
1083
+ getActiveMaskSet()["lastValidPosition"] = nlvp;
1084
+ }
1085
+ } else getActiveMaskSet()["writeOutBuffer"] = false;
1086
+ } else setBufferElement(buffer, p, c, true);
1087
+ if (minimalForwardPosition == -1 || minimalForwardPosition > seekNext(p)) {
1088
+ minimalForwardPosition = seekNext(p);
1089
+ }
1090
+ } else if (!strict) {
1091
+ var nextPos = p < getMaskLength() ? p + 1 : p;
1092
+ if (minimalForwardPosition == -1 || minimalForwardPosition > nextPos) {
1093
+ minimalForwardPosition = nextPos;
1094
+ }
1095
+ }
1096
+ if (minimalForwardPosition > getActiveMaskSet()["p"])
1097
+ getActiveMaskSet()["p"] = minimalForwardPosition; //needed for checkval strict
1098
+ }
1099
+ });
1100
+
1101
+ if (strict !== true) {
1102
+ activeMasksetIndex = initialIndex;
1103
+ determineActiveMasksetIndex();
1104
+ }
1105
+ if (writeOut !== false) {
1106
+ $.each(results, function (ndx, rslt) {
1107
+ if (rslt["activeMasksetIndex"] == activeMasksetIndex) {
1108
+ result = rslt;
1109
+ return false;
1110
+ }
1111
+ });
1112
+ if (result != undefined) {
1113
+ var self = this;
1114
+ setTimeout(function () { opts.onKeyValidation.call(self, result["result"], opts); }, 0);
1115
+ if (getActiveMaskSet()["writeOutBuffer"] && result["result"] !== false) {
1116
+ var buffer = getActiveBuffer();
1117
+
1118
+ var newCaretPosition;
1119
+ if (checkval) {
1120
+ newCaretPosition = undefined;
1121
+ } else if (opts.numericInput) {
1122
+ if (p > radixPosition) {
1123
+ newCaretPosition = seekPrevious(minimalForwardPosition);
1124
+ } else if (c == opts.radixPoint) {
1125
+ newCaretPosition = minimalForwardPosition - 1;
1126
+ } else newCaretPosition = seekPrevious(minimalForwardPosition - 1);
1127
+ } else {
1128
+ newCaretPosition = minimalForwardPosition;
1129
+ }
1130
+
1131
+ writeBuffer(input, buffer, newCaretPosition);
1132
+ if (checkval !== true) {
1133
+ setTimeout(function () { //timeout needed for IE
1134
+ if (isComplete(buffer) === true)
1135
+ $input.trigger("complete");
1136
+ skipInputEvent = true;
1137
+ $input.trigger("input");
1138
+ }, 0);
1139
+ }
1140
+ } else if (isSlctn) {
1141
+ getActiveMaskSet()["buffer"] = getActiveMaskSet()["undoBuffer"].split('');
1142
+ }
1143
+ } else if (isSlctn) {
1144
+ getActiveMaskSet()["buffer"] = getActiveMaskSet()["undoBuffer"].split('');
1145
+ }
1146
+ }
1147
+
1148
+ if (opts.showTooltip) { //update tooltip
1149
+ $input.prop("title", getActiveMaskSet()["mask"]);
1150
+ }
1151
+
1152
+ //needed for IE8 and below
1153
+ if (e) e.preventDefault ? e.preventDefault() : e.returnValue = false;
1154
+ }
1155
+ }
1156
+ }
1157
+
1158
+ function keyupEvent(e) {
1159
+ var $input = $(this), input = this, k = e.keyCode, buffer = getActiveBuffer();
1160
+
1161
+ opts.onKeyUp.call(this, e, buffer, opts); //extra stuff to execute on keyup
1162
+ if (k == opts.keyCode.TAB && opts.showMaskOnFocus) {
1163
+ if ($input.hasClass('focus.inputmask') && input._valueGet().length == 0) {
1164
+ buffer = getActiveBufferTemplate().slice();
1165
+ writeBuffer(input, buffer);
1166
+ caret(input, 0);
1167
+ valueOnFocus = getActiveBuffer().join('');
1168
+ } else {
1169
+ writeBuffer(input, buffer);
1170
+ if (buffer.join('') == getActiveBufferTemplate().join('') && $.inArray(opts.radixPoint, buffer) != -1) {
1171
+ caret(input, TranslatePosition(0));
1172
+ $input.click();
1173
+ } else
1174
+ caret(input, TranslatePosition(0), TranslatePosition(getMaskLength()));
1175
+ }
1176
+ }
1177
+ }
1178
+
1179
+ function pasteEvent(e) {
1180
+ if (skipInputEvent === true && e.type == "input") {
1181
+ skipInputEvent = false;
1182
+ return true;
1183
+ }
1184
+
1185
+ var input = this, $input = $(input);
1186
+ //paste event for IE8 and lower I guess ;-)
1187
+ if (e.type == "propertychange" && input._valueGet().length <= getMaskLength()) {
1188
+ return true;
1189
+ }
1190
+ setTimeout(function () {
1191
+ var pasteValue = $.isFunction(opts.onBeforePaste) ? opts.onBeforePaste.call(input, input._valueGet(), opts) : input._valueGet();
1192
+ checkVal(input, false, false, pasteValue.split(''), true);
1193
+ writeBuffer(input, getActiveBuffer());
1194
+ if (isComplete(getActiveBuffer()) === true)
1195
+ $input.trigger("complete");
1196
+ $input.click();
1197
+ }, 0);
1198
+ }
1199
+
1200
+ //not used - attempt to support android
1201
+ function mobileInputEvent(e) {
1202
+ var input = this, $input = $(input);
1203
+
1204
+ //backspace in chrome32 only fires input event - detect & treat
1205
+ var caretPos = caret(input),
1206
+ currentValue = input._valueGet();
1207
+
1208
+ currentValue = currentValue.replace(new RegExp("(" + escapeRegex(getActiveBufferTemplate().join('')) + ")*"), "");
1209
+ //correct caretposition for chrome
1210
+ if (caretPos.begin > currentValue.length) {
1211
+ caret(input, currentValue.length);
1212
+ caretPos = caret(input);
1213
+ }
1214
+ if ((getActiveBuffer().length - currentValue.length) == 1 && currentValue.charAt(caretPos.begin) != getActiveBuffer()[caretPos.begin]
1215
+ && currentValue.charAt(caretPos.begin + 1) != getActiveBuffer()[caretPos.begin]
1216
+ && !isMask(caretPos.begin)) {
1217
+ e.keyCode = opts.keyCode.BACKSPACE;
1218
+ keydownEvent.call(input, e);
1219
+ } else { //nonnumerics don't fire keypress
1220
+ checkVal(input, false, false, currentValue.split(''));
1221
+ writeBuffer(input, getActiveBuffer());
1222
+ if (isComplete(getActiveBuffer()) === true)
1223
+ $input.trigger("complete");
1224
+ $input.click();
1225
+ }
1226
+ e.preventDefault();
1227
+ }
1228
+
1229
+ function mask(el) {
1230
+ $el = $(el);
1231
+ if ($el.is(":input")) {
1232
+ //store tests & original buffer in the input element - used to get the unmasked value
1233
+ $el.data('_inputmask', {
1234
+ 'masksets': masksets,
1235
+ 'activeMasksetIndex': activeMasksetIndex,
1236
+ 'opts': opts,
1237
+ 'isRTL': false
1238
+ });
1239
+
1240
+ //show tooltip
1241
+ if (opts.showTooltip) {
1242
+ $el.prop("title", getActiveMaskSet()["mask"]);
1243
+ }
1244
+
1245
+ //correct greedy setting if needed
1246
+ getActiveMaskSet()['greedy'] = getActiveMaskSet()['greedy'] ? getActiveMaskSet()['greedy'] : getActiveMaskSet()['repeat'] == 0;
1247
+
1248
+ //handle maxlength attribute
1249
+ if ($el.attr("maxLength") != null) //only when the attribute is set
1250
+ {
1251
+ var maxLength = $el.prop('maxLength');
1252
+ if (maxLength > -1) { //handle *-repeat
1253
+ $.each(masksets, function (ndx, ms) {
1254
+ if (typeof (ms) == "object") {
1255
+ if (ms["repeat"] == "*") {
1256
+ ms["repeat"] = maxLength;
1257
+ }
1258
+ }
1259
+ });
1260
+ }
1261
+ if (getMaskLength() >= maxLength && maxLength > -1) { //FF sets no defined max length to -1
1262
+ if (maxLength < getActiveBufferTemplate().length) getActiveBufferTemplate().length = maxLength;
1263
+ if (getActiveMaskSet()['greedy'] == false) {
1264
+ getActiveMaskSet()['repeat'] = Math.round(maxLength / getActiveBufferTemplate().length);
1265
+ }
1266
+ $el.prop('maxLength', getMaskLength() * 2);
1267
+ }
1268
+ }
1269
+
1270
+ patchValueProperty(el);
1271
+
1272
+ if (opts.numericInput) opts.isNumeric = opts.numericInput;
1273
+ if (el.dir == "rtl" || (opts.numericInput && opts.rightAlignNumerics) || (opts.isNumeric && opts.rightAlignNumerics))
1274
+ $el.css("text-align", "right");
1275
+
1276
+ if (el.dir == "rtl" || opts.numericInput) {
1277
+ el.dir = "ltr";
1278
+ $el.removeAttr("dir");
1279
+ var inputData = $el.data('_inputmask');
1280
+ inputData['isRTL'] = true;
1281
+ $el.data('_inputmask', inputData);
1282
+ isRTL = true;
1283
+ }
1284
+
1285
+ //unbind all events - to make sure that no other mask will interfere when re-masking
1286
+ $el.unbind(".inputmask");
1287
+ $el.removeClass('focus.inputmask');
1288
+ //bind events
1289
+ $el.closest('form').bind("submit", function () { //trigger change on submit if any
1290
+ if (valueOnFocus != getActiveBuffer().join('')) {
1291
+ $el.change();
1292
+ }
1293
+ }).bind('reset', function () {
1294
+ setTimeout(function () {
1295
+ $el.trigger("setvalue");
1296
+ }, 0);
1297
+ });
1298
+ $el.bind("mouseenter.inputmask", function () {
1299
+ var $input = $(this), input = this;
1300
+ if (!$input.hasClass('focus.inputmask') && opts.showMaskOnHover) {
1301
+ if (input._valueGet() != getActiveBuffer().join('')) {
1302
+ writeBuffer(input, getActiveBuffer());
1303
+ }
1304
+ }
1305
+ }).bind("blur.inputmask", function () {
1306
+ var $input = $(this), input = this, nptValue = input._valueGet(), buffer = getActiveBuffer();
1307
+ $input.removeClass('focus.inputmask');
1308
+ if (valueOnFocus != getActiveBuffer().join('')) {
1309
+ $input.change();
1310
+ }
1311
+ if (opts.clearMaskOnLostFocus && nptValue != '') {
1312
+ if (nptValue == getActiveBufferTemplate().join(''))
1313
+ input._valueSet('');
1314
+ else { //clearout optional tail of the mask
1315
+ clearOptionalTail(input);
1316
+ }
1317
+ }
1318
+ if (isComplete(buffer) === false) {
1319
+ $input.trigger("incomplete");
1320
+ if (opts.clearIncomplete) {
1321
+ $.each(masksets, function (ndx, ms) {
1322
+ if (typeof (ms) == "object") {
1323
+ ms["buffer"] = ms["_buffer"].slice();
1324
+ ms["lastValidPosition"] = -1;
1325
+ }
1326
+ });
1327
+ activeMasksetIndex = 0;
1328
+ if (opts.clearMaskOnLostFocus)
1329
+ input._valueSet('');
1330
+ else {
1331
+ buffer = getActiveBufferTemplate().slice();
1332
+ writeBuffer(input, buffer);
1333
+ }
1334
+ }
1335
+ }
1336
+ }).bind("focus.inputmask", function () {
1337
+ var $input = $(this), input = this, nptValue = input._valueGet();
1338
+ if (opts.showMaskOnFocus && !$input.hasClass('focus.inputmask') && (!opts.showMaskOnHover || (opts.showMaskOnHover && nptValue == ''))) {
1339
+ if (input._valueGet() != getActiveBuffer().join('')) {
1340
+ writeBuffer(input, getActiveBuffer(), seekNext(getActiveMaskSet()["lastValidPosition"]));
1341
+ }
1342
+ }
1343
+ $input.addClass('focus.inputmask');
1344
+ valueOnFocus = getActiveBuffer().join('');
1345
+ }).bind("mouseleave.inputmask", function () {
1346
+ var $input = $(this), input = this;
1347
+ if (opts.clearMaskOnLostFocus) {
1348
+ if (!$input.hasClass('focus.inputmask') && input._valueGet() != $input.attr("placeholder")) {
1349
+ if (input._valueGet() == getActiveBufferTemplate().join('') || input._valueGet() == '')
1350
+ input._valueSet('');
1351
+ else { //clearout optional tail of the mask
1352
+ clearOptionalTail(input);
1353
+ }
1354
+ }
1355
+ }
1356
+ }).bind("click.inputmask", function () {
1357
+ var input = this;
1358
+ setTimeout(function () {
1359
+ var selectedCaret = caret(input), buffer = getActiveBuffer();
1360
+ if (selectedCaret.begin == selectedCaret.end) {
1361
+ var clickPosition = isRTL ? TranslatePosition(selectedCaret.begin) : selectedCaret.begin,
1362
+ lvp = getActiveMaskSet()["lastValidPosition"],
1363
+ lastPosition;
1364
+ if (opts.isNumeric) {
1365
+ lastPosition = opts.skipRadixDance === false && opts.radixPoint != "" && $.inArray(opts.radixPoint, buffer) != -1 ?
1366
+ (opts.numericInput ? seekNext($.inArray(opts.radixPoint, buffer)) : $.inArray(opts.radixPoint, buffer)) :
1367
+ seekNext(lvp);
1368
+ } else {
1369
+ lastPosition = seekNext(lvp);
1370
+ }
1371
+ if (clickPosition < lastPosition) {
1372
+ if (isMask(clickPosition))
1373
+ caret(input, clickPosition);
1374
+ else caret(input, seekNext(clickPosition));
1375
+ } else
1376
+ caret(input, lastPosition);
1377
+ }
1378
+ }, 0);
1379
+ }).bind('dblclick.inputmask', function () {
1380
+ var input = this;
1381
+ setTimeout(function () {
1382
+ caret(input, 0, seekNext(getActiveMaskSet()["lastValidPosition"]));
1383
+ }, 0);
1384
+ }).bind(PasteEventType + ".inputmask dragdrop.inputmask drop.inputmask", pasteEvent
1385
+ ).bind('setvalue.inputmask', function () {
1386
+ var input = this;
1387
+ checkVal(input, true);
1388
+ valueOnFocus = getActiveBuffer().join('');
1389
+ if (input._valueGet() == getActiveBufferTemplate().join(''))
1390
+ input._valueSet('');
1391
+ }).bind('complete.inputmask', opts.oncomplete
1392
+ ).bind('incomplete.inputmask', opts.onincomplete
1393
+ ).bind('cleared.inputmask', opts.oncleared);
1394
+
1395
+ $el.bind("keydown.inputmask", keydownEvent
1396
+ ).bind("keypress.inputmask", keypressEvent
1397
+ ).bind("keyup.inputmask", keyupEvent);
1398
+
1399
+ // as the other inputevents aren't reliable for the moment we only base on the input event
1400
+ // needs follow-up
1401
+ if (android || androidfirefox || androidchrome || kindle) {
1402
+ $el.attr("autocomplete", "off")
1403
+ .attr("autocorrect", "off")
1404
+ .attr("autocapitalize", "off")
1405
+ .attr("spellcheck", false);
1406
+
1407
+ if (androidfirefox || kindle) {
1408
+ $el.unbind("keydown.inputmask", keydownEvent
1409
+ ).unbind("keypress.inputmask", keypressEvent
1410
+ ).unbind("keyup.inputmask", keyupEvent);
1411
+ if (PasteEventType == "input") {
1412
+ $el.unbind(PasteEventType + ".inputmask");
1413
+ }
1414
+ $el.bind("input.inputmask", mobileInputEvent);
1415
+ }
1416
+ }
1417
+
1418
+ if (msie1x)
1419
+ $el.bind("input.inputmask", pasteEvent);
1420
+
1421
+ //apply mask
1422
+ var initialValue = $.isFunction(opts.onBeforeMask) ? opts.onBeforeMask.call(el, el._valueGet(), opts) : el._valueGet();
1423
+ checkVal(el, true, false, initialValue.split(''));
1424
+ valueOnFocus = getActiveBuffer().join('');
1425
+ // Wrap document.activeElement in a try/catch block since IE9 throw "Unspecified error" if document.activeElement is undefined when we are in an IFrame.
1426
+ var activeElement;
1427
+ try {
1428
+ activeElement = document.activeElement;
1429
+ } catch (e) {
1430
+ }
1431
+ if (activeElement === el) { //position the caret when in focus
1432
+ $el.addClass('focus.inputmask');
1433
+ caret(el, seekNext(getActiveMaskSet()["lastValidPosition"]));
1434
+ } else if (opts.clearMaskOnLostFocus) {
1435
+ if (getActiveBuffer().join('') == getActiveBufferTemplate().join('')) {
1436
+ el._valueSet('');
1437
+ } else {
1438
+ clearOptionalTail(el);
1439
+ }
1440
+ } else {
1441
+ writeBuffer(el, getActiveBuffer());
1442
+ }
1443
+
1444
+ installEventRuler(el);
1445
+ }
1446
+ }
1447
+
1448
+ //action object
1449
+ if (actionObj != undefined) {
1450
+ switch (actionObj["action"]) {
1451
+ case "isComplete":
1452
+ return isComplete(actionObj["buffer"]);
1453
+ case "unmaskedvalue":
1454
+ isRTL = actionObj["$input"].data('_inputmask')['isRTL'];
1455
+ return unmaskedvalue(actionObj["$input"], actionObj["skipDatepickerCheck"]);
1456
+ case "mask":
1457
+ mask(actionObj["el"]);
1458
+ break;
1459
+ case "format":
1460
+ $el = $({});
1461
+ $el.data('_inputmask', {
1462
+ 'masksets': masksets,
1463
+ 'activeMasksetIndex': activeMasksetIndex,
1464
+ 'opts': opts,
1465
+ 'isRTL': opts.numericInput
1466
+ });
1467
+ if (opts.numericInput) {
1468
+ opts.isNumeric = opts.numericInput;
1469
+ isRTL = true;
1470
+ }
1471
+
1472
+ checkVal($el, false, false, actionObj["value"].split(''), true);
1473
+ return getActiveBuffer().join('');
1474
+ case "isValid":
1475
+ $el = $({});
1476
+ $el.data('_inputmask', {
1477
+ 'masksets': masksets,
1478
+ 'activeMasksetIndex': activeMasksetIndex,
1479
+ 'opts': opts,
1480
+ 'isRTL': opts.numericInput
1481
+ });
1482
+ if (opts.numericInput) {
1483
+ opts.isNumeric = opts.numericInput;
1484
+ isRTL = true;
1485
+ }
1486
+
1487
+ checkVal($el, false, true, actionObj["value"].split(''));
1488
+ return isComplete(getActiveBuffer());
1489
+ }
1490
+ }
1491
+ };
1492
+
1493
+ $.inputmask = {
1494
+ //options default
1495
+ defaults: {
1496
+ placeholder: "_",
1497
+ optionalmarker: { start: "[", end: "]" },
1498
+ quantifiermarker: { start: "{", end: "}" },
1499
+ groupmarker: { start: "(", end: ")" },
1500
+ escapeChar: "\\",
1501
+ mask: null,
1502
+ oncomplete: $.noop, //executes when the mask is complete
1503
+ onincomplete: $.noop, //executes when the mask is incomplete and focus is lost
1504
+ oncleared: $.noop, //executes when the mask is cleared
1505
+ repeat: 0, //repetitions of the mask: * ~ forever, otherwise specify an integer
1506
+ greedy: true, //true: allocated buffer for the mask and repetitions - false: allocate only if needed
1507
+ autoUnmask: false, //automatically unmask when retrieving the value with $.fn.val or value if the browser supports __lookupGetter__ or getOwnPropertyDescriptor
1508
+ clearMaskOnLostFocus: true,
1509
+ insertMode: true, //insert the input or overwrite the input
1510
+ clearIncomplete: false, //clear the incomplete input on blur
1511
+ aliases: {}, //aliases definitions => see jquery.inputmask.extensions.js
1512
+ onKeyUp: $.noop, //override to implement autocomplete on certain keys for example
1513
+ onKeyDown: $.noop, //override to implement autocomplete on certain keys for example
1514
+ onBeforeMask: undefined, //executes before masking the initial value to allow preprocessing of the initial value. args => initialValue, opts => return processedValue
1515
+ onBeforePaste: undefined, //executes before masking the pasted value to allow preprocessing of the pasted value. args => pastedValue, opts => return processedValue
1516
+ onUnMask: undefined, //executes after unmasking to allow postprocessing of the unmaskedvalue. args => maskedValue, unmaskedValue, opts
1517
+ showMaskOnFocus: true, //show the mask-placeholder when the input has focus
1518
+ showMaskOnHover: true, //show the mask-placeholder when hovering the empty input
1519
+ onKeyValidation: $.noop, //executes on every key-press with the result of isValid. Params: result, opts
1520
+ skipOptionalPartCharacter: " ", //a character which can be used to skip an optional part of a mask
1521
+ showTooltip: false, //show the activemask as tooltip
1522
+ numericInput: false, //numericInput input direction style (input shifts to the left while holding the caret position)
1523
+ //numeric basic properties
1524
+ isNumeric: false, //enable numeric features
1525
+ radixPoint: "", //".", // | ","
1526
+ skipRadixDance: false, //disable radixpoint caret positioning
1527
+ rightAlignNumerics: true, //align numerics to the right
1528
+ //numeric basic properties
1529
+ definitions: {
1530
+ '9': {
1531
+ validator: "[0-9]",
1532
+ cardinality: 1,
1533
+ definitionSymbol: "*"
1534
+ },
1535
+ 'a': {
1536
+ validator: "[A-Za-z\u0410-\u044F\u0401\u0451]",
1537
+ cardinality: 1,
1538
+ definitionSymbol: "*"
1539
+ },
1540
+ '*': {
1541
+ validator: "[A-Za-z\u0410-\u044F\u0401\u04510-9]",
1542
+ cardinality: 1
1543
+ }
1544
+ },
1545
+ keyCode: {
1546
+ ALT: 18, BACKSPACE: 8, CAPS_LOCK: 20, COMMA: 188, COMMAND: 91, COMMAND_LEFT: 91, COMMAND_RIGHT: 93, CONTROL: 17, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, INSERT: 45, LEFT: 37, MENU: 93, NUMPAD_ADD: 107, NUMPAD_DECIMAL: 110, NUMPAD_DIVIDE: 111, NUMPAD_ENTER: 108,
1547
+ NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91
1548
+ },
1549
+ //specify keycodes which should not be considered in the keypress event, otherwise the preventDefault will stop their default behavior especially in FF
1550
+ ignorables: [8, 9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123],
1551
+ getMaskLength: undefined, //override for getMaskLength - args => buffer, greedy, repeat, currentBuffer, opts - return length
1552
+ isComplete: undefined //override for isComplete - args => buffer, opts - return true || false
1553
+ },
1554
+ escapeRegex: function (str) {
1555
+ var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
1556
+ return str.replace(new RegExp('(\\' + specials.join('|\\') + ')', 'gim'), '\\$1');
1557
+ },
1558
+ format: function (value, options) {
1559
+ var opts = $.extend(true, {}, $.inputmask.defaults, options);
1560
+ resolveAlias(opts.alias, options, opts);
1561
+ return maskScope(generateMaskSets(opts), 0, opts, { "action": "format", "value": value });
1562
+ },
1563
+ isValid: function (value, options) {
1564
+ var opts = $.extend(true, {}, $.inputmask.defaults, options);
1565
+ resolveAlias(opts.alias, options, opts);
1566
+ return maskScope(generateMaskSets(opts), 0, opts, { "action": "isValid", "value": value });
1567
+ }
1568
+ };
1569
+
1570
+ $.fn.inputmask = function (fn, options) {
1571
+ var opts = $.extend(true, {}, $.inputmask.defaults, options),
1572
+ masksets,
1573
+ activeMasksetIndex = 0;
1574
+
1575
+ if (typeof fn === "string") {
1576
+ switch (fn) {
1577
+ case "mask":
1578
+ //resolve possible aliases given by options
1579
+ resolveAlias(opts.alias, options, opts);
1580
+ masksets = generateMaskSets(opts);
1581
+ if (masksets.length == 0) { return this; }
1582
+
1583
+ return this.each(function () {
1584
+ maskScope($.extend(true, {}, masksets), 0, opts, { "action": "mask", "el": this });
1585
+ });
1586
+ case "unmaskedvalue":
1587
+ var $input = $(this), input = this;
1588
+ if ($input.data('_inputmask')) {
1589
+ masksets = $input.data('_inputmask')['masksets'];
1590
+ activeMasksetIndex = $input.data('_inputmask')['activeMasksetIndex'];
1591
+ opts = $input.data('_inputmask')['opts'];
1592
+ return maskScope(masksets, activeMasksetIndex, opts, { "action": "unmaskedvalue", "$input": $input });
1593
+ } else return $input.val();
1594
+ case "remove":
1595
+ return this.each(function () {
1596
+ var $input = $(this), input = this;
1597
+ if ($input.data('_inputmask')) {
1598
+ masksets = $input.data('_inputmask')['masksets'];
1599
+ activeMasksetIndex = $input.data('_inputmask')['activeMasksetIndex'];
1600
+ opts = $input.data('_inputmask')['opts'];
1601
+ //writeout the unmaskedvalue
1602
+ input._valueSet(maskScope(masksets, activeMasksetIndex, opts, { "action": "unmaskedvalue", "$input": $input, "skipDatepickerCheck": true }));
1603
+ //clear data
1604
+ $input.removeData('_inputmask');
1605
+ //unbind all events
1606
+ $input.unbind(".inputmask");
1607
+ $input.removeClass('focus.inputmask');
1608
+ //restore the value property
1609
+ var valueProperty;
1610
+ if (Object.getOwnPropertyDescriptor)
1611
+ valueProperty = Object.getOwnPropertyDescriptor(input, "value");
1612
+ if (valueProperty && valueProperty.get) {
1613
+ if (input._valueGet) {
1614
+ Object.defineProperty(input, "value", {
1615
+ get: input._valueGet,
1616
+ set: input._valueSet
1617
+ });
1618
+ }
1619
+ } else if (document.__lookupGetter__ && input.__lookupGetter__("value")) {
1620
+ if (input._valueGet) {
1621
+ input.__defineGetter__("value", input._valueGet);
1622
+ input.__defineSetter__("value", input._valueSet);
1623
+ }
1624
+ }
1625
+ try { //try catch needed for IE7 as it does not supports deleting fns
1626
+ delete input._valueGet;
1627
+ delete input._valueSet;
1628
+ } catch (e) {
1629
+ input._valueGet = undefined;
1630
+ input._valueSet = undefined;
1631
+
1632
+ }
1633
+ }
1634
+ });
1635
+ break;
1636
+ case "getemptymask": //return the default (empty) mask value, usefull for setting the default value in validation
1637
+ if (this.data('_inputmask')) {
1638
+ masksets = this.data('_inputmask')['masksets'];
1639
+ activeMasksetIndex = this.data('_inputmask')['activeMasksetIndex'];
1640
+ return masksets[activeMasksetIndex]['_buffer'].join('');
1641
+ }
1642
+ else return "";
1643
+ case "hasMaskedValue": //check wheter the returned value is masked or not; currently only works reliable when using jquery.val fn to retrieve the value
1644
+ return this.data('_inputmask') ? !this.data('_inputmask')['opts'].autoUnmask : false;
1645
+ case "isComplete":
1646
+ masksets = this.data('_inputmask')['masksets'];
1647
+ activeMasksetIndex = this.data('_inputmask')['activeMasksetIndex'];
1648
+ opts = this.data('_inputmask')['opts'];
1649
+ return maskScope(masksets, activeMasksetIndex, opts, { "action": "isComplete", "buffer": this[0]._valueGet().split('') });
1650
+ case "getmetadata": //return mask metadata if exists
1651
+ if (this.data('_inputmask')) {
1652
+ masksets = this.data('_inputmask')['masksets'];
1653
+ activeMasksetIndex = this.data('_inputmask')['activeMasksetIndex'];
1654
+ return masksets[activeMasksetIndex]['metadata'];
1655
+ }
1656
+ else return undefined;
1657
+ default:
1658
+ //check if the fn is an alias
1659
+ if (!resolveAlias(fn, options, opts)) {
1660
+ //maybe fn is a mask so we try
1661
+ //set mask
1662
+ opts.mask = fn;
1663
+ }
1664
+ masksets = generateMaskSets(opts);
1665
+ if (masksets.length == 0) { return this; }
1666
+ return this.each(function () {
1667
+ maskScope($.extend(true, {}, masksets), activeMasksetIndex, opts, { "action": "mask", "el": this });
1668
+ });
1669
+
1670
+ break;
1671
+ }
1672
+ } else if (typeof fn == "object") {
1673
+ opts = $.extend(true, {}, $.inputmask.defaults, fn);
1674
+
1675
+ resolveAlias(opts.alias, fn, opts); //resolve aliases
1676
+ masksets = generateMaskSets(opts);
1677
+ if (masksets.length == 0) { return this; }
1678
+ return this.each(function () {
1679
+ maskScope($.extend(true, {}, masksets), activeMasksetIndex, opts, { "action": "mask", "el": this });
1680
+ });
1681
+ } else if (fn == undefined) {
1682
+ //look for data-inputmask atribute - the attribute should only contain optipns
1683
+ return this.each(function () {
1684
+ var attrOptions = $(this).attr("data-inputmask");
1685
+ if (attrOptions && attrOptions != "") {
1686
+ try {
1687
+ attrOptions = attrOptions.replace(new RegExp("'", "g"), '"');
1688
+ var dataoptions = $.parseJSON("{" + attrOptions + "}");
1689
+ $.extend(true, dataoptions, options);
1690
+ opts = $.extend(true, {}, $.inputmask.defaults, dataoptions);
1691
+ resolveAlias(opts.alias, dataoptions, opts);
1692
+ opts.alias = undefined;
1693
+ $(this).inputmask(opts);
1694
+ } catch (ex) { } //need a more relax parseJSON
1695
+ }
1696
+ });
1697
+ }
1698
+ };
1699
+ }
1700
+ })(jQuery);
1701
+ /*
1702
+ Input Mask plugin extensions
1703
+ http://github.com/RobinHerbots/jquery.inputmask
1704
+ Copyright (c) 2010 - 2014 Robin Herbots
1705
+ Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
1706
+ Version: 2.5.5
1707
+
1708
+ Optional extensions on the jquery.inputmask base
1709
+ */
1710
+ (function ($) {
1711
+ //extra definitions
1712
+ $.extend($.inputmask.defaults.definitions, {
1713
+ 'A': {
1714
+ validator: "[A-Za-z]",
1715
+ cardinality: 1,
1716
+ casing: "upper" //auto uppercasing
1717
+ },
1718
+ '#': {
1719
+ validator: "[A-Za-z\u0410-\u044F\u0401\u04510-9]",
1720
+ cardinality: 1,
1721
+ casing: "upper"
1722
+ }
1723
+ });
1724
+ $.extend($.inputmask.defaults.aliases, {
1725
+ 'url': {
1726
+ mask: "ir",
1727
+ placeholder: "",
1728
+ separator: "",
1729
+ defaultPrefix: "http://",
1730
+ regex: {
1731
+ urlpre1: new RegExp("[fh]"),
1732
+ urlpre2: new RegExp("(ft|ht)"),
1733
+ urlpre3: new RegExp("(ftp|htt)"),
1734
+ urlpre4: new RegExp("(ftp:|http|ftps)"),
1735
+ urlpre5: new RegExp("(ftp:/|ftps:|http:|https)"),
1736
+ urlpre6: new RegExp("(ftp://|ftps:/|http:/|https:)"),
1737
+ urlpre7: new RegExp("(ftp://|ftps://|http://|https:/)"),
1738
+ urlpre8: new RegExp("(ftp://|ftps://|http://|https://)")
1739
+ },
1740
+ definitions: {
1741
+ 'i': {
1742
+ validator: function (chrs, buffer, pos, strict, opts) {
1743
+ return true;
1744
+ },
1745
+ cardinality: 8,
1746
+ prevalidator: (function () {
1747
+ var result = [], prefixLimit = 8;
1748
+ for (var i = 0; i < prefixLimit; i++) {
1749
+ result[i] = (function () {
1750
+ var j = i;
1751
+ return {
1752
+ validator: function (chrs, buffer, pos, strict, opts) {
1753
+ if (opts.regex["urlpre" + (j + 1)]) {
1754
+ var tmp = chrs, k;
1755
+ if (((j + 1) - chrs.length) > 0) {
1756
+ tmp = buffer.join('').substring(0, ((j + 1) - chrs.length)) + "" + tmp;
1757
+ }
1758
+ var isValid = opts.regex["urlpre" + (j + 1)].test(tmp);
1759
+ if (!strict && !isValid) {
1760
+ pos = pos - j;
1761
+ for (k = 0; k < opts.defaultPrefix.length; k++) {
1762
+ buffer[pos] = opts.defaultPrefix[k]; pos++;
1763
+ }
1764
+ for (k = 0; k < tmp.length - 1; k++) {
1765
+ buffer[pos] = tmp[k]; pos++;
1766
+ }
1767
+ return { "pos": pos };
1768
+ }
1769
+ return isValid;
1770
+ } else {
1771
+ return false;
1772
+ }
1773
+ }, cardinality: j
1774
+ };
1775
+ })();
1776
+ }
1777
+ return result;
1778
+ })()
1779
+ },
1780
+ "r": {
1781
+ validator: ".",
1782
+ cardinality: 50
1783
+ }
1784
+ },
1785
+ insertMode: false,
1786
+ autoUnmask: false
1787
+ },
1788
+ "ip": { //ip-address mask
1789
+ mask: ["[[x]y]z.[[x]y]z.[[x]y]z.x[yz]", "[[x]y]z.[[x]y]z.[[x]y]z.[[x]y][z]"],
1790
+ definitions: {
1791
+ 'x': {
1792
+ validator: "[012]",
1793
+ cardinality: 1,
1794
+ definitionSymbol: "i"
1795
+ },
1796
+ 'y': {
1797
+ validator: function (chrs, buffer, pos, strict, opts) {
1798
+ if (pos - 1 > -1 && buffer[pos - 1] != ".")
1799
+ chrs = buffer[pos - 1] + chrs;
1800
+ else chrs = "0" + chrs;
1801
+ return new RegExp("2[0-5]|[01][0-9]").test(chrs);
1802
+ },
1803
+ cardinality: 1,
1804
+ definitionSymbol: "i"
1805
+ },
1806
+ 'z': {
1807
+ validator: function (chrs, buffer, pos, strict, opts) {
1808
+ if (pos - 1 > -1 && buffer[pos - 1] != ".") {
1809
+ chrs = buffer[pos - 1] + chrs;
1810
+ if (pos - 2 > -1 && buffer[pos - 2] != ".") {
1811
+ chrs = buffer[pos - 2] + chrs;
1812
+ } else chrs = "0" + chrs;
1813
+ } else chrs = "00" + chrs;
1814
+ return new RegExp("25[0-5]|2[0-4][0-9]|[01][0-9][0-9]").test(chrs);
1815
+ },
1816
+ cardinality: 1,
1817
+ definitionSymbol: "i"
1818
+ }
1819
+ }
1820
+ }
1821
+ });
1822
+ })(jQuery);
1823
+ /*
1824
+ Input Mask plugin extensions
1825
+ http://github.com/RobinHerbots/jquery.inputmask
1826
+ Copyright (c) 2010 - 2014 Robin Herbots
1827
+ Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
1828
+ Version: 2.5.5
1829
+
1830
+ Optional extensions on the jquery.inputmask base
1831
+ */
1832
+ (function ($) {
1833
+ //date & time aliases
1834
+ $.extend($.inputmask.defaults.definitions, {
1835
+ 'h': { //hours
1836
+ validator: "[01][0-9]|2[0-3]",
1837
+ cardinality: 2,
1838
+ prevalidator: [{ validator: "[0-2]", cardinality: 1 }]
1839
+ },
1840
+ 's': { //seconds || minutes
1841
+ validator: "[0-5][0-9]",
1842
+ cardinality: 2,
1843
+ prevalidator: [{ validator: "[0-5]", cardinality: 1 }]
1844
+ },
1845
+ 'd': { //basic day
1846
+ validator: "0[1-9]|[12][0-9]|3[01]",
1847
+ cardinality: 2,
1848
+ prevalidator: [{ validator: "[0-3]", cardinality: 1 }]
1849
+ },
1850
+ 'm': { //basic month
1851
+ validator: "0[1-9]|1[012]",
1852
+ cardinality: 2,
1853
+ prevalidator: [{ validator: "[01]", cardinality: 1 }]
1854
+ },
1855
+ 'y': { //basic year
1856
+ validator: "(19|20)\\d{2}",
1857
+ cardinality: 4,
1858
+ prevalidator: [
1859
+ { validator: "[12]", cardinality: 1 },
1860
+ { validator: "(19|20)", cardinality: 2 },
1861
+ { validator: "(19|20)\\d", cardinality: 3 }
1862
+ ]
1863
+ }
1864
+ });
1865
+ $.extend($.inputmask.defaults.aliases, {
1866
+ 'dd/mm/yyyy': {
1867
+ mask: "1/2/y",
1868
+ placeholder: "dd/mm/yyyy",
1869
+ regex: {
1870
+ val1pre: new RegExp("[0-3]"), //daypre
1871
+ val1: new RegExp("0[1-9]|[12][0-9]|3[01]"), //day
1872
+ val2pre: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[1-9]|[12][0-9]|3[01])" + escapedSeparator + "[01])"); }, //monthpre
1873
+ val2: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[1-9]|[12][0-9])" + escapedSeparator + "(0[1-9]|1[012]))|(30" + escapedSeparator + "(0[13-9]|1[012]))|(31" + escapedSeparator + "(0[13578]|1[02]))"); }//month
1874
+ },
1875
+ leapday: "29/02/",
1876
+ separator: '/',
1877
+ yearrange: { minyear: 1900, maxyear: 2099 },
1878
+ isInYearRange: function (chrs, minyear, maxyear) {
1879
+ var enteredyear = parseInt(chrs.concat(minyear.toString().slice(chrs.length)));
1880
+ var enteredyear2 = parseInt(chrs.concat(maxyear.toString().slice(chrs.length)));
1881
+ return (enteredyear != NaN ? minyear <= enteredyear && enteredyear <= maxyear : false) ||
1882
+ (enteredyear2 != NaN ? minyear <= enteredyear2 && enteredyear2 <= maxyear : false);
1883
+ },
1884
+ determinebaseyear: function (minyear, maxyear, hint) {
1885
+ var currentyear = (new Date()).getFullYear();
1886
+ if (minyear > currentyear) return minyear;
1887
+ if (maxyear < currentyear) {
1888
+ var maxYearPrefix = maxyear.toString().slice(0, 2);
1889
+ var maxYearPostfix = maxyear.toString().slice(2, 4);
1890
+ while (maxyear < maxYearPrefix + hint) {
1891
+ maxYearPrefix--;
1892
+ }
1893
+ var maxxYear = maxYearPrefix + maxYearPostfix;
1894
+ return minyear > maxxYear ? minyear : maxxYear;
1895
+ }
1896
+
1897
+ return currentyear;
1898
+ },
1899
+ onKeyUp: function (e, buffer, opts) {
1900
+ var $input = $(this);
1901
+ if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {
1902
+ var today = new Date();
1903
+ $input.val(today.getDate().toString() + (today.getMonth() + 1).toString() + today.getFullYear().toString());
1904
+ }
1905
+ },
1906
+ definitions: {
1907
+ '1': { //val1 ~ day or month
1908
+ validator: function (chrs, buffer, pos, strict, opts) {
1909
+ var isValid = opts.regex.val1.test(chrs);
1910
+ if (!strict && !isValid) {
1911
+ if (chrs.charAt(1) == opts.separator || "-./".indexOf(chrs.charAt(1)) != -1) {
1912
+ isValid = opts.regex.val1.test("0" + chrs.charAt(0));
1913
+ if (isValid) {
1914
+ buffer[pos - 1] = "0";
1915
+ return { "pos": pos, "c": chrs.charAt(0) };
1916
+ }
1917
+ }
1918
+ }
1919
+ return isValid;
1920
+ },
1921
+ cardinality: 2,
1922
+ prevalidator: [{
1923
+ validator: function (chrs, buffer, pos, strict, opts) {
1924
+ var isValid = opts.regex.val1pre.test(chrs);
1925
+ if (!strict && !isValid) {
1926
+ isValid = opts.regex.val1.test("0" + chrs);
1927
+ if (isValid) {
1928
+ buffer[pos] = "0";
1929
+ pos++;
1930
+ return { "pos": pos };
1931
+ }
1932
+ }
1933
+ return isValid;
1934
+ }, cardinality: 1
1935
+ }]
1936
+ },
1937
+ '2': { //val2 ~ day or month
1938
+ validator: function (chrs, buffer, pos, strict, opts) {
1939
+ var frontValue = buffer.join('').substr(0, 3);
1940
+ if (frontValue.indexOf(opts.placeholder[0]) != -1) frontValue = "01" + opts.separator;
1941
+ var isValid = opts.regex.val2(opts.separator).test(frontValue + chrs);
1942
+ if (!strict && !isValid) {
1943
+ if (chrs.charAt(1) == opts.separator || "-./".indexOf(chrs.charAt(1)) != -1) {
1944
+ isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs.charAt(0));
1945
+ if (isValid) {
1946
+ buffer[pos - 1] = "0";
1947
+ return { "pos": pos, "c": chrs.charAt(0) };
1948
+ }
1949
+ }
1950
+ }
1951
+ return isValid;
1952
+ },
1953
+ cardinality: 2,
1954
+ prevalidator: [{
1955
+ validator: function (chrs, buffer, pos, strict, opts) {
1956
+ var frontValue = buffer.join('').substr(0, 3);
1957
+ if (frontValue.indexOf(opts.placeholder[0]) != -1) frontValue = "01" + opts.separator;
1958
+ var isValid = opts.regex.val2pre(opts.separator).test(frontValue + chrs);
1959
+ if (!strict && !isValid) {
1960
+ isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs);
1961
+ if (isValid) {
1962
+ buffer[pos] = "0";
1963
+ pos++;
1964
+ return { "pos": pos };
1965
+ }
1966
+ }
1967
+ return isValid;
1968
+ }, cardinality: 1
1969
+ }]
1970
+ },
1971
+ 'y': { //year
1972
+ validator: function (chrs, buffer, pos, strict, opts) {
1973
+ if (opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) {
1974
+ var dayMonthValue = buffer.join('').substr(0, 6);
1975
+ if (dayMonthValue != opts.leapday)
1976
+ return true;
1977
+ else {
1978
+ var year = parseInt(chrs, 10);//detect leap year
1979
+ if (year % 4 === 0)
1980
+ if (year % 100 === 0)
1981
+ if (year % 400 === 0)
1982
+ return true;
1983
+ else return false;
1984
+ else return true;
1985
+ else return false;
1986
+ }
1987
+ } else return false;
1988
+ },
1989
+ cardinality: 4,
1990
+ prevalidator: [
1991
+ {
1992
+ validator: function (chrs, buffer, pos, strict, opts) {
1993
+ var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
1994
+ if (!strict && !isValid) {
1995
+ var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + "0").toString().slice(0, 1);
1996
+
1997
+ isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
1998
+ if (isValid) {
1999
+ buffer[pos++] = yearPrefix[0];
2000
+ return { "pos": pos };
2001
+ }
2002
+ yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + "0").toString().slice(0, 2);
2003
+
2004
+ isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
2005
+ if (isValid) {
2006
+ buffer[pos++] = yearPrefix[0];
2007
+ buffer[pos++] = yearPrefix[1];
2008
+ return { "pos": pos };
2009
+ }
2010
+ }
2011
+ return isValid;
2012
+ },
2013
+ cardinality: 1
2014
+ },
2015
+ {
2016
+ validator: function (chrs, buffer, pos, strict, opts) {
2017
+ var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
2018
+ if (!strict && !isValid) {
2019
+ var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2);
2020
+
2021
+ isValid = opts.isInYearRange(chrs[0] + yearPrefix[1] + chrs[1], opts.yearrange.minyear, opts.yearrange.maxyear);
2022
+ if (isValid) {
2023
+ buffer[pos++] = yearPrefix[1];
2024
+ return { "pos": pos };
2025
+ }
2026
+
2027
+ yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2);
2028
+ if (opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) {
2029
+ var dayMonthValue = buffer.join('').substr(0, 6);
2030
+ if (dayMonthValue != opts.leapday)
2031
+ isValid = true;
2032
+ else {
2033
+ var year = parseInt(chrs, 10);//detect leap year
2034
+ if (year % 4 === 0)
2035
+ if (year % 100 === 0)
2036
+ if (year % 400 === 0)
2037
+ isValid = true;
2038
+ else isValid = false;
2039
+ else isValid = true;
2040
+ else isValid = false;
2041
+ }
2042
+ } else isValid = false;
2043
+ if (isValid) {
2044
+ buffer[pos - 1] = yearPrefix[0];
2045
+ buffer[pos++] = yearPrefix[1];
2046
+ buffer[pos++] = chrs[0];
2047
+ return { "pos": pos };
2048
+ }
2049
+ }
2050
+ return isValid;
2051
+ }, cardinality: 2
2052
+ },
2053
+ {
2054
+ validator: function (chrs, buffer, pos, strict, opts) {
2055
+ return opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
2056
+ }, cardinality: 3
2057
+ }
2058
+ ]
2059
+ }
2060
+ },
2061
+ insertMode: false,
2062
+ autoUnmask: false
2063
+ },
2064
+ 'mm/dd/yyyy': {
2065
+ placeholder: "mm/dd/yyyy",
2066
+ alias: "dd/mm/yyyy", //reuse functionality of dd/mm/yyyy alias
2067
+ regex: {
2068
+ val2pre: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[13-9]|1[012])" + escapedSeparator + "[0-3])|(02" + escapedSeparator + "[0-2])"); }, //daypre
2069
+ val2: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "(0[1-9]|[12][0-9]))|((0[13-9]|1[012])" + escapedSeparator + "30)|((0[13578]|1[02])" + escapedSeparator + "31)"); }, //day
2070
+ val1pre: new RegExp("[01]"), //monthpre
2071
+ val1: new RegExp("0[1-9]|1[012]") //month
2072
+ },
2073
+ leapday: "02/29/",
2074
+ onKeyUp: function (e, buffer, opts) {
2075
+ var $input = $(this);
2076
+ if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {
2077
+ var today = new Date();
2078
+ $input.val((today.getMonth() + 1).toString() + today.getDate().toString() + today.getFullYear().toString());
2079
+ }
2080
+ }
2081
+ },
2082
+ 'yyyy/mm/dd': {
2083
+ mask: "y/1/2",
2084
+ placeholder: "yyyy/mm/dd",
2085
+ alias: "mm/dd/yyyy",
2086
+ leapday: "/02/29",
2087
+ onKeyUp: function (e, buffer, opts) {
2088
+ var $input = $(this);
2089
+ if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {
2090
+ var today = new Date();
2091
+ $input.val(today.getFullYear().toString() + (today.getMonth() + 1).toString() + today.getDate().toString());
2092
+ }
2093
+ },
2094
+ definitions: {
2095
+ '2': { //val2 ~ day or month
2096
+ validator: function (chrs, buffer, pos, strict, opts) {
2097
+ var frontValue = buffer.join('').substr(5, 3);
2098
+ if (frontValue.indexOf(opts.placeholder[5]) != -1) frontValue = "01" + opts.separator;
2099
+ var isValid = opts.regex.val2(opts.separator).test(frontValue + chrs);
2100
+ if (!strict && !isValid) {
2101
+ if (chrs.charAt(1) == opts.separator || "-./".indexOf(chrs.charAt(1)) != -1) {
2102
+ isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs.charAt(0));
2103
+ if (isValid) {
2104
+ buffer[pos - 1] = "0";
2105
+ return { "pos": pos, "c": chrs.charAt(0) };
2106
+ }
2107
+ }
2108
+ }
2109
+
2110
+ //check leap yeap
2111
+ if (isValid) {
2112
+ var dayMonthValue = buffer.join('').substr(4, 4) + chrs;
2113
+ if (dayMonthValue != opts.leapday)
2114
+ return true;
2115
+ else {
2116
+ var year = parseInt(buffer.join('').substr(0, 4), 10); //detect leap year
2117
+ if (year % 4 === 0)
2118
+ if (year % 100 === 0)
2119
+ if (year % 400 === 0)
2120
+ return true;
2121
+ else return false;
2122
+ else return true;
2123
+ else return false;
2124
+ }
2125
+ }
2126
+
2127
+ return isValid;
2128
+ },
2129
+ cardinality: 2,
2130
+ prevalidator: [{
2131
+ validator: function (chrs, buffer, pos, strict, opts) {
2132
+ var frontValue = buffer.join('').substr(5, 3);
2133
+ if (frontValue.indexOf(opts.placeholder[5]) != -1) frontValue = "01" + opts.separator;
2134
+ var isValid = opts.regex.val2pre(opts.separator).test(frontValue + chrs);
2135
+ if (!strict && !isValid) {
2136
+ isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs);
2137
+ if (isValid) {
2138
+ buffer[pos] = "0";
2139
+ pos++;
2140
+ return { "pos": pos };
2141
+ }
2142
+ }
2143
+ return isValid;
2144
+ }, cardinality: 1
2145
+ }]
2146
+ }
2147
+ }
2148
+ },
2149
+ 'dd.mm.yyyy': {
2150
+ mask: "1.2.y",
2151
+ placeholder: "dd.mm.yyyy",
2152
+ leapday: "29.02.",
2153
+ separator: '.',
2154
+ alias: "dd/mm/yyyy"
2155
+ },
2156
+ 'dd-mm-yyyy': {
2157
+ mask: "1-2-y",
2158
+ placeholder: "dd-mm-yyyy",
2159
+ leapday: "29-02-",
2160
+ separator: '-',
2161
+ alias: "dd/mm/yyyy"
2162
+ },
2163
+ 'mm.dd.yyyy': {
2164
+ mask: "1.2.y",
2165
+ placeholder: "mm.dd.yyyy",
2166
+ leapday: "02.29.",
2167
+ separator: '.',
2168
+ alias: "mm/dd/yyyy"
2169
+ },
2170
+ 'mm-dd-yyyy': {
2171
+ mask: "1-2-y",
2172
+ placeholder: "mm-dd-yyyy",
2173
+ leapday: "02-29-",
2174
+ separator: '-',
2175
+ alias: "mm/dd/yyyy"
2176
+ },
2177
+ 'yyyy.mm.dd': {
2178
+ mask: "y.1.2",
2179
+ placeholder: "yyyy.mm.dd",
2180
+ leapday: ".02.29",
2181
+ separator: '.',
2182
+ alias: "yyyy/mm/dd"
2183
+ },
2184
+ 'yyyy-mm-dd': {
2185
+ mask: "y-1-2",
2186
+ placeholder: "yyyy-mm-dd",
2187
+ leapday: "-02-29",
2188
+ separator: '-',
2189
+ alias: "yyyy/mm/dd"
2190
+ },
2191
+ 'datetime': {
2192
+ mask: "1/2/y h:s",
2193
+ placeholder: "dd/mm/yyyy hh:mm",
2194
+ alias: "dd/mm/yyyy",
2195
+ regex: {
2196
+ hrspre: new RegExp("[012]"), //hours pre
2197
+ hrs24: new RegExp("2[0-9]|1[3-9]"),
2198
+ hrs: new RegExp("[01][0-9]|2[0-3]"), //hours
2199
+ ampm: new RegExp("^[a|p|A|P][m|M]")
2200
+ },
2201
+ timeseparator: ':',
2202
+ hourFormat: "24", // or 12
2203
+ definitions: {
2204
+ 'h': { //hours
2205
+ validator: function (chrs, buffer, pos, strict, opts) {
2206
+ var isValid = opts.regex.hrs.test(chrs);
2207
+ if (!strict && !isValid) {
2208
+ if (chrs.charAt(1) == opts.timeseparator || "-.:".indexOf(chrs.charAt(1)) != -1) {
2209
+ isValid = opts.regex.hrs.test("0" + chrs.charAt(0));
2210
+ if (isValid) {
2211
+ buffer[pos - 1] = "0";
2212
+ buffer[pos] = chrs.charAt(0);
2213
+ pos++;
2214
+ return { "pos": pos };
2215
+ }
2216
+ }
2217
+ }
2218
+
2219
+ if (isValid && opts.hourFormat !== "24" && opts.regex.hrs24.test(chrs)) {
2220
+
2221
+ var tmp = parseInt(chrs, 10);
2222
+
2223
+ if (tmp == 24) {
2224
+ buffer[pos + 5] = "a";
2225
+ buffer[pos + 6] = "m";
2226
+ } else {
2227
+ buffer[pos + 5] = "p";
2228
+ buffer[pos + 6] = "m";
2229
+ }
2230
+
2231
+ tmp = tmp - 12;
2232
+
2233
+ if (tmp < 10) {
2234
+ buffer[pos] = tmp.toString();
2235
+ buffer[pos - 1] = "0";
2236
+ } else {
2237
+ buffer[pos] = tmp.toString().charAt(1);
2238
+ buffer[pos - 1] = tmp.toString().charAt(0);
2239
+ }
2240
+
2241
+ return { "pos": pos, "c": buffer[pos] };
2242
+ }
2243
+
2244
+ return isValid;
2245
+ },
2246
+ cardinality: 2,
2247
+ prevalidator: [{
2248
+ validator: function (chrs, buffer, pos, strict, opts) {
2249
+ var isValid = opts.regex.hrspre.test(chrs);
2250
+ if (!strict && !isValid) {
2251
+ isValid = opts.regex.hrs.test("0" + chrs);
2252
+ if (isValid) {
2253
+ buffer[pos] = "0";
2254
+ pos++;
2255
+ return { "pos": pos };
2256
+ }
2257
+ }
2258
+ return isValid;
2259
+ }, cardinality: 1
2260
+ }]
2261
+ },
2262
+ 't': { //am/pm
2263
+ validator: function (chrs, buffer, pos, strict, opts) {
2264
+ return opts.regex.ampm.test(chrs + "m");
2265
+ },
2266
+ casing: "lower",
2267
+ cardinality: 1
2268
+ }
2269
+ },
2270
+ insertMode: false,
2271
+ autoUnmask: false
2272
+ },
2273
+ 'datetime12': {
2274
+ mask: "1/2/y h:s t\\m",
2275
+ placeholder: "dd/mm/yyyy hh:mm xm",
2276
+ alias: "datetime",
2277
+ hourFormat: "12"
2278
+ },
2279
+ 'hh:mm t': {
2280
+ mask: "h:s t\\m",
2281
+ placeholder: "hh:mm xm",
2282
+ alias: "datetime",
2283
+ hourFormat: "12"
2284
+ },
2285
+ 'h:s t': {
2286
+ mask: "h:s t\\m",
2287
+ placeholder: "hh:mm xm",
2288
+ alias: "datetime",
2289
+ hourFormat: "12"
2290
+ },
2291
+ 'hh:mm:ss': {
2292
+ mask: "h:s:s",
2293
+ autoUnmask: false
2294
+ },
2295
+ 'hh:mm': {
2296
+ mask: "h:s",
2297
+ autoUnmask: false
2298
+ },
2299
+ 'date': {
2300
+ alias: "dd/mm/yyyy" // "mm/dd/yyyy"
2301
+ },
2302
+ 'mm/yyyy': {
2303
+ mask: "1/y",
2304
+ placeholder: "mm/yyyy",
2305
+ leapday: "donotuse",
2306
+ separator: '/',
2307
+ alias: "mm/dd/yyyy"
2308
+ }
2309
+ });
2310
+ })(jQuery);
2311
+ /*
2312
+ Input Mask plugin extensions
2313
+ http://github.com/RobinHerbots/jquery.inputmask
2314
+ Copyright (c) 2010 - 2014 Robin Herbots
2315
+ Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
2316
+ Version: 2.5.5
2317
+
2318
+ Optional extensions on the jquery.inputmask base
2319
+ */
2320
+ (function ($) {
2321
+ //number aliases
2322
+ $.extend($.inputmask.defaults.aliases, {
2323
+ 'decimal': {
2324
+ mask: "~",
2325
+ placeholder: "",
2326
+ repeat: "*",
2327
+ greedy: false,
2328
+ numericInput: false,
2329
+ isNumeric: true,
2330
+ digits: "*", //number of fractionalDigits
2331
+ groupSeparator: "",//",", // | "."
2332
+ radixPoint: ".",
2333
+ groupSize: 3,
2334
+ autoGroup: false,
2335
+ allowPlus: true,
2336
+ allowMinus: true,
2337
+ //todo
2338
+ integerDigits: "*", //number of integerDigits
2339
+ defaultValue: "",
2340
+ prefix: "",
2341
+ suffix: "",
2342
+
2343
+ //todo
2344
+ getMaskLength: function (buffer, greedy, repeat, currentBuffer, opts) { //custom getMaskLength to take the groupSeparator into account
2345
+ var calculatedLength = buffer.length;
2346
+
2347
+ if (!greedy) {
2348
+ if (repeat == "*") {
2349
+ calculatedLength = currentBuffer.length + 1;
2350
+ } else if (repeat > 1) {
2351
+ calculatedLength += (buffer.length * (repeat - 1));
2352
+ }
2353
+ }
2354
+
2355
+ var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);
2356
+ var escapedRadixPoint = $.inputmask.escapeRegex.call(this, opts.radixPoint);
2357
+ var currentBufferStr = currentBuffer.join(''), strippedBufferStr = currentBufferStr.replace(new RegExp(escapedGroupSeparator, "g"), "").replace(new RegExp(escapedRadixPoint), ""),
2358
+ groupOffset = currentBufferStr.length - strippedBufferStr.length;
2359
+ return calculatedLength + groupOffset;
2360
+ },
2361
+ postFormat: function (buffer, pos, reformatOnly, opts) {
2362
+ if (opts.groupSeparator == "") return pos;
2363
+ var cbuf = buffer.slice(),
2364
+ radixPos = $.inArray(opts.radixPoint, buffer);
2365
+ if (!reformatOnly) {
2366
+ cbuf.splice(pos, 0, "?"); //set position indicator
2367
+ }
2368
+ var bufVal = cbuf.join('');
2369
+ if (opts.autoGroup || (reformatOnly && bufVal.indexOf(opts.groupSeparator) != -1)) {
2370
+ var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);
2371
+ bufVal = bufVal.replace(new RegExp(escapedGroupSeparator, "g"), '');
2372
+ var radixSplit = bufVal.split(opts.radixPoint);
2373
+ bufVal = radixSplit[0];
2374
+ var reg = new RegExp('([-\+]?[\\d\?]+)([\\d\?]{' + opts.groupSize + '})');
2375
+ while (reg.test(bufVal)) {
2376
+ bufVal = bufVal.replace(reg, '$1' + opts.groupSeparator + '$2');
2377
+ bufVal = bufVal.replace(opts.groupSeparator + opts.groupSeparator, opts.groupSeparator);
2378
+ }
2379
+ if (radixSplit.length > 1)
2380
+ bufVal += opts.radixPoint + radixSplit[1];
2381
+ }
2382
+ buffer.length = bufVal.length; //align the length
2383
+ for (var i = 0, l = bufVal.length; i < l; i++) {
2384
+ buffer[i] = bufVal.charAt(i);
2385
+ }
2386
+ var newPos = $.inArray("?", buffer);
2387
+ if (!reformatOnly) buffer.splice(newPos, 1);
2388
+
2389
+ return reformatOnly ? pos : newPos;
2390
+ },
2391
+ regex: {
2392
+ number: function (opts) {
2393
+ var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);
2394
+ var escapedRadixPoint = $.inputmask.escapeRegex.call(this, opts.radixPoint);
2395
+ var digitExpression = isNaN(opts.digits) ? opts.digits : '{0,' + opts.digits + '}';
2396
+ var signedExpression = opts.allowPlus || opts.allowMinus ? "[" + (opts.allowPlus ? "\+" : "") + (opts.allowMinus ? "-" : "") + "]?" : "";
2397
+ return new RegExp("^" + signedExpression + "(\\d+|\\d{1," + opts.groupSize + "}((" + escapedGroupSeparator + "\\d{" + opts.groupSize + "})?)+)(" + escapedRadixPoint + "\\d" + digitExpression + ")?$");
2398
+ }
2399
+ },
2400
+ onKeyDown: function (e, buffer, opts) {
2401
+ var $input = $(this), input = this;
2402
+ if (e.keyCode == opts.keyCode.TAB) {
2403
+ var radixPosition = $.inArray(opts.radixPoint, buffer);
2404
+ if (radixPosition != -1) {
2405
+ var masksets = $input.data('_inputmask')['masksets'];
2406
+ var activeMasksetIndex = $input.data('_inputmask')['activeMasksetIndex'];
2407
+ for (var i = 1; i <= opts.digits && i < opts.getMaskLength(masksets[activeMasksetIndex]["_buffer"], masksets[activeMasksetIndex]["greedy"], masksets[activeMasksetIndex]["repeat"], buffer, opts) ; i++) {
2408
+ if (buffer[radixPosition + i] == undefined || buffer[radixPosition + i] == "") buffer[radixPosition + i] = "0";
2409
+ }
2410
+ input._valueSet(buffer.join(''));
2411
+ }
2412
+ } else if (e.keyCode == opts.keyCode.DELETE || e.keyCode == opts.keyCode.BACKSPACE) {
2413
+ opts.postFormat(buffer, 0, true, opts);
2414
+ input._valueSet(buffer.join(''));
2415
+ return true;
2416
+ }
2417
+ },
2418
+ definitions: {
2419
+ '~': { //real number
2420
+ validator: function (chrs, buffer, pos, strict, opts) {
2421
+ var iopts = $.extend({}, opts, { digits: strict ? "*" : opts.digits });
2422
+ if (chrs == "") return false;
2423
+ if (!strict && pos <= 1 && buffer[0] === '0' && new RegExp("[\\d-]").test(chrs) && buffer.join('').length == 1) { //handle first char
2424
+ buffer[0] = "";
2425
+ return { "pos": 0 };
2426
+ }
2427
+
2428
+ var cbuf = strict ? buffer.slice(0, pos) : buffer.slice();
2429
+
2430
+ cbuf.splice(pos, 0, chrs);
2431
+ var bufferStr = cbuf.join('');
2432
+
2433
+ //strip groupseparator
2434
+ var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);
2435
+ bufferStr = bufferStr.replace(new RegExp(escapedGroupSeparator, "g"), '');
2436
+ if (strict && bufferStr.lastIndexOf(opts.radixPoint) == bufferStr.length - 1) {
2437
+ var escapedRadixPoint = $.inputmask.escapeRegex.call(this, opts.radixPoint);
2438
+ bufferStr = bufferStr.replace(new RegExp(escapedRadixPoint, "g"), '');
2439
+ }
2440
+ if (!strict && bufferStr == "") return false;
2441
+
2442
+ var isValid = opts.regex.number(iopts).test(bufferStr);
2443
+ if (!isValid) {
2444
+ //let's help the regex a bit
2445
+ bufferStr += "0";
2446
+ isValid = opts.regex.number(iopts).test(bufferStr);
2447
+ if (!isValid) {
2448
+ //make a valid group
2449
+ var lastGroupSeparator = bufferStr.lastIndexOf(opts.groupSeparator);
2450
+ for (var i = bufferStr.length - lastGroupSeparator; i <= 3; i++) {
2451
+ bufferStr += "0";
2452
+ }
2453
+
2454
+ isValid = opts.regex.number(iopts).test(bufferStr);
2455
+ if (!isValid && !strict) {
2456
+ if (chrs == opts.radixPoint) {
2457
+ isValid = opts.regex.number(iopts).test("0" + bufferStr + "0");
2458
+ if (isValid) {
2459
+ buffer[pos] = "0";
2460
+ pos++;
2461
+ return { "pos": pos };
2462
+ }
2463
+ }
2464
+ }
2465
+ }
2466
+ }
2467
+
2468
+ if (isValid != false && !strict && chrs != opts.radixPoint) {
2469
+ var newPos = opts.postFormat(buffer, pos, (chrs == "-" || chrs == "+") ? true : false, opts);
2470
+ return { "pos": newPos };
2471
+ }
2472
+
2473
+ return isValid;
2474
+ },
2475
+ cardinality: 1,
2476
+ prevalidator: null
2477
+ }
2478
+ },
2479
+ insertMode: true,
2480
+ autoUnmask: false
2481
+ },
2482
+ 'integer': {
2483
+ regex: {
2484
+ number: function (opts) {
2485
+ var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);
2486
+ var signedExpression = opts.allowPlus || opts.allowMinus ? "[" + (opts.allowPlus ? "\+" : "") + (opts.allowMinus ? "-" : "") + "]?" : "";
2487
+ return new RegExp("^" + signedExpression + "(\\d+|\\d{1," + opts.groupSize + "}((" + escapedGroupSeparator + "\\d{" + opts.groupSize + "})?)+)$");
2488
+ }
2489
+ },
2490
+ alias: "decimal"
2491
+ }
2492
+ });
2493
+ })(jQuery);
2494
+ /*
2495
+ Input Mask plugin extensions
2496
+ http://github.com/RobinHerbots/jquery.inputmask
2497
+ Copyright (c) 2010 - 2014 Robin Herbots
2498
+ Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
2499
+ Version: 2.5.5
2500
+
2501
+ Regex extensions on the jquery.inputmask base
2502
+ Allows for using regular expressions as a mask
2503
+ */
2504
+ (function ($) {
2505
+ $.extend($.inputmask.defaults.aliases, { // $(selector).inputmask("Regex", { regex: "[0-9]*"}
2506
+ 'Regex': {
2507
+ mask: "r",
2508
+ greedy: false,
2509
+ repeat: "*",
2510
+ regex: null,
2511
+ regexTokens: null,
2512
+ //Thx to https://github.com/slevithan/regex-colorizer for the tokenizer regex
2513
+ tokenizer: /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g,
2514
+ quantifierFilter: /[0-9]+[^,]/,
2515
+ definitions: {
2516
+ 'r': {
2517
+ validator: function (chrs, buffer, pos, strict, opts) {
2518
+ function regexToken(isGroup, isQuantifier) {
2519
+ this.matches = [];
2520
+ this.isGroup = isGroup || false;
2521
+ this.isQuantifier = isQuantifier || false;
2522
+ this.quantifier = { min: 1, max: 1 };
2523
+ this.repeaterPart = undefined;
2524
+ }
2525
+ function analyseRegex() {
2526
+ var currentToken = new regexToken(), match, m, opengroups = [];
2527
+
2528
+ opts.regexTokens = [];
2529
+
2530
+ // The tokenizer regex does most of the tokenization grunt work
2531
+ while (match = opts.tokenizer.exec(opts.regex)) {
2532
+ m = match[0];
2533
+ switch (m.charAt(0)) {
2534
+ case "(": // Group opening
2535
+ opengroups.push(new regexToken(true));
2536
+ break;
2537
+ case ")": // Group closing
2538
+ var groupToken = opengroups.pop();
2539
+ if (opengroups.length > 0) {
2540
+ opengroups[opengroups.length - 1]["matches"].push(groupToken);
2541
+ } else {
2542
+ currentToken.matches.push(groupToken);
2543
+ }
2544
+ break;
2545
+ case "{": case "+": case "*": //Quantifier
2546
+ var quantifierToken = new regexToken(false, true);
2547
+ m = m.replace(/[{}]/g, "");
2548
+ var mq = m.split(","), mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]), mq1 = mq.length == 1 ? mq0 : (isNaN(mq[1]) ? mq[1] : parseInt(mq[1]));
2549
+ quantifierToken.quantifier = { min: mq0, max: mq1 };
2550
+ if (opengroups.length > 0) {
2551
+ var matches = opengroups[opengroups.length - 1]["matches"];
2552
+ match = matches.pop();
2553
+ if (!match["isGroup"]) {
2554
+ var groupToken = new regexToken(true);
2555
+ groupToken.matches.push(match);
2556
+ match = groupToken;
2557
+ }
2558
+ matches.push(match);
2559
+ matches.push(quantifierToken);
2560
+ } else {
2561
+ match = currentToken.matches.pop();
2562
+ if (!match["isGroup"]) {
2563
+ var groupToken = new regexToken(true);
2564
+ groupToken.matches.push(match);
2565
+ match = groupToken;
2566
+ }
2567
+ currentToken.matches.push(match);
2568
+ currentToken.matches.push(quantifierToken);
2569
+ }
2570
+ break;
2571
+ default:
2572
+ if (opengroups.length > 0) {
2573
+ opengroups[opengroups.length - 1]["matches"].push(m);
2574
+ } else {
2575
+ currentToken.matches.push(m);
2576
+ }
2577
+ break;
2578
+ }
2579
+ }
2580
+
2581
+ if (currentToken.matches.length > 0)
2582
+ opts.regexTokens.push(currentToken);
2583
+ };
2584
+
2585
+ function validateRegexToken(token, fromGroup) {
2586
+ var isvalid = false;
2587
+ if (fromGroup) {
2588
+ regexPart += "(";
2589
+ openGroupCount++;
2590
+ }
2591
+ for (var mndx = 0; mndx < token["matches"].length; mndx++) {
2592
+ var matchToken = token["matches"][mndx];
2593
+ if (matchToken["isGroup"] == true) {
2594
+ isvalid = validateRegexToken(matchToken, true);
2595
+ } else if (matchToken["isQuantifier"] == true) {
2596
+ var crrntndx = token["matches"].indexOf(matchToken),
2597
+ matchGroup = token["matches"][crrntndx - 1];
2598
+ var regexPartBak = regexPart;
2599
+ if (isNaN(matchToken.quantifier.max)) {
2600
+ while (matchToken["repeaterPart"] && matchToken["repeaterPart"] != regexPart && matchToken["repeaterPart"].length > regexPart.length) {
2601
+ isvalid = validateRegexToken(matchGroup, true);
2602
+ if (isvalid) break;
2603
+ }
2604
+ isvalid = isvalid || validateRegexToken(matchGroup, true);
2605
+ if (isvalid) matchToken["repeaterPart"] = regexPart;
2606
+ regexPart = regexPartBak + matchToken.quantifier.max;
2607
+ } else {
2608
+ for (var i = 0, qm = matchToken.quantifier.max - 1; i < qm; i++) {
2609
+ isvalid = validateRegexToken(matchGroup, true);
2610
+ if (isvalid) break;
2611
+ }
2612
+ regexPart = regexPartBak + "{" + matchToken.quantifier.min + "," + matchToken.quantifier.max + "}";
2613
+ }
2614
+ } else if (matchToken["matches"] != undefined) {
2615
+ for (var k = 0; k < matchToken.length; k++) {
2616
+ isvalid = validateRegexToken(matchToken[k], fromGroup);
2617
+ if (isvalid) break;
2618
+ }
2619
+ } else {
2620
+ var testExp;
2621
+ if (matchToken[0] == "[") {
2622
+ testExp = regexPart;
2623
+ testExp += matchToken;
2624
+ for (var j = 0; j < openGroupCount; j++) {
2625
+ testExp += ")";
2626
+ }
2627
+ var exp = new RegExp("^(" + testExp + ")$");
2628
+ isvalid = exp.test(bufferStr);
2629
+ } else {
2630
+ for (var l = 0, tl = matchToken.length; l < tl; l++) {
2631
+ if (matchToken[l] == "\\") continue;
2632
+ testExp = regexPart;
2633
+ testExp += matchToken.substr(0, l + 1);
2634
+ testExp = testExp.replace(/\|$/, "");
2635
+ for (var j = 0; j < openGroupCount; j++) {
2636
+ testExp += ")";
2637
+ }
2638
+ var exp = new RegExp("^(" + testExp + ")$");
2639
+ isvalid = exp.test(bufferStr);
2640
+ if (isvalid) break;
2641
+ }
2642
+ }
2643
+ regexPart += matchToken;
2644
+ }
2645
+ if (isvalid) break;
2646
+ }
2647
+
2648
+ if (fromGroup) {
2649
+ regexPart += ")";
2650
+ openGroupCount--;
2651
+ }
2652
+
2653
+ return isvalid;
2654
+ }
2655
+
2656
+
2657
+ if (opts.regexTokens == null) {
2658
+ analyseRegex();
2659
+ }
2660
+
2661
+ var cbuffer = buffer.slice(), regexPart = "", isValid = false, openGroupCount = 0;
2662
+ cbuffer.splice(pos, 0, chrs);
2663
+ var bufferStr = cbuffer.join('');
2664
+ for (var i = 0; i < opts.regexTokens.length; i++) {
2665
+ var regexToken = opts.regexTokens[i];
2666
+ isValid = validateRegexToken(regexToken, regexToken["isGroup"]);
2667
+ if (isValid) break;
2668
+ }
2669
+
2670
+ return isValid;
2671
+ },
2672
+ cardinality: 1
2673
+ }
2674
+ }
2675
+ }
2676
+ });
2677
+ })(jQuery);
2678
+ /*
2679
+ Input Mask plugin extensions
2680
+ http://github.com/RobinHerbots/jquery.inputmask
2681
+ Copyright (c) 2010 - 2014 Robin Herbots
2682
+ Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
2683
+ Version: 2.5.5
2684
+
2685
+ Phone extension.
2686
+ When using this extension make sure you specify the correct url to get the masks
2687
+
2688
+ $(selector).inputmask("phone", {
2689
+ url: "Scripts/jquery.inputmask/phone-codes/phone-codes.json",
2690
+ onKeyValidation: function () { //show some metadata in the console
2691
+ console.log($(this).inputmask("getmetadata")["name_en"]);
2692
+ }
2693
+ });
2694
+
2695
+
2696
+ */
2697
+ (function ($) {
2698
+ $.extend($.inputmask.defaults.aliases, {
2699
+ 'phone': {
2700
+ url: "phone-codes/phone-codes.json",
2701
+ mask: function (opts) {
2702
+ opts.definitions = {
2703
+ 'p': {
2704
+ validator: function () { return false; },
2705
+ cardinality: 1
2706
+ },
2707
+ '#': {
2708
+ validator: "[0-9]",
2709
+ cardinality: 1
2710
+ }
2711
+ };
2712
+ var maskList = [];
2713
+ $.ajax({
2714
+ url: opts.url,
2715
+ async: false,
2716
+ dataType: 'json',
2717
+ success: function (response) {
2718
+ maskList = response;
2719
+ }
2720
+ });
2721
+
2722
+ maskList.splice(0, 0, "+p(ppp)ppp-pppp");
2723
+ return maskList;
2724
+ }
2725
+ }
2726
+ });
2727
+ })(jQuery);