You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
382 lines
14 KiB
382 lines
14 KiB
/*
|
|
* @license Multi Input Mask plugin for jquery
|
|
* https://github.com/andr-04/inputmask-multi
|
|
* Copyright (c) 2012 Andrey Egorov
|
|
* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
|
|
* Version: 1.0.2
|
|
*
|
|
* Requriements:
|
|
* https://github.com/RobinHerbots/jquery.inputmask
|
|
* https://github.com/private-face/jquery.bind-first
|
|
*/
|
|
(function ($) {
|
|
$.masksLoad = function(url) {
|
|
var maskList;
|
|
$.ajax({
|
|
url: url,
|
|
async: false,
|
|
dataType: 'json',
|
|
success: function (response) {
|
|
maskList = response;
|
|
}
|
|
});
|
|
return maskList;
|
|
}
|
|
|
|
$.masksSort = function(maskList, defs, match, key) {
|
|
maskList.sort(function (a, b) {
|
|
var ia = 0, ib = 0;
|
|
for (; (ia<a[key].length && ib<b[key].length);) {
|
|
var cha = a[key].charAt(ia);
|
|
var chb = b[key].charAt(ib);
|
|
if (!match.test(cha)) {
|
|
ia++;
|
|
continue;
|
|
}
|
|
if (!match.test(chb)) {
|
|
ib++;
|
|
continue;
|
|
}
|
|
if ($.inArray(cha, defs) != -1 && $.inArray(chb, defs) == -1) {
|
|
return 1;
|
|
}
|
|
if ($.inArray(cha, defs) == -1 && $.inArray(chb, defs) != -1) {
|
|
return -1;
|
|
}
|
|
if ($.inArray(cha, defs) == -1 && $.inArray(chb, defs) == -1) {
|
|
if (cha != chb) {
|
|
return cha < chb ? -1 : 1;
|
|
}
|
|
}
|
|
ia++;
|
|
ib++;
|
|
}
|
|
for (; (ia<a[key].length || ib<b[key].length);) {
|
|
if (ia<a[key].length && !match.test(a[key].charAt(ia))) {
|
|
ia++;
|
|
continue;
|
|
}
|
|
if (ib<b[key].length && !match.test(b[key].charAt(ib))) {
|
|
ib++;
|
|
continue;
|
|
}
|
|
if (ia<a[key].length) {
|
|
return 1;
|
|
}
|
|
if (ib<b[key].length) {
|
|
return -1;
|
|
}
|
|
}
|
|
return 0;
|
|
});
|
|
return maskList;
|
|
}
|
|
|
|
$.fn.inputmasks = function(maskOpts, mode) {
|
|
//Helper Functions
|
|
var caret = function(begin, end) {
|
|
if (typeof begin == 'number') {
|
|
end = (typeof end == 'number') ? end : begin;
|
|
if (this.setSelectionRange) {
|
|
this.setSelectionRange(begin, end);
|
|
} else if (this.createTextRange) {
|
|
var range = this.createTextRange();
|
|
range.collapse(true);
|
|
range.moveEnd('character', end);
|
|
range.moveStart('character', begin);
|
|
range.select();
|
|
}
|
|
} else {
|
|
if (this.setSelectionRange) {
|
|
begin = this.selectionStart;
|
|
end = this.selectionEnd;
|
|
} else if (document.selection && document.selection.createRange) {
|
|
var range = document.selection.createRange();
|
|
begin = 0 - range.duplicate().moveStart('character', -100000);
|
|
end = begin + range.text.length;
|
|
}
|
|
return {
|
|
begin: begin,
|
|
end: end
|
|
};
|
|
}
|
|
};
|
|
|
|
var keys = Object.keys || function(obj) {
|
|
if (obj !== Object(obj)) {
|
|
throw new TypeError('Invalid object');
|
|
}
|
|
var keys = [];
|
|
for (var key in obj) {
|
|
keys[keys.length] = key;
|
|
}
|
|
return keys;
|
|
};
|
|
|
|
maskOpts = $.extend(true, {
|
|
onMaskChange: $.noop
|
|
}, maskOpts);
|
|
var defs = {};
|
|
for (var def in maskOpts.inputmask.definitions) {
|
|
var validator = maskOpts.inputmask.definitions[def].validator;
|
|
switch (typeof validator) {
|
|
case "string":
|
|
defs[def] = new RegExp(validator);
|
|
break;
|
|
case "object":
|
|
if ("test" in maskOpts.definitions[def].validator) {
|
|
defs[def] = validator;
|
|
}
|
|
break;
|
|
case "function":
|
|
defs[def] = {
|
|
test: validator
|
|
};
|
|
break;
|
|
}
|
|
}
|
|
maskOpts.inputmask.definitions[maskOpts.replace] = {
|
|
validator: maskOpts.match.source,
|
|
cardinality: 1
|
|
};
|
|
var iphone = navigator.userAgent.match(/iphone/i) != null;
|
|
var oldmatch = false;
|
|
var placeholder = $.extend(true, {}, $.inputmask.defaults, maskOpts.inputmask).placeholder;
|
|
var insertMode = $.extend(true, {}, $.inputmask.defaults, maskOpts.inputmask).insertMode;
|
|
|
|
var maskMatch = function(text) {
|
|
var mtxt = "";
|
|
for (var i=0; i<text.length; i++) {
|
|
var ch = text.charAt(i);
|
|
if (ch == placeholder) {
|
|
break;
|
|
}
|
|
if (maskOpts.match.test(ch)) {
|
|
mtxt += ch;
|
|
}
|
|
}
|
|
for (var mid in maskOpts.list) {
|
|
var mask = maskOpts.list[mid][maskOpts.listKey];
|
|
var pass = true;
|
|
for (var it=0, im=0; (it<mtxt.length && im<mask.length);) {
|
|
var chm = mask.charAt(im);
|
|
var cht = mtxt.charAt(it);
|
|
if (!maskOpts.match.test(chm) && !(chm in defs)) {
|
|
im++;
|
|
continue;
|
|
}
|
|
if (((chm in defs) && defs[chm].test(cht)) || (cht == chm)) {
|
|
it++;
|
|
im++;
|
|
} else {
|
|
pass = false;
|
|
break;
|
|
}
|
|
}
|
|
if (pass && it==mtxt.length) {
|
|
var determined = mask.substr(im).search(maskOpts.match) == -1;
|
|
mask = mask.replace(new RegExp([maskOpts.match.source].concat(keys(defs)).join('|'), 'g'), maskOpts.replace);
|
|
var completed = mask.substr(im).search(maskOpts.replace) == -1;
|
|
return {
|
|
mask: mask,
|
|
obj: maskOpts.list[mid],
|
|
determined: determined,
|
|
completed: completed
|
|
};
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
var caretApply = function(oldMask, newMask, oldPos) {
|
|
if (!oldMask) {
|
|
return 0;
|
|
}
|
|
var pos = 0, startPos = 0;
|
|
for (; pos < oldPos.begin; pos++) {
|
|
if (oldMask.charAt(pos) == maskOpts.replace) {
|
|
startPos++;
|
|
}
|
|
}
|
|
var endPos = 0;
|
|
for (; pos < oldPos.end; pos++) {
|
|
if (oldMask.charAt(pos) == maskOpts.replace) {
|
|
endPos++;
|
|
}
|
|
}
|
|
for (pos = 0; (pos < newMask.length && (startPos > 0 || newMask.charAt(pos) != maskOpts.replace)); pos++) {
|
|
if (newMask.charAt(pos) == maskOpts.replace) {
|
|
startPos--;
|
|
}
|
|
}
|
|
startPos = pos;
|
|
for (; (pos < newMask.length && endPos > 0); pos++) {
|
|
if (newMask.charAt(pos) == maskOpts.replace) {
|
|
endPos--;
|
|
}
|
|
}
|
|
endPos = pos;
|
|
return {
|
|
begin: startPos,
|
|
end: endPos
|
|
};
|
|
}
|
|
|
|
var maskUnbind = function() {
|
|
$(this)
|
|
.unbind("keypress.inputmask", masksKeyPress)
|
|
.unbind("input.inputmask", masksPaste)
|
|
.unbind("paste.inputmask", masksPaste)
|
|
.unbind("dragdrop.inputmask", masksPaste)
|
|
.unbind("drop.inputmask", masksPaste)
|
|
.unbind("keydown.inputmask", masksKeyDown)
|
|
.unbind("setvalue.inputmask", masksSetValue)
|
|
.unbind("blur.inputmask", masksChange);
|
|
}
|
|
|
|
var maskRebind = function() {
|
|
maskUnbind.call(this);
|
|
$(this)
|
|
.bindFirst("keypress.inputmask", masksKeyPress)
|
|
.bindFirst("input.inputmask", masksPaste)
|
|
.bindFirst("paste.inputmask", masksPaste)
|
|
.bindFirst("dragdrop.inputmask", masksPaste)
|
|
.bindFirst("drop.inputmask", masksPaste)
|
|
.bindFirst("keydown.inputmask", masksKeyDown)
|
|
.bindFirst("setvalue.inputmask", masksSetValue)
|
|
.bind("blur.inputmask", masksChange);
|
|
}
|
|
|
|
var maskApply = function(match, newtext) {
|
|
if (match && (newtext || match.mask != oldmatch.mask)) {
|
|
var caretPos;
|
|
if (!newtext) {
|
|
caretPos = caretApply(oldmatch.mask, match.mask, caret.call(this));
|
|
}
|
|
if (newtext) {
|
|
if (this._valueSet) {
|
|
this._valueSet(newtext);
|
|
} else {
|
|
this.value = newtext;
|
|
}
|
|
}
|
|
$(this).inputmask(match.mask, $.extend(true, maskOpts.inputmask, {
|
|
insertMode: insertMode
|
|
}));
|
|
if (!newtext) {
|
|
caret.call(this, caretPos.begin, caretPos.end);
|
|
}
|
|
}
|
|
oldmatch = match;
|
|
maskOpts.onMaskChange.call(this, match.obj, match.determined);
|
|
return true;
|
|
}
|
|
|
|
var keyboardApply = function(e, text, insert) {
|
|
var match = maskMatch(text);
|
|
if (!match || match.obj != oldmatch.obj || match.determined != oldmatch.determined) {
|
|
if (match) {
|
|
maskUnbind.call(this);
|
|
if (insert) {
|
|
maskApply.call(this, match);
|
|
$(this).trigger(e);
|
|
} else {
|
|
$(this).trigger(e);
|
|
maskApply.call(this, match);
|
|
}
|
|
maskRebind.call(this);
|
|
}
|
|
e.stopImmediatePropagation();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
var masksKeyDown = function(e) {
|
|
e = e || window.event;
|
|
var k = e.which || e.charCode || e.keyCode;
|
|
if (k == 8 || k == 46 || (iphone && k == 127)) { // delete or backspace
|
|
var text = this._valueGet();
|
|
var caretPos = caret.call(this);
|
|
if (caretPos.begin == caretPos.end || (!insertMode && caretPos.begin == caretPos.end-1)) {
|
|
var pos = caretPos.begin;
|
|
do {
|
|
if (k != 46) { // backspace
|
|
pos--;
|
|
}
|
|
var chr = text.charAt(pos);
|
|
text = text.substring(0, pos) + text.substring(pos+1);
|
|
} while (pos>0 && pos<text.length && chr != placeholder && !maskOpts.match.test(chr));
|
|
} else {
|
|
var test = text.substring(0, caretPos.begin) + text.substring(caretPos.end);
|
|
if (test.search(maskOpts.match) == -1) {
|
|
text = test;
|
|
}
|
|
}
|
|
return keyboardApply.call(this, e, text, false);
|
|
}
|
|
if (k == 45) { // insert
|
|
insertMode = !insertMode;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
var masksKeyPress = function(e) {
|
|
var text = this._valueGet();
|
|
e = e || window.event;
|
|
var k = e.which || e.charCode || e.keyCode, c = String.fromCharCode(k);
|
|
caretPos = caret.call(this);
|
|
text = text.substring(0, caretPos.begin) + c + text.substring(caretPos.end);
|
|
return keyboardApply.call(this, e, text, true);
|
|
}
|
|
|
|
var masksChange = function(e) {
|
|
var match = maskMatch(this._valueGet());
|
|
maskApply.call(this, match);
|
|
maskRebind.call(this);
|
|
return true;
|
|
}
|
|
|
|
var masksSetValue = function(e) {
|
|
maskInit.call(this);
|
|
e.stopImmediatePropagation();
|
|
return true;
|
|
}
|
|
|
|
var maskInit = function() {
|
|
var text;
|
|
if (this._valueGet) {
|
|
text = this._valueGet();
|
|
} else {
|
|
text = this.value;
|
|
}
|
|
var match = maskMatch(text);
|
|
while (!match && text.length>0) {
|
|
text = text.substr(0, text.length-1);
|
|
match = maskMatch(text);
|
|
}
|
|
maskApply.call(this, match, text);
|
|
maskRebind.call(this);
|
|
}
|
|
|
|
var masksPaste = function(e) {
|
|
var input = this;
|
|
setTimeout(function() {
|
|
maskInit.call(input);
|
|
}, 0);
|
|
e.stopImmediatePropagation();
|
|
return true;
|
|
}
|
|
|
|
switch (mode) {
|
|
case "isCompleted":
|
|
var res = maskMatch((this[0]._valueGet && this[0]._valueGet()) || this[0].value);
|
|
return (res && res.completed);
|
|
default:
|
|
this.each(function () {
|
|
maskInit.call(this);
|
|
});
|
|
return this;
|
|
}
|
|
}
|
|
})(jQuery);
|
|
|