Skip to content

Commit 32f93ec

Browse files
author
Igor Escobar
authored
Merge pull request igorescobar#556 from onuradsay/master
Fix cursor position
2 parents f6d0afa + 824c8f9 commit 32f93ec

File tree

1 file changed

+79
-23
lines changed

1 file changed

+79
-23
lines changed

src/jquery.mask.js

Lines changed: 79 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@
100100
.on('keydown.mask', function(e) {
101101
el.data('mask-keycode', e.keyCode || e.which);
102102
el.data('mask-previus-value', el.val());
103+
el.data('mask-previus-caret-pos', p.getCaret());
104+
p.maskDigitPosMapOld = p.maskDigitPosMap;
103105
})
104106
.on($.jMaskGlobals.useInput ? 'input.mask' : 'keyup.mask', p.behaviour)
105107
.on('paste.mask drop.mask', function() {
@@ -186,26 +188,66 @@
186188

187189
return r;
188190
},
189-
calculateCaretPosition: function(caretPos, newVal) {
190-
var newValL = newVal.length,
191-
oValue = el.data('mask-previus-value') || '',
192-
oValueL = oValue.length;
193-
194-
// edge cases when erasing digits
195-
if (el.data('mask-keycode') === 8 && oValue !== newVal) {
196-
caretPos = caretPos - (newVal.slice(0, caretPos).length - oValue.slice(0, caretPos).length);
197-
198-
// edge cases when typing new digits
199-
} else if (oValue !== newVal) {
200-
// if the cursor is at the end keep it there
201-
if (caretPos >= oValueL) {
202-
caretPos = newValL;
203-
} else {
204-
caretPos = caretPos + (newVal.slice(0, caretPos).length - oValue.slice(0, caretPos).length);
191+
calculateCaretPosition: function() {
192+
var oldVal = el.data('mask-previus-value') || '',
193+
newVal = p.getMasked(),
194+
caretPosNew = p.getCaret();
195+
if (oldVal !== newVal) {
196+
var caretPosOld = el.data('mask-previus-caret-pos') || 0,
197+
newValL = newVal.length,
198+
oldValL = oldVal.length,
199+
maskDigitsBeforeCaret = 0,
200+
maskDigitsAfterCaret = 0,
201+
maskDigitsBeforeCaretAll = 0,
202+
maskDigitsBeforeCaretAllOld = 0,
203+
i = 0;
204+
205+
for (i = caretPosNew; i < newValL; i++) {
206+
if (!p.maskDigitPosMap[i]) {
207+
break;
208+
}
209+
maskDigitsAfterCaret++;
210+
}
211+
212+
for (i = caretPosNew - 1; i >= 0; i--) {
213+
if (!p.maskDigitPosMap[i]) {
214+
break;
215+
}
216+
maskDigitsBeforeCaret++;
217+
}
218+
219+
for (i = caretPosNew - 1; i >= 0; i--) {
220+
if (p.maskDigitPosMap[i]) {
221+
maskDigitsBeforeCaretAll++;
222+
}
223+
}
224+
225+
for (i = caretPosOld - 1; i >= 0; i--) {
226+
if (p.maskDigitPosMapOld[i]) {
227+
maskDigitsBeforeCaretAllOld++;
228+
}
205229
}
206-
}
207230

208-
return caretPos;
231+
if (caretPosNew > oldValL) {
232+
// if the cursor is at the end keep it there
233+
caretPosNew = newValL;
234+
}
235+
else if (caretPosOld >= caretPosNew && caretPosOld !== oldValL) {
236+
if (!p.maskDigitPosMapOld[caretPosNew]) {
237+
var caretPos = caretPosNew;
238+
caretPosNew -= maskDigitsBeforeCaretAllOld - maskDigitsBeforeCaretAll;
239+
caretPosNew -= maskDigitsBeforeCaret;
240+
if (p.maskDigitPosMap[caretPosNew]) {
241+
caretPosNew = caretPos;
242+
}
243+
}
244+
}
245+
else if (caretPosNew > caretPosOld) {
246+
caretPosNew += maskDigitsBeforeCaretAll - maskDigitsBeforeCaretAllOld;
247+
caretPosNew += maskDigitsAfterCaret;
248+
}
249+
}
250+
return caretPosNew;
209251
},
210252
behaviour: function(e) {
211253
e = e || window.event;
@@ -217,9 +259,9 @@
217259
var newVal = p.getMasked(),
218260
caretPos = p.getCaret();
219261

220-
setTimeout(function(caretPos, newVal) {
221-
p.setCaret(p.calculateCaretPosition(caretPos, newVal));
222-
}, 10, caretPos, newVal);
262+
setTimeout(function() {
263+
p.setCaret(p.calculateCaretPosition());
264+
}, 10);
223265

224266
p.val(newVal);
225267
p.setCaret(caretPos);
@@ -233,6 +275,8 @@
233275
v = 0, valLen = value.length,
234276
offset = 1, addMethod = 'push',
235277
resetPos = -1,
278+
maskDigitCount = 0,
279+
maskDigitPosArr = [],
236280
lastMaskChar,
237281
check;
238282

@@ -277,6 +321,7 @@
277321
// matched the last untranslated (raw) mask character that we encountered
278322
// likely an insert offset the mask character from the last entry; fall
279323
// through and only increment v
324+
maskDigitCount--;
280325
lastUntranslatedMaskChar = undefined;
281326
} else if (translation.optional) {
282327
m += offset;
@@ -295,9 +340,12 @@
295340
}
296341

297342
if (valDigit === maskDigit) {
343+
maskDigitPosArr.push(v);
298344
v += offset;
299345
} else {
300346
lastUntranslatedMaskChar = maskDigit;
347+
maskDigitPosArr.push(v + maskDigitCount);
348+
maskDigitCount++;
301349
}
302350

303351
m += offset;
@@ -309,7 +357,16 @@
309357
buf.push(lastMaskCharDigit);
310358
}
311359

312-
return buf.join('');
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+
}
313370
},
314371
callbacks: function (e) {
315372
var val = p.val(),
@@ -538,4 +595,3 @@
538595
}
539596
}, globals.watchInterval);
540597
}, window.jQuery, window.Zepto));
541-

0 commit comments

Comments
 (0)