Reputation: 11
This angular directive auto-inserts commas every three digits in number input fields (e.g. "1000" becomes "1,000"). It preserves cursor position correctly in all browsers I have tested, except on Samsung phones with the Samsung keyboard, for example the Galaxy S8 running Android 7.0, Samsung experience version 8.1.
On Samsung, if I type "1000", the comma is inserted, and my cursor ends up between the tens and ones position, when it should be all the way to the right.
Is there any known fix for this issue?
angular.module('someWebApp')
.directive('commaInput', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModelController) {
var el = element[0];
function clean(x) {
while (x.toString().indexOf(",") != -1)
{
x = x.replace(",", "");
}
return x.replace(/\B(?=(?:\d{3})+(?!\d))/g, ",");
}
ngModelController.$parsers.push(function(val) {
var cleaned = clean(val);
// Avoid infinite loop of $setViewValue <-> $parsers
if (cleaned === val) return val;
var start = el.selectionStart + cleaned.length - val.length;
var end = el.selectionEnd + cleaned.length - val.length;
// element.val(cleaned) does not behave with
// repeated invalid elements
ngModelController.$setViewValue(cleaned);
ngModelController.$render();
el.setSelectionRange(start, end);
return cleaned;
});
}
}
});
The html input uses this directive (comma-input) and has type="tel".
Upvotes: 1
Views: 219
Reputation: 412
This really seems to be a problem with some devices. I had a simmilar problem on a Samsung S7 device. My only solution which worked was pushing the setSelectionRange()
method into a setTimeout().
setTimeout(() => {
el.setSelectionRange(selStart, selEnd);
});
The millisecond
param on the setTimeout method can be omitted as we don't need to wait before execution.
Upvotes: 0