|
|
@@ -56,19 +56,19 @@
|
|
|
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
|
|
|
},
|
|
|
//specify keycodes which should not be considered in the keypress event, otherwise the preventDefault will stop their default behavior especially in FF
|
|
|
- ignorables: [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]
|
|
|
+ ignorables: [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],
|
|
|
+ getMaskLength: function (buffer, greedy, repeat, currentBuffer, opts) {
|
|
|
+ var calculatedLength = buffer.length;
|
|
|
+ if (!greedy && repeat > 1) {
|
|
|
+ calculatedLength += (buffer.length * (repeat - 1));
|
|
|
+ }
|
|
|
+ return calculatedLength;
|
|
|
+ }
|
|
|
},
|
|
|
val: $.fn.val, //store the original jquery val function
|
|
|
escapeRegex: function (str) {
|
|
|
var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
|
|
|
return str.replace(new RegExp('(\\' + specials.join('|\\') + ')', 'gim'), '\\$1');
|
|
|
- },
|
|
|
- getMaskLength: function (buffer, greedy, repeat) {
|
|
|
- var calculatedLength = buffer.length;
|
|
|
- if (!greedy && repeat > 1) {
|
|
|
- calculatedLength += (buffer.length * (repeat - 1));
|
|
|
- }
|
|
|
- return calculatedLength;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -303,7 +303,7 @@
|
|
|
|
|
|
function isValid(pos, c, buffer, strict) { //strict true ~ no correction or autofill
|
|
|
var result = false;
|
|
|
- if (pos >= 0 && pos < getMaskLength()) {
|
|
|
+ if (pos >= 0 && pos < getMaskLength(buffer)) {
|
|
|
var testPos = determineTestPosition(pos), loopend = c ? 1 : 0, chrs = '';
|
|
|
for (var i = tests[testPos].cardinality; i > loopend; i--) {
|
|
|
chrs += getBufferElement(buffer, testPos - (i - 1));
|
|
|
@@ -334,13 +334,13 @@
|
|
|
return opts.placeholder.charAt(pos % opts.placeholder.length);
|
|
|
}
|
|
|
|
|
|
- function getMaskLength() {
|
|
|
- return $.inputmask.getMaskLength(_buffer, opts.greedy, opts.repeat);
|
|
|
+ function getMaskLength(currentBuffer) {
|
|
|
+ return opts.getMaskLength(_buffer, opts.greedy, opts.repeat, currentBuffer, opts);
|
|
|
}
|
|
|
|
|
|
//pos: from position
|
|
|
function seekNext(buffer, pos) {
|
|
|
- var maskL = getMaskLength();
|
|
|
+ var maskL = getMaskLength(buffer);
|
|
|
if (pos >= maskL) return maskL;
|
|
|
var position = pos;
|
|
|
while (++position < maskL && !isMask(position)) { };
|
|
|
@@ -382,7 +382,7 @@
|
|
|
function prepareBuffer(buffer, position, isRTL) {
|
|
|
var j;
|
|
|
if (isRTL) {
|
|
|
- while (position < 0 && buffer.length < getMaskLength()) {
|
|
|
+ while (position < 0 && buffer.length < getMaskLength(buffer)) {
|
|
|
j = _buffer.length - 1;
|
|
|
position = _buffer.length;
|
|
|
while (_buffer[j] !== undefined) {
|
|
|
@@ -390,7 +390,7 @@
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- while (buffer[position] == undefined && buffer.length < getMaskLength()) {
|
|
|
+ while (buffer[position] == undefined && buffer.length < getMaskLength(buffer)) {
|
|
|
j = 0;
|
|
|
while (_buffer[j] !== undefined) { //add a new buffer
|
|
|
buffer.push(_buffer[j++]);
|
|
|
@@ -413,7 +413,7 @@
|
|
|
}
|
|
|
};
|
|
|
function clearBuffer(buffer, start, end) {
|
|
|
- for (var i = start, maskL = getMaskLength() ; i < end && i < maskL; i++) {
|
|
|
+ for (var i = start, maskL = getMaskLength(buffer) ; i < end && i < maskL; i++) {
|
|
|
setBufferElement(buffer, i, getBufferElement(_buffer.slice(), i));
|
|
|
}
|
|
|
};
|
|
|
@@ -427,8 +427,8 @@
|
|
|
var isRTL = $(input).data('inputmask')['isRTL'],
|
|
|
inputValue = truncateInput(input._valueGet(), isRTL).split('');
|
|
|
|
|
|
+ var maskL = getMaskLength(buffer);
|
|
|
if (isRTL) { //align inputValue for RTL/numeric input
|
|
|
- var maskL = getMaskLength();
|
|
|
var inputValueRev = inputValue.reverse(); inputValueRev.length = maskL;
|
|
|
|
|
|
for (var i = 0; i < maskL; i++) {
|
|
|
@@ -444,7 +444,7 @@
|
|
|
}
|
|
|
clearBuffer(buffer, 0, buffer.length);
|
|
|
buffer.length = _buffer.length;
|
|
|
- var lastMatch = -1, checkPosition = -1, np, maskL = getMaskLength(), ivl = inputValue.length, rtlMatch = ivl == 0 ? maskL : -1;
|
|
|
+ var lastMatch = -1, checkPosition = -1, np, ivl = inputValue.length, rtlMatch = ivl == 0 ? maskL : -1;
|
|
|
for (var i = 0; i < ivl; i++) {
|
|
|
for (var pos = checkPosition + 1; pos < maskL; pos++) {
|
|
|
if (isMask(pos)) {
|
|
|
@@ -586,17 +586,18 @@
|
|
|
var $input = $(el);
|
|
|
if (!$input.is(":input")) return;
|
|
|
|
|
|
+ var buffer = _buffer.slice();
|
|
|
+
|
|
|
//correct greedy setting if needed
|
|
|
opts.greedy = opts.greedy ? opts.greedy : opts.repeat == 0;
|
|
|
-
|
|
|
//handle maxlength attribute
|
|
|
var maxLength = $input.prop('maxLength');
|
|
|
- if (getMaskLength() > maxLength && maxLength > -1) { //FF sets no defined max length to -1
|
|
|
+ if (getMaskLength(buffer) > maxLength && maxLength > -1) { //FF sets no defined max length to -1
|
|
|
if (maxLength < _buffer.length) _buffer.length = maxLength;
|
|
|
if (opts.greedy == false) {
|
|
|
opts.repeat = Math.round(maxLength / _buffer.length);
|
|
|
}
|
|
|
- $input.prop('maxLength', getMaskLength() * 2);
|
|
|
+ $input.prop('maxLength', getMaskLength(buffer) * 2);
|
|
|
}
|
|
|
|
|
|
//store tests & original buffer in the input element - used to get the unmasked value
|
|
|
@@ -613,13 +614,13 @@
|
|
|
patchValueProperty(el);
|
|
|
|
|
|
//init vars
|
|
|
- var buffer = _buffer.slice(),
|
|
|
- undoBuffer = el._valueGet(),
|
|
|
+
|
|
|
+ var undoBuffer = el._valueGet(),
|
|
|
skipKeyPressEvent = false, //Safari 5.1.x - modal dialog fires keypress twice workaround
|
|
|
ignorable = false,
|
|
|
lastPosition = -1,
|
|
|
firstMaskPos = seekNext(buffer, -1),
|
|
|
- lastMaskPos = seekPrevious(buffer, getMaskLength()),
|
|
|
+ lastMaskPos = seekPrevious(buffer, getMaskLength(buffer)),
|
|
|
isRTL = false;
|
|
|
if (el.dir == "rtl" || opts.numericInput) {
|
|
|
el.dir = "ltr"
|
|
|
@@ -699,6 +700,7 @@
|
|
|
if (selectedCaret.begin == selectedCaret.end) {
|
|
|
var clickPosition = selectedCaret.begin;
|
|
|
lastPosition = checkVal(input, buffer, false);
|
|
|
+ determineInputDirection(input, selectedCaret);
|
|
|
if (isRTL)
|
|
|
caret(input, clickPosition > lastPosition && (isValid(clickPosition, buffer[clickPosition], buffer, true) !== false || !isMask(clickPosition)) ? clickPosition : lastPosition);
|
|
|
else
|
|
|
@@ -833,16 +835,26 @@
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ function determineInputDirection(input, pos) {
|
|
|
+ //set input direction according the position to the radixPoint
|
|
|
+ if (opts.numericInput && opts.radixPoint != "") {
|
|
|
+ var nptStr = input._valueGet();
|
|
|
+ var radixPosition = nptStr.indexOf(opts.radixPoint);
|
|
|
+ isRTL = pos.begin <= radixPosition || pos.end <= radixPosition || radixPosition == -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
//shift chars to left from start to end and put c at end position if defined
|
|
|
function shiftL(start, end, c) {
|
|
|
while (!isMask(start) && start - 1 >= 0) start--;
|
|
|
- for (var i = start; i < end && i < getMaskLength() ; i++) {
|
|
|
+ for (var i = start; i < end && i < getMaskLength(buffer) ; i++) {
|
|
|
if (isMask(i)) {
|
|
|
setReTargetPlaceHolder(buffer, i);
|
|
|
var j = seekNext(buffer, i);
|
|
|
var p = getBufferElement(buffer, j);
|
|
|
if (p != getPlaceHolder(j)) {
|
|
|
- if (j < getMaskLength() && isValid(i, p, buffer, true) !== false && tests[determineTestPosition(i)].def == tests[determineTestPosition(j)].def) {
|
|
|
+ if (j < getMaskLength(buffer) && isValid(i, p, buffer, true) !== false && tests[determineTestPosition(i)].def == tests[determineTestPosition(j)].def) {
|
|
|
setBufferElement(buffer, i, getBufferElement(buffer, j));
|
|
|
setReTargetPlaceHolder(buffer, j); //cleanup next position
|
|
|
} else {
|
|
|
@@ -863,13 +875,13 @@
|
|
|
return start; //return the used start position
|
|
|
}
|
|
|
function shiftR(start, end, c, full) { //full => behave like a push right ~ do not stop on placeholders
|
|
|
- for (var i = start; i <= end && i < getMaskLength() ; i++) {
|
|
|
+ for (var i = start; i <= end && i < getMaskLength(buffer) ; i++) {
|
|
|
if (isMask(i)) {
|
|
|
var t = getBufferElement(buffer, i);
|
|
|
setBufferElement(buffer, i, c);
|
|
|
if (t != getPlaceHolder(i)) {
|
|
|
var j = seekNext(buffer, i);
|
|
|
- if (j < getMaskLength()) {
|
|
|
+ if (j < getMaskLength(buffer)) {
|
|
|
if (isValid(j, t, buffer, true) !== false && tests[determineTestPosition(i)].def == tests[determineTestPosition(j)].def)
|
|
|
c = t;
|
|
|
else {
|
|
|
@@ -895,44 +907,54 @@
|
|
|
|
|
|
var input = this, k = e.keyCode, pos = caret(input);
|
|
|
|
|
|
- //set input direction according the position to the radixPoint
|
|
|
- if (opts.numericInput && opts.radixPoint != "") {
|
|
|
- var nptStr = input._valueGet();
|
|
|
- var radixPosition = nptStr.indexOf(opts.radixPoint);
|
|
|
- if (radixPosition != -1) {
|
|
|
- isRTL = pos.begin <= radixPosition || pos.end <= radixPosition;
|
|
|
- }
|
|
|
- }
|
|
|
+ determineInputDirection(input, pos);
|
|
|
|
|
|
//backspace, delete, and escape get special treatment
|
|
|
if (k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE || (iphone && k == 127)) {//backspace/delete
|
|
|
- var maskL = getMaskLength();
|
|
|
- if (pos.begin == 0 && pos.end == maskL) {
|
|
|
+ var maskL = getMaskLength(buffer);
|
|
|
+ if (pos.begin == 0 && pos.end == maskL) { //remove full selection
|
|
|
buffer = _buffer.slice();
|
|
|
writeBuffer(input, buffer);
|
|
|
caret(input, checkVal(input, buffer, false));
|
|
|
- } else if ((pos.end - pos.begin) > 1 || ((pos.end - pos.begin) == 1 && opts.insertMode)) {
|
|
|
+ } else if ((pos.end - pos.begin) > 1 || ((pos.end - pos.begin) == 1 && opts.insertMode)) { //partial selection
|
|
|
clearBuffer(buffer, pos.begin, pos.end);
|
|
|
writeBuffer(input, buffer);
|
|
|
caret(isRTL ? checkVal(input, buffer, false) : pos.begin);
|
|
|
- } else {
|
|
|
- var beginPos = pos.begin - (k == opts.keyCode.DELETE ? 0 : 1);
|
|
|
- if (beginPos < firstMaskPos && k == opts.keyCode.DELETE) {
|
|
|
- beginPos = firstMaskPos;
|
|
|
- }
|
|
|
- if (beginPos >= firstMaskPos) {
|
|
|
- if (opts.numericInput && opts.greedy && k == opts.keyCode.DELETE && buffer[beginPos] == opts.radixPoint) {
|
|
|
- beginPos = seekNext(buffer, beginPos);
|
|
|
- isRTL = false;
|
|
|
- } else if (opts.numericInput && opts.greedy && k == opts.keyCode.BACKSPACE && buffer[beginPos] == opts.radixPoint) {
|
|
|
- beginPos--;
|
|
|
- isRTL = true;
|
|
|
+ } else { //handle delete
|
|
|
+ var beginPos = pos.begin;
|
|
|
+ if (k == opts.keyCode.DELETE) {
|
|
|
+ if (beginPos < firstMaskPos)
|
|
|
+ beginPos = firstMaskPos;
|
|
|
+ if (beginPos < maskL) {
|
|
|
+ if (opts.numericInput && opts.radixPoint != "" && buffer[beginPos] == opts.radixPoint) {
|
|
|
+ beginPos = seekNext(buffer, beginPos);
|
|
|
+ beginPos = shiftL(beginPos, maskL);
|
|
|
+ } else {
|
|
|
+ if (isRTL) {
|
|
|
+ beginPos = shiftR(firstMaskPos, beginPos, getPlaceHolder(beginPos), true);
|
|
|
+ beginPos = seekNext(buffer, beginPos);
|
|
|
+ } else {
|
|
|
+ beginPos = shiftL(beginPos, maskL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ writeBuffer(input, buffer, beginPos);
|
|
|
+ }
|
|
|
+ } else if (k == opts.keyCode.BACKSPACE) { //handle backspace
|
|
|
+ if (beginPos > firstMaskPos) {
|
|
|
+ beginPos -= 1;
|
|
|
+ if (opts.numericInput && opts.radixPoint != "" && buffer[beginPos] == opts.radixPoint) {
|
|
|
+ beginPos = shiftR(firstMaskPos, beginPos - 1, getPlaceHolder(beginPos), true);
|
|
|
+ beginPos++;
|
|
|
+ } else {
|
|
|
+ if (isRTL) {
|
|
|
+ beginPos = shiftR(firstMaskPos, beginPos, getPlaceHolder(beginPos), true);
|
|
|
+ beginPos = buffer[beginPos + 1] == opts.radixPoint ? beginPos + 1 : seekNext(buffer, beginPos);
|
|
|
+ } else {
|
|
|
+ beginPos = shiftL(beginPos, maskL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ writeBuffer(input, buffer, beginPos);
|
|
|
}
|
|
|
- if (isRTL) {
|
|
|
- beginPos = shiftR(firstMaskPos, beginPos, getPlaceHolder(beginPos), true);
|
|
|
- beginPos = (opts.numericInput && opts.greedy && k == opts.keyCode.BACKSPACE && buffer[beginPos + 1] == opts.radixPoint) ? beginPos + 1 : seekNext(buffer, beginPos);
|
|
|
- } else beginPos = shiftL(beginPos, maskL);
|
|
|
- writeBuffer(input, buffer, beginPos);
|
|
|
}
|
|
|
}
|
|
|
if (input._valueGet() == _buffer.join(''))
|
|
|
@@ -942,7 +964,7 @@
|
|
|
} else if (k == opts.keyCode.END || k == opts.keyCode.PAGE_DOWN) { //when END or PAGE_DOWN pressed set position at lastmatch
|
|
|
setTimeout(function () {
|
|
|
var caretPos = checkVal(input, buffer, false, true);
|
|
|
- if (!opts.insertMode && caretPos == getMaskLength() && !e.shiftKey) caretPos--;
|
|
|
+ if (!opts.insertMode && caretPos == getMaskLength(buffer) && !e.shiftKey) caretPos--;
|
|
|
caret(input, e.shiftKey ? pos.begin : caretPos, caretPos);
|
|
|
}, 0);
|
|
|
} else if (k == opts.keyCode.HOME || k == opts.keyCode.PAGE_UP) {//Home or page_up
|
|
|
@@ -953,7 +975,7 @@
|
|
|
caret(input, 0, checkVal(input, buffer));
|
|
|
} else if (k == opts.keyCode.INSERT) {//insert
|
|
|
opts.insertMode = !opts.insertMode;
|
|
|
- caret(input, !opts.insertMode && pos.begin == getMaskLength() ? pos.begin - 1 : pos.begin);
|
|
|
+ caret(input, !opts.insertMode && pos.begin == getMaskLength(buffer) ? pos.begin - 1 : pos.begin);
|
|
|
} else if (e.ctrlKey && k == 88) {
|
|
|
setTimeout(function () {
|
|
|
caret(input, checkVal(input, buffer, true));
|
|
|
@@ -961,7 +983,7 @@
|
|
|
} else if (!opts.insertMode) { //overwritemode
|
|
|
if (k == opts.keyCode.RIGHT) {//right
|
|
|
var caretPos = pos.begin == pos.end ? pos.end + 1 : pos.end;
|
|
|
- caretPos = caretPos < getMaskLength() ? caretPos : pos.end;
|
|
|
+ caretPos = caretPos < getMaskLength(buffer) ? caretPos : pos.end;
|
|
|
caret(input, e.shiftKey ? pos.begin : caretPos, e.shiftKey ? caretPos + 1 : caretPos);
|
|
|
} else if (k == opts.keyCode.LEFT) {//left
|
|
|
var caretPos = pos.begin - 1;
|
|
|
@@ -983,12 +1005,12 @@
|
|
|
|
|
|
e = e || window.event;
|
|
|
var k = e.which || e.charCode || e.keyCode,
|
|
|
- c = String.fromCharCode(k);
|
|
|
+ c = String.fromCharCode(k);
|
|
|
|
|
|
if (opts.numericInput && c == opts.radixPoint) {
|
|
|
var nptStr = input._valueGet();
|
|
|
var radixPosition = nptStr.indexOf(opts.radixPoint);
|
|
|
- caret(input, seekNext(buffer, radixPosition != -1 ? radixPosition : getMaskLength()));
|
|
|
+ caret(input, seekNext(buffer, radixPosition != -1 ? radixPosition : getMaskLength(buffer)));
|
|
|
}
|
|
|
|
|
|
if (e.ctrlKey || e.altKey || e.metaKey || ignorable) {
|
|
|
@@ -997,7 +1019,7 @@
|
|
|
if (k) {
|
|
|
$input.trigger('input');
|
|
|
|
|
|
- var pos = caret(input), maskL = getMaskLength(), writeOutBuffer = true;
|
|
|
+ var pos = caret(input), maskL = getMaskLength(buffer), writeOutBuffer = true;
|
|
|
clearBuffer(buffer, pos.begin, pos.end);
|
|
|
|
|
|
if (isRTL) {
|
|
|
@@ -1007,6 +1029,7 @@
|
|
|
p = np.pos != undefined ? np.pos : p; //set new position from isValid
|
|
|
c = np.c != undefined ? np.c : c; //set new char from isValid
|
|
|
}
|
|
|
+ maskL = getMaskLength(buffer); //update masklength to include possible groupSeparator offset
|
|
|
|
|
|
var firstUnmaskedPosition = firstMaskPos;
|
|
|
if (opts.insertMode == true) {
|
|
|
@@ -1044,7 +1067,7 @@
|
|
|
c = np.c != undefined ? np.c : c; //set new char from isValid
|
|
|
}
|
|
|
if (opts.insertMode == true) {
|
|
|
- var lastUnmaskedPosition = getMaskLength();
|
|
|
+ var lastUnmaskedPosition = getMaskLength(buffer);
|
|
|
var bfrClone = buffer.slice();
|
|
|
while (getBufferElement(bfrClone, lastUnmaskedPosition, true) != getPlaceHolder(lastUnmaskedPosition) && lastUnmaskedPosition >= p) {
|
|
|
lastUnmaskedPosition = lastUnmaskedPosition == 0 ? -1 : seekPrevious(buffer, lastUnmaskedPosition);
|