1 | /**
|
---|
2 | * jquery.input-mask.js
|
---|
3 | * @version: v1.14.15
|
---|
4 | * @author: Igor Escobar
|
---|
5 | *
|
---|
6 | * Created by Igor Escobar on 2012-03-10. Please report any bug at github.com/igorescobar/jQuery-Mask-Plugin
|
---|
7 | *
|
---|
8 | * Copyright (c) 2012 Igor Escobar http://igorescobar.com
|
---|
9 | *
|
---|
10 | * The MIT License (http://www.opensource.org/licenses/mit-license.php)
|
---|
11 | *
|
---|
12 | * Permission is hereby granted, free of charge, to any person
|
---|
13 | * obtaining a copy of this software and associated documentation
|
---|
14 | * files (the "Software"), to deal in the Software without
|
---|
15 | * restriction, including without limitation the rights to use,
|
---|
16 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
17 | * copies of the Software, and to permit persons to whom the
|
---|
18 | * Software is furnished to do so, subject to the following
|
---|
19 | * conditions:
|
---|
20 | *
|
---|
21 | * The above copyright notice and this permission notice shall be
|
---|
22 | * included in all copies or substantial portions of the Software.
|
---|
23 | *
|
---|
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
---|
25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
---|
26 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
---|
27 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
---|
28 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
---|
29 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
---|
30 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
---|
31 | * OTHER DEALINGS IN THE SOFTWARE.
|
---|
32 | */
|
---|
33 |
|
---|
34 | /* jshint laxbreak: true */
|
---|
35 | /* jshint maxcomplexity:17 */
|
---|
36 | /* global define */
|
---|
37 |
|
---|
38 | // UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere.
|
---|
39 | // https://github.com/umdjs/umd/blob/master/templates/jqueryPlugin.js
|
---|
40 | (function (factory, jQuery, Zepto) {
|
---|
41 |
|
---|
42 | if (typeof define === 'function' && define.amd) {
|
---|
43 | define(['jquery'], factory);
|
---|
44 | } else if (typeof exports === 'object') {
|
---|
45 | module.exports = factory(require('jquery'));
|
---|
46 | } else {
|
---|
47 | factory(jQuery || Zepto);
|
---|
48 | }
|
---|
49 |
|
---|
50 | }(function ($) {
|
---|
51 | 'use strict';
|
---|
52 |
|
---|
53 | var Mask = function (el, mask, options) {
|
---|
54 |
|
---|
55 | var p = {
|
---|
56 | invalid: [],
|
---|
57 | getCaret: function () {
|
---|
58 | try {
|
---|
59 | var sel,
|
---|
60 | pos = 0,
|
---|
61 | ctrl = el.get(0),
|
---|
62 | dSel = document.selection,
|
---|
63 | cSelStart = ctrl.selectionStart;
|
---|
64 |
|
---|
65 | // IE Support
|
---|
66 | if (dSel && navigator.appVersion.indexOf('MSIE 10') === -1) {
|
---|
67 | sel = dSel.createRange();
|
---|
68 | sel.moveStart('character', -p.val().length);
|
---|
69 | pos = sel.text.length;
|
---|
70 | }
|
---|
71 | // Firefox support
|
---|
72 | else if (cSelStart || cSelStart === '0') {
|
---|
73 | pos = cSelStart;
|
---|
74 | }
|
---|
75 |
|
---|
76 | return pos;
|
---|
77 | } catch (e) {}
|
---|
78 | },
|
---|
79 | setCaret: function(pos) {
|
---|
80 | try {
|
---|
81 | if (el.is(':focus')) {
|
---|
82 | var range, ctrl = el.get(0);
|
---|
83 |
|
---|
84 | // Firefox, WebKit, etc..
|
---|
85 | if (ctrl.setSelectionRange) {
|
---|
86 | ctrl.setSelectionRange(pos, pos);
|
---|
87 | } else { // IE
|
---|
88 | range = ctrl.createTextRange();
|
---|
89 | range.collapse(true);
|
---|
90 | range.moveEnd('character', pos);
|
---|
91 | range.moveStart('character', pos);
|
---|
92 | range.select();
|
---|
93 | }
|
---|
94 | }
|
---|
95 | } catch (e) {}
|
---|
96 | },
|
---|
97 | events: function() {
|
---|
98 | el
|
---|
99 | .on('keydown.mask', function(e) {
|
---|
100 | el.data('input-mask-keycode', e.keyCode || e.which);
|
---|
101 | el.data('input-mask-previus-value', el.val());
|
---|
102 | el.data('input-mask-previus-caret-pos', p.getCaret());
|
---|
103 | p.maskDigitPosMapOld = p.maskDigitPosMap;
|
---|
104 | })
|
---|
105 | .on($.jMaskGlobals.useInput ? 'input.mask' : 'keyup.mask', p.behaviour)
|
---|
106 | .on('paste.input-mask drop.mask', function() {
|
---|
107 | setTimeout(function() {
|
---|
108 | el.keydown().keyup();
|
---|
109 | }, 100);
|
---|
110 | })
|
---|
111 | .on('change.mask', function(){
|
---|
112 | el.data('changed', true);
|
---|
113 | })
|
---|
114 | .on('blur.mask', function(){
|
---|
115 | if (oldValue !== p.val() && !el.data('changed')) {
|
---|
116 | el.trigger('change');
|
---|
117 | }
|
---|
118 | el.data('changed', false);
|
---|
119 | })
|
---|
120 | // it's very important that this callback remains in this position
|
---|
121 | // otherwhise oldValue it's going to work buggy
|
---|
122 | .on('blur.mask', function() {
|
---|
123 | oldValue = p.val();
|
---|
124 | })
|
---|
125 | // select all text on focus
|
---|
126 | .on('focus.mask', function (e) {
|
---|
127 | if (options.selectOnFocus === true) {
|
---|
128 | $(e.target).select();
|
---|
129 | }
|
---|
130 | })
|
---|
131 | // clear the value if it not complete the input-mask
|
---|
132 | .on('focusout.mask', function() {
|
---|
133 | if (options.clearIfNotMatch && !regexMask.test(p.val())) {
|
---|
134 | p.val('');
|
---|
135 | }
|
---|
136 | });
|
---|
137 | },
|
---|
138 | getRegexMask: function() {
|
---|
139 | var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r;
|
---|
140 |
|
---|
141 | for (var i = 0; i < mask.length; i++) {
|
---|
142 | translation = jMask.translation[mask.charAt(i)];
|
---|
143 |
|
---|
144 | if (translation) {
|
---|
145 |
|
---|
146 | pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, '');
|
---|
147 | optional = translation.optional;
|
---|
148 | recursive = translation.recursive;
|
---|
149 |
|
---|
150 | if (recursive) {
|
---|
151 | maskChunks.push(mask.charAt(i));
|
---|
152 | oRecursive = {digit: mask.charAt(i), pattern: pattern};
|
---|
153 | } else {
|
---|
154 | maskChunks.push(!optional && !recursive ? pattern : (pattern + '?'));
|
---|
155 | }
|
---|
156 |
|
---|
157 | } else {
|
---|
158 | maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
|
---|
159 | }
|
---|
160 | }
|
---|
161 |
|
---|
162 | r = maskChunks.join('');
|
---|
163 |
|
---|
164 | if (oRecursive) {
|
---|
165 | r = r.replace(new RegExp('(' + oRecursive.digit + '(.*' + oRecursive.digit + ')?)'), '($1)?')
|
---|
166 | .replace(new RegExp(oRecursive.digit, 'g'), oRecursive.pattern);
|
---|
167 | }
|
---|
168 |
|
---|
169 | return new RegExp(r);
|
---|
170 | },
|
---|
171 | destroyEvents: function() {
|
---|
172 | el.off(['input', 'keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask '));
|
---|
173 | },
|
---|
174 | val: function(v) {
|
---|
175 | var isInput = el.is('input'),
|
---|
176 | method = isInput ? 'val' : 'text',
|
---|
177 | r;
|
---|
178 |
|
---|
179 | if (arguments.length > 0) {
|
---|
180 | if (el[method]() !== v) {
|
---|
181 | el[method](v);
|
---|
182 | }
|
---|
183 | r = el;
|
---|
184 | } else {
|
---|
185 | r = el[method]();
|
---|
186 | }
|
---|
187 |
|
---|
188 | return r;
|
---|
189 | },
|
---|
190 | calculateCaretPosition: function() {
|
---|
191 | var oldVal = el.data('input-mask-previus-value') || '',
|
---|
192 | newVal = p.getMasked(),
|
---|
193 | caretPosNew = p.getCaret();
|
---|
194 | if (oldVal !== newVal) {
|
---|
195 | var caretPosOld = el.data('input-mask-previus-caret-pos') || 0,
|
---|
196 | newValL = newVal.length,
|
---|
197 | oldValL = oldVal.length,
|
---|
198 | maskDigitsBeforeCaret = 0,
|
---|
199 | maskDigitsAfterCaret = 0,
|
---|
200 | maskDigitsBeforeCaretAll = 0,
|
---|
201 | maskDigitsBeforeCaretAllOld = 0,
|
---|
202 | i = 0;
|
---|
203 |
|
---|
204 | for (i = caretPosNew; i < newValL; i++) {
|
---|
205 | if (!p.maskDigitPosMap[i]) {
|
---|
206 | break;
|
---|
207 | }
|
---|
208 | maskDigitsAfterCaret++;
|
---|
209 | }
|
---|
210 |
|
---|
211 | for (i = caretPosNew - 1; i >= 0; i--) {
|
---|
212 | if (!p.maskDigitPosMap[i]) {
|
---|
213 | break;
|
---|
214 | }
|
---|
215 | maskDigitsBeforeCaret++;
|
---|
216 | }
|
---|
217 |
|
---|
218 | for (i = caretPosNew - 1; i >= 0; i--) {
|
---|
219 | if (p.maskDigitPosMap[i]) {
|
---|
220 | maskDigitsBeforeCaretAll++;
|
---|
221 | }
|
---|
222 | }
|
---|
223 |
|
---|
224 | for (i = caretPosOld - 1; i >= 0; i--) {
|
---|
225 | if (p.maskDigitPosMapOld[i]) {
|
---|
226 | maskDigitsBeforeCaretAllOld++;
|
---|
227 | }
|
---|
228 | }
|
---|
229 |
|
---|
230 | // if the cursor is at the end keep it there
|
---|
231 | if (caretPosNew > oldValL) {
|
---|
232 | caretPosNew = newValL * 10;
|
---|
233 | } else if (caretPosOld >= caretPosNew && caretPosOld !== oldValL) {
|
---|
234 | if (!p.maskDigitPosMapOld[caretPosNew]) {
|
---|
235 | var caretPos = caretPosNew;
|
---|
236 | caretPosNew -= maskDigitsBeforeCaretAllOld - maskDigitsBeforeCaretAll;
|
---|
237 | caretPosNew -= maskDigitsBeforeCaret;
|
---|
238 | if (p.maskDigitPosMap[caretPosNew]) {
|
---|
239 | caretPosNew = caretPos;
|
---|
240 | }
|
---|
241 | }
|
---|
242 | }
|
---|
243 | else if (caretPosNew > caretPosOld) {
|
---|
244 | caretPosNew += maskDigitsBeforeCaretAll - maskDigitsBeforeCaretAllOld;
|
---|
245 | caretPosNew += maskDigitsAfterCaret;
|
---|
246 | }
|
---|
247 | }
|
---|
248 | return caretPosNew;
|
---|
249 | },
|
---|
250 | behaviour: function(e) {
|
---|
251 | e = e || window.event;
|
---|
252 | p.invalid = [];
|
---|
253 |
|
---|
254 | var keyCode = el.data('input-mask-keycode');
|
---|
255 |
|
---|
256 | if ($.inArray(keyCode, jMask.byPassKeys) === -1) {
|
---|
257 | var newVal = p.getMasked(),
|
---|
258 | caretPos = p.getCaret();
|
---|
259 |
|
---|
260 | // this is a compensation to devices/browsers that don't compensate
|
---|
261 | // caret positioning the right way
|
---|
262 | setTimeout(function() {
|
---|
263 | p.setCaret(p.calculateCaretPosition());
|
---|
264 | }, $.jMaskGlobals.keyStrokeCompensation);
|
---|
265 |
|
---|
266 | p.val(newVal);
|
---|
267 | p.setCaret(caretPos);
|
---|
268 | return p.callbacks(e);
|
---|
269 | }
|
---|
270 | },
|
---|
271 | getMasked: function(skipMaskChars, val) {
|
---|
272 | var buf = [],
|
---|
273 | value = val === undefined ? p.val() : val + '',
|
---|
274 | m = 0, maskLen = mask.length,
|
---|
275 | v = 0, valLen = value.length,
|
---|
276 | offset = 1, addMethod = 'push',
|
---|
277 | resetPos = -1,
|
---|
278 | maskDigitCount = 0,
|
---|
279 | maskDigitPosArr = [],
|
---|
280 | lastMaskChar,
|
---|
281 | check;
|
---|
282 |
|
---|
283 | if (options.reverse) {
|
---|
284 | addMethod = 'unshift';
|
---|
285 | offset = -1;
|
---|
286 | lastMaskChar = 0;
|
---|
287 | m = maskLen - 1;
|
---|
288 | v = valLen - 1;
|
---|
289 | check = function () {
|
---|
290 | return m > -1 && v > -1;
|
---|
291 | };
|
---|
292 | } else {
|
---|
293 | lastMaskChar = maskLen - 1;
|
---|
294 | check = function () {
|
---|
295 | return m < maskLen && v < valLen;
|
---|
296 | };
|
---|
297 | }
|
---|
298 |
|
---|
299 | var lastUntranslatedMaskChar;
|
---|
300 | while (check()) {
|
---|
301 | var maskDigit = mask.charAt(m),
|
---|
302 | valDigit = value.charAt(v),
|
---|
303 | translation = jMask.translation[maskDigit];
|
---|
304 |
|
---|
305 | if (translation) {
|
---|
306 | if (valDigit.match(translation.pattern)) {
|
---|
307 | buf[addMethod](valDigit);
|
---|
308 | if (translation.recursive) {
|
---|
309 | if (resetPos === -1) {
|
---|
310 | resetPos = m;
|
---|
311 | } else if (m === lastMaskChar && m !== resetPos) {
|
---|
312 | m = resetPos - offset;
|
---|
313 | }
|
---|
314 |
|
---|
315 | if (lastMaskChar === resetPos) {
|
---|
316 | m -= offset;
|
---|
317 | }
|
---|
318 | }
|
---|
319 | m += offset;
|
---|
320 | } else if (valDigit === lastUntranslatedMaskChar) {
|
---|
321 | // matched the last untranslated (raw) input-mask character that we encountered
|
---|
322 | // likely an insert offset the input-mask character from the last entry; fall
|
---|
323 | // through and only increment v
|
---|
324 | maskDigitCount--;
|
---|
325 | lastUntranslatedMaskChar = undefined;
|
---|
326 | } else if (translation.optional) {
|
---|
327 | m += offset;
|
---|
328 | v -= offset;
|
---|
329 | } else if (translation.fallback) {
|
---|
330 | buf[addMethod](translation.fallback);
|
---|
331 | m += offset;
|
---|
332 | v -= offset;
|
---|
333 | } else {
|
---|
334 | p.invalid.push({p: v, v: valDigit, e: translation.pattern});
|
---|
335 | }
|
---|
336 | v += offset;
|
---|
337 | } else {
|
---|
338 | if (!skipMaskChars) {
|
---|
339 | buf[addMethod](maskDigit);
|
---|
340 | }
|
---|
341 |
|
---|
342 | if (valDigit === maskDigit) {
|
---|
343 | maskDigitPosArr.push(v);
|
---|
344 | v += offset;
|
---|
345 | } else {
|
---|
346 | lastUntranslatedMaskChar = maskDigit;
|
---|
347 | maskDigitPosArr.push(v + maskDigitCount);
|
---|
348 | maskDigitCount++;
|
---|
349 | }
|
---|
350 |
|
---|
351 | m += offset;
|
---|
352 | }
|
---|
353 | }
|
---|
354 |
|
---|
355 | var lastMaskCharDigit = mask.charAt(lastMaskChar);
|
---|
356 | if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) {
|
---|
357 | buf.push(lastMaskCharDigit);
|
---|
358 | }
|
---|
359 |
|
---|
360 | var newVal = buf.join('');
|
---|
361 | p.mapMaskdigitPositions(newVal, maskDigitPosArr, valLen);
|
---|
362 | return newVal;
|
---|
363 | },
|
---|
364 | mapMaskdigitPositions: function(newVal, maskDigitPosArr, valLen) {
|
---|
365 | var maskDiff = options.reverse ? newVal.length - valLen : 0;
|
---|
366 | p.maskDigitPosMap = {};
|
---|
367 | for (var i = 0; i < maskDigitPosArr.length; i++) {
|
---|
368 | p.maskDigitPosMap[maskDigitPosArr[i] + maskDiff] = 1;
|
---|
369 | }
|
---|
370 | },
|
---|
371 | callbacks: function (e) {
|
---|
372 | var val = p.val(),
|
---|
373 | changed = val !== oldValue,
|
---|
374 | defaultArgs = [val, e, el, options],
|
---|
375 | callback = function(name, criteria, args) {
|
---|
376 | if (typeof options[name] === 'function' && criteria) {
|
---|
377 | options[name].apply(this, args);
|
---|
378 | }
|
---|
379 | };
|
---|
380 |
|
---|
381 | callback('onChange', changed === true, defaultArgs);
|
---|
382 | callback('onKeyPress', changed === true, defaultArgs);
|
---|
383 | callback('onComplete', val.length === mask.length, defaultArgs);
|
---|
384 | callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]);
|
---|
385 | }
|
---|
386 | };
|
---|
387 |
|
---|
388 | el = $(el);
|
---|
389 | var jMask = this, oldValue = p.val(), regexMask;
|
---|
390 |
|
---|
391 | mask = typeof mask === 'function' ? mask(p.val(), undefined, el, options) : mask;
|
---|
392 |
|
---|
393 | // public methods
|
---|
394 | jMask.mask = mask;
|
---|
395 | jMask.options = options;
|
---|
396 | jMask.remove = function() {
|
---|
397 | var caret = p.getCaret();
|
---|
398 | if (jMask.options.placeholder) {
|
---|
399 | el.removeAttr('placeholder');
|
---|
400 | }
|
---|
401 | if (el.data('input-mask-maxlength')) {
|
---|
402 | el.removeAttr('maxlength');
|
---|
403 | }
|
---|
404 | p.destroyEvents();
|
---|
405 | p.val(jMask.getCleanVal());
|
---|
406 | p.setCaret(caret);
|
---|
407 | return el;
|
---|
408 | };
|
---|
409 |
|
---|
410 | // get value without input-mask
|
---|
411 | jMask.getCleanVal = function() {
|
---|
412 | return p.getMasked(true);
|
---|
413 | };
|
---|
414 |
|
---|
415 | // get masked value without the value being in the input or element
|
---|
416 | jMask.getMaskedVal = function(val) {
|
---|
417 | return p.getMasked(false, val);
|
---|
418 | };
|
---|
419 |
|
---|
420 | jMask.init = function(onlyMask) {
|
---|
421 | onlyMask = onlyMask || false;
|
---|
422 | options = options || {};
|
---|
423 |
|
---|
424 | jMask.clearIfNotMatch = $.jMaskGlobals.clearIfNotMatch;
|
---|
425 | jMask.byPassKeys = $.jMaskGlobals.byPassKeys;
|
---|
426 | jMask.translation = $.extend({}, $.jMaskGlobals.translation, options.translation);
|
---|
427 |
|
---|
428 | jMask = $.extend(true, {}, jMask, options);
|
---|
429 |
|
---|
430 | regexMask = p.getRegexMask();
|
---|
431 |
|
---|
432 | if (onlyMask) {
|
---|
433 | p.events();
|
---|
434 | p.val(p.getMasked());
|
---|
435 | } else {
|
---|
436 | if (options.placeholder) {
|
---|
437 | el.attr('placeholder' , options.placeholder);
|
---|
438 | }
|
---|
439 |
|
---|
440 | // this is necessary, otherwise if the user submit the form
|
---|
441 | // and then press the "back" button, the autocomplete will erase
|
---|
442 | // the data. Works fine on IE9+, FF, Opera, Safari.
|
---|
443 | if (el.data('mask')) {
|
---|
444 | el.attr('autocomplete', 'off');
|
---|
445 | }
|
---|
446 |
|
---|
447 | // detect if is necessary let the user type freely.
|
---|
448 | // for is a lot faster than forEach.
|
---|
449 | for (var i = 0, maxlength = true; i < mask.length; i++) {
|
---|
450 | var translation = jMask.translation[mask.charAt(i)];
|
---|
451 | if (translation && translation.recursive) {
|
---|
452 | maxlength = false;
|
---|
453 | break;
|
---|
454 | }
|
---|
455 | }
|
---|
456 |
|
---|
457 | if (maxlength) {
|
---|
458 | el.attr('maxlength', mask.length).data('input-mask-maxlength', true);
|
---|
459 | }
|
---|
460 |
|
---|
461 | p.destroyEvents();
|
---|
462 | p.events();
|
---|
463 |
|
---|
464 | var caret = p.getCaret();
|
---|
465 | p.val(p.getMasked());
|
---|
466 | p.setCaret(caret);
|
---|
467 | }
|
---|
468 | };
|
---|
469 |
|
---|
470 | jMask.init(!el.is('input'));
|
---|
471 | };
|
---|
472 |
|
---|
473 | $.maskWatchers = {};
|
---|
474 | var HTMLAttributes = function () {
|
---|
475 | var input = $(this),
|
---|
476 | options = {},
|
---|
477 | prefix = 'data-input-mask-',
|
---|
478 | mask = input.attr('data-input-mask');
|
---|
479 |
|
---|
480 | if (input.attr(prefix + 'reverse')) {
|
---|
481 | options.reverse = true;
|
---|
482 | }
|
---|
483 |
|
---|
484 | if (input.attr(prefix + 'clearifnotmatch')) {
|
---|
485 | options.clearIfNotMatch = true;
|
---|
486 | }
|
---|
487 |
|
---|
488 | if (input.attr(prefix + 'selectonfocus') === 'true') {
|
---|
489 | options.selectOnFocus = true;
|
---|
490 | }
|
---|
491 |
|
---|
492 | if (notSameMaskObject(input, mask, options)) {
|
---|
493 | return input.data('mask', new Mask(this, mask, options));
|
---|
494 | }
|
---|
495 | },
|
---|
496 | notSameMaskObject = function(field, mask, options) {
|
---|
497 | options = options || {};
|
---|
498 | var maskObject = $(field).data('mask'),
|
---|
499 | stringify = JSON.stringify,
|
---|
500 | value = $(field).val() || $(field).text();
|
---|
501 | try {
|
---|
502 | if (typeof mask === 'function') {
|
---|
503 | mask = mask(value);
|
---|
504 | }
|
---|
505 | return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask;
|
---|
506 | } catch (e) {}
|
---|
507 | },
|
---|
508 | eventSupported = function(eventName) {
|
---|
509 | var el = document.createElement('div'), isSupported;
|
---|
510 |
|
---|
511 | eventName = 'on' + eventName;
|
---|
512 | isSupported = (eventName in el);
|
---|
513 |
|
---|
514 | if ( !isSupported ) {
|
---|
515 | el.setAttribute(eventName, 'return;');
|
---|
516 | isSupported = typeof el[eventName] === 'function';
|
---|
517 | }
|
---|
518 | el = null;
|
---|
519 |
|
---|
520 | return isSupported;
|
---|
521 | };
|
---|
522 |
|
---|
523 | $.fn.mask = function(mask, options) {
|
---|
524 | options = options || {};
|
---|
525 | var selector = this.selector,
|
---|
526 | globals = $.jMaskGlobals,
|
---|
527 | interval = globals.watchInterval,
|
---|
528 | watchInputs = options.watchInputs || globals.watchInputs,
|
---|
529 | maskFunction = function() {
|
---|
530 | if (notSameMaskObject(this, mask, options)) {
|
---|
531 | return $(this).data('mask', new Mask(this, mask, options));
|
---|
532 | }
|
---|
533 | };
|
---|
534 |
|
---|
535 | $(this).each(maskFunction);
|
---|
536 |
|
---|
537 | if (selector && selector !== '' && watchInputs) {
|
---|
538 | clearInterval($.maskWatchers[selector]);
|
---|
539 | $.maskWatchers[selector] = setInterval(function(){
|
---|
540 | $(document).find(selector).each(maskFunction);
|
---|
541 | }, interval);
|
---|
542 | }
|
---|
543 | return this;
|
---|
544 | };
|
---|
545 |
|
---|
546 | $.fn.masked = function(val) {
|
---|
547 | return this.data('mask').getMaskedVal(val);
|
---|
548 | };
|
---|
549 |
|
---|
550 | $.fn.unmask = function() {
|
---|
551 | clearInterval($.maskWatchers[this.selector]);
|
---|
552 | delete $.maskWatchers[this.selector];
|
---|
553 | return this.each(function() {
|
---|
554 | var dataMask = $(this).data('mask');
|
---|
555 | if (dataMask) {
|
---|
556 | dataMask.remove().removeData('mask');
|
---|
557 | }
|
---|
558 | });
|
---|
559 | };
|
---|
560 |
|
---|
561 | $.fn.cleanVal = function() {
|
---|
562 | return this.data('mask').getCleanVal();
|
---|
563 | };
|
---|
564 |
|
---|
565 | $.applyDataMask = function(selector) {
|
---|
566 | selector = selector || $.jMaskGlobals.maskElements;
|
---|
567 | var $selector = (selector instanceof $) ? selector : $(selector);
|
---|
568 | $selector.filter($.jMaskGlobals.dataMaskAttr).each(HTMLAttributes);
|
---|
569 | };
|
---|
570 |
|
---|
571 | var globals = {
|
---|
572 | maskElements: 'input,td,span,div',
|
---|
573 | dataMaskAttr: '*[data-input-mask]',
|
---|
574 | dataMask: true,
|
---|
575 | watchInterval: 300,
|
---|
576 | watchInputs: true,
|
---|
577 | keyStrokeCompensation: 10,
|
---|
578 | // old versions of chrome dont work great with input event
|
---|
579 | useInput: !/Chrome\/[2-4][0-9]|SamsungBrowser/.test(window.navigator.userAgent) && eventSupported('input'),
|
---|
580 | watchDataMask: false,
|
---|
581 | byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91],
|
---|
582 | translation: {
|
---|
583 | '0': {pattern: /\d/},
|
---|
584 | '9': {pattern: /\d/, optional: true},
|
---|
585 | '#': {pattern: /\d/, recursive: true},
|
---|
586 | 'A': {pattern: /[a-zA-Z0-9]/},
|
---|
587 | 'S': {pattern: /[a-zA-Z]/}
|
---|
588 | }
|
---|
589 | };
|
---|
590 |
|
---|
591 | $.jMaskGlobals = $.jMaskGlobals || {};
|
---|
592 | globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals);
|
---|
593 |
|
---|
594 | // looking for inputs with data-input-mask attribute
|
---|
595 | if (globals.dataMask) {
|
---|
596 | $.applyDataMask();
|
---|
597 | }
|
---|
598 |
|
---|
599 | setInterval(function() {
|
---|
600 | if ($.jMaskGlobals.watchDataMask) {
|
---|
601 | $.applyDataMask();
|
---|
602 | }
|
---|
603 | }, globals.watchInterval);
|
---|
604 | }, window.jQuery, window.Zepto));
|
---|