/* Masked Input plugin for jQuery Copyright (c) 2007-2013 Josh Bush (digitalbush.com) Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license) Version: 1.3.1 */ //(function(e){function t(){var e=document.createElement("input"),t="onpaste";return e.setAttribute(t,""),"function"==typeof e[t]?"paste":"input"}var n,a=t()+".mask",r=navigator.userAgent,i=/iphone/i.test(r),o=/android/i.test(r);e.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},dataName:"rawMaskFn",placeholder:"_"},e.fn.extend({caret:function(e,t){var n;if(0!==this.length&&!this.is(":hidden"))return"number"==typeof e?(t="number"==typeof t?t:e,this.each(function(){this.setSelectionRange?this.setSelectionRange(e,t):this.createTextRange&&(n=this.createTextRange(),n.collapse(!0),n.moveEnd("character",t),n.moveStart("character",e),n.select())})):(this[0].setSelectionRange?(e=this[0].selectionStart,t=this[0].selectionEnd):document.selection&&document.selection.createRange&&(n=document.selection.createRange(),e=0-n.duplicate().moveStart("character",-1e5),t=e+n.text.length),{begin:e,end:t})},unmask:function(){return this.trigger("unmask")},mask:function(t,r){var c,l,s,u,f,h;return!t&&this.length>0?(c=e(this[0]),c.data(e.mask.dataName)()):(r=e.extend({placeholder:e.mask.placeholder,completed:null},r),l=e.mask.definitions,s=[],u=h=t.length,f=null,e.each(t.split(""),function(e,t){"?"==t?(h--,u=e):l[t]?(s.push(RegExp(l[t])),null===f&&(f=s.length-1)):s.push(null)}),this.trigger("unmask").each(function(){function c(e){for(;h>++e&&!s[e];);return e}function d(e){for(;--e>=0&&!s[e];);return e}function m(e,t){var n,a;if(!(0>e)){for(n=e,a=c(t);h>n;n++)if(s[n]){if(!(h>a&&s[n].test(R[a])))break;R[n]=R[a],R[a]=r.placeholder,a=c(a)}b(),x.caret(Math.max(f,e))}}function p(e){var t,n,a,i;for(t=e,n=r.placeholder;h>t;t++)if(s[t]){if(a=c(t),i=R[t],R[t]=n,!(h>a&&s[a].test(i)))break;n=i}}function g(e){var t,n,a,r=e.which;8===r||46===r||i&&127===r?(t=x.caret(),n=t.begin,a=t.end,0===a-n&&(n=46!==r?d(n):a=c(n-1),a=46===r?c(a):a),k(n,a),m(n,a-1),e.preventDefault()):27==r&&(x.val(S),x.caret(0,y()),e.preventDefault())}function v(t){var n,a,i,l=t.which,u=x.caret();t.ctrlKey||t.altKey||t.metaKey||32>l||l&&(0!==u.end-u.begin&&(k(u.begin,u.end),m(u.begin,u.end-1)),n=c(u.begin-1),h>n&&(a=String.fromCharCode(l),s[n].test(a)&&(p(n),R[n]=a,b(),i=c(n),o?setTimeout(e.proxy(e.fn.caret,x,i),0):x.caret(i),r.completed&&i>=h&&r.completed.call(x))),t.preventDefault())}function k(e,t){var n;for(n=e;t>n&&h>n;n++)s[n]&&(R[n]=r.placeholder)}function b(){x.val(R.join(""))}function y(e){var t,n,a=x.val(),i=-1;for(t=0,pos=0;h>t;t++)if(s[t]){for(R[t]=r.placeholder;pos++a.length)break}else R[t]===a.charAt(pos)&&t!==u&&(pos++,i=t);return e?b():u>i+1?(x.val(""),k(0,h)):(b(),x.val(x.val().substring(0,i+1))),u?t:f}var x=e(this),R=e.map(t.split(""),function(e){return"?"!=e?l[e]?r.placeholder:e:void 0}),S=x.val();x.data(e.mask.dataName,function(){return e.map(R,function(e,t){return s[t]&&e!=r.placeholder?e:null}).join("")}),x.attr("readonly")||x.one("unmask",function(){x.unbind(".mask").removeData(e.mask.dataName)}).bind("focus.mask",function(){clearTimeout(n);var e;S=x.val(),e=y(),n=setTimeout(function(){b(),e==t.length?x.caret(0,e):x.caret(e)},10)}).bind("blur.mask",function(){y(),x.val()!=S&&x.change()}).bind("keydown.mask",g).bind("keypress.mask",v).bind(a,function(){setTimeout(function(){var e=y(!0);x.caret(e),r.completed&&e==x.val().length&&r.completed.call(x)},0)}),y()}))}})})(jQuery); (function($) { function getPasteEvent() { var el = document.createElement('input'), name = 'onpaste'; el.setAttribute(name, ''); return (typeof el[name] === 'function')?'paste':'input'; } var pasteEventName = getPasteEvent() + ".mask", ua = navigator.userAgent, iPhone = /iphone/i.test(ua), chrome = /chrome/i.test(ua), android=/android/i.test(ua), caretTimeoutId; $.mask = { //Predefined character definitions definitions: { '9': "[0-9]", 'a': "[A-Za-z]", '*': "[A-Za-z0-9]" }, autoclear: true, dataName: "rawMaskFn", placeholder: '_' }; $.fn.extend({ //Helper Function for Caret positioning caret: function(begin, end) { var range; if (this.length === 0 || this.is(":hidden")) { return; } if (typeof begin == 'number') { end = (typeof end === 'number') ? end : begin; return this.each(function() { if (this.setSelectionRange) { this.setSelectionRange(begin, end); } else if (this.createTextRange) { range = this.createTextRange(); range.collapse(true); range.moveEnd('character', end); range.moveStart('character', begin); range.select(); } }); } else { if (this[0].setSelectionRange) { begin = this[0].selectionStart; end = this[0].selectionEnd; } else if (document.selection && document.selection.createRange) { range = document.selection.createRange(); begin = 0 - range.duplicate().moveStart('character', -100000); end = begin + range.text.length; } return { begin: begin, end: end }; } }, unmask: function() { return this.trigger("unmask"); }, mask: function(mask, settings) { var input, defs, tests, partialPosition, firstNonMaskPos, len; if (!mask && this.length > 0) { input = $(this[0]); return input.data($.mask.dataName)(); } settings = $.extend({ autoclear: $.mask.autoclear, placeholder: $.mask.placeholder, // Load default placeholder completed: null }, settings); defs = $.mask.definitions; tests = []; partialPosition = len = mask.length; firstNonMaskPos = null; $.each(mask.split(""), function(i, c) { if (c == '?') { len--; partialPosition = i; } else if (defs[c]) { tests.push(new RegExp(defs[c])); if (firstNonMaskPos === null) { firstNonMaskPos = tests.length - 1; } } else { tests.push(null); } }); return this.trigger("unmask").each(function() { var input = $(this), buffer = $.map( mask.split(""), function(c, i) { if (c != '?') { return defs[c] ? settings.placeholder[i % settings.placeholder.length] : c; } }), defaultBuffer = buffer.join(''), focusText = input.val(); function seekNext(pos) { while (++pos < len && !tests[pos]); return pos; } function seekPrev(pos) { while (--pos >= 0 && !tests[pos]); return pos; } function shiftL(begin,end) { var i, j; if (begin<0) { return; } for (i = begin, j = seekNext(end); i < len; i++) { if (tests[i]) { if (j < len && tests[i].test(buffer[j])) { buffer[i] = buffer[j]; buffer[j] = settings.placeholder; } else { break; } j = seekNext(j); } } writeBuffer(); input.caret(Math.max(firstNonMaskPos, begin)); } function shiftR(pos) { var i, c, j, t; for (i = pos, c = settings.placeholder; i < len; i++) { if (tests[i]) { j = seekNext(i); t = buffer[i]; buffer[i] = c; if (j < len && tests[j].test(t)) { c = t; } else { break; } } } } function blurEvent(e) { checkVal(); if (input.val() != focusText) input.change(); } function keydownEvent(e) { var k = e.which, pos, begin, end; //backspace, delete, and escape get special treatment if (k === 8 || k === 46 || (iPhone && k === 127)) { pos = input.caret(); begin = pos.begin; end = pos.end; if (end - begin === 0) { begin=k!==46?seekPrev(begin):(end=seekNext(begin-1)); end=k===46?seekNext(end):end; } clearBuffer(begin, end); shiftL(begin, end - 1); e.preventDefault(); } else if( k === 13 ) { // enter blurEvent.call(this, e); } else if (k === 27) { // escape input.val(focusText); input.caret(0, checkVal()); e.preventDefault(); } } function keypressEvent(e) { var k = e.which, pos = input.caret(), p, c, next; if (k == 0) { // unable to detect key pressed. Grab it from pos and adjust // this is a failsafe for mobile chrome // which can't detect keypress events // reliably if (pos.begin >= len) { input.val(input.val().substr(0, len)); e.preventDefault(); return false; } if (pos.begin == pos.end) { k = input.val().charCodeAt(pos.begin - 1); pos.begin--; pos.end--; } } if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore return; } else if ( k && k !== 13 ) { if (pos.end - pos.begin !== 0){ clearBuffer(pos.begin, pos.end); shiftL(pos.begin, pos.end-1); } p = seekNext(pos.begin - 1); if (p < len) { c = String.fromCharCode(k); if (tests[p].test(c)) { shiftR(p); buffer[p] = c; writeBuffer(); next = seekNext(p); if(android){ setTimeout($.proxy($.fn.caret,input,next),0); }else{ input.caret(next); } if (settings.completed && next >= len) { settings.completed.call(input); } } } e.preventDefault(); } } function clearBuffer(start, end) { var i; for (i = start; i < end && i < len; i++) { if (tests[i]) { buffer[i] = settings.placeholder[i % settings.placeholder.length]; } } } function writeBuffer() { input.val(buffer.join('')); } function checkVal(allow) { //try to place characters where they belong var test = input.val(), lastMatch = -1, i, c, pos; for (i = 0, pos = 0; i < len; i++) { if (tests[i]) { buffer[i] = settings.placeholder[i % settings.placeholder.length]; while (pos++ < test.length) { c = test.charAt(pos - 1); if (tests[i].test(c)) { buffer[i] = c; lastMatch = i; break; } } if (pos > test.length) { break; } } else if (buffer[i] === test.charAt(pos) && i !== partialPosition) { pos++; lastMatch = i; } } if (allow) { writeBuffer(); } else if (lastMatch + 1 < partialPosition) { if (settings.autoclear || buffer.join('') === defaultBuffer) { // Invalid value. Remove it and replace it with the // mask, which is the default behavior. input.val(""); clearBuffer(0, len); } else { // Invalid value, but we opt to show the value to the // user and allow them to correct their mistake. writeBuffer(); } } else { writeBuffer(); input.val(input.val().substring(0, lastMatch + 1)); } return (partialPosition ? i : firstNonMaskPos); } input.data($.mask.dataName,function(){ return $.map(buffer, function(c, i) { return tests[i]&&c!=settings.placeholder[i % settings.placeholder.length] ? c : null; }).join(''); }); if (!input.attr("readonly")) input .one("unmask", function() { input .unbind(".mask") .removeData($.mask.dataName); }) .bind("focus.mask", function() { clearTimeout(caretTimeoutId); var pos; focusText = input.val(); pos = checkVal(); caretTimeoutId = setTimeout(function(){ writeBuffer(); if (pos == mask.replace("?","").length) { input.caret(0, pos); } else { input.caret(pos); } }, 10); }) .bind("blur.mask", blurEvent) .bind("keydown.mask", keydownEvent) .bind("keypress.mask", keypressEvent) .bind(pasteEventName, function() { setTimeout(function() { var pos=checkVal(true); input.caret(pos); if (settings.completed && pos == input.val().length) settings.completed.call(input); }, 0); }); if (chrome && android) { input.bind("keyup.mask", keypressEvent); } checkVal(); //Perform initial check for existing values }); } }); })(jQuery);