I don't know why, but after hours spent dealing with this I can say there's something wrong.
I have a simple input
<input type="number">
I want it to accept only numbers (digit [0-9]) and nothing more. In order to achieve this I added an event listener where I control the keycode of the event.
Nothing special and everything working on almost all platforms, problems comes with Android. Here the
type="number"
causes numeric keyboard to appear - and that's great - with also some other characters (comma, dot, hyphen...). When you press one of this special characters the behavior is strange:
What am I missing?
My environment is powerd by AngularJs so I setted up event listeners inside a directive. However doing same things with jQuery doesn't solve problems.
Someone can suggest to use a "$parsers" to push my custom value without unwanted characters. Anyway this doesn't work I guess because the type of the input is "number" and it expect only numbers (another way to say the browser on Android is doing something wrong..)
Here there's a working Fiddle, open it on Android.
The onKeyDown event is triggered when the user presses a key. The onKeyUp event is triggered when the user releases a key. The onKeyPress event is triggered when the user presses & releases a key ( onKeyDown followed by onKeyUp ).
The onkeydown attribute fires when the user is pressing a key (on the keyboard).
keypress Fires when an actual character is being inserted in, for instance, a text input. It repeats while the user keeps the key depressed. keyup Fires when the user releases a key, after the default action of that key has been performed.
The keypress
event isn't fired, only keydown
and keyup
. onkeydown
you're able to invoke the preventDefault()
method. But what to prevent? charCode
is always 0
and keyCode
is 229
. You should check all the input.
Something like this:
if(!event.charCode) {
this.removeInvalidChar();
return;
}
private removeInvalidChar(): void {
setTimeout(() => {
let input = this.control.control.value;
if (input) {
input.split('').forEach((char: string) => {
if (!this.pattern.test(char)) {
input = input.replace(char, '');
}
});
this.control.control.setValue(input);
}
});
}
What about this directive with $parsers.unshift
:
app.directive('format', ['$filter', '$window', function($filter, $window) {
return {
require: '?ngModel',
link: function(scope, elem, attrs, ctrl) {
if (!ctrl) return;
scope.plainNumber = scope.test+'';
ctrl.$parsers.unshift(function(viewValue) {
if(!viewValue){
viewValue = scope.plainNumber;
}
scope.plainNumber = viewValue.replace(/[^\d]/g, '');
elem.val(scope.plainNumber);
return scope.plainNumber;
});
}
};
}]);
And usage:
<input type="number" ng-model="test" format />
Demo Fiddle
Tested on Android
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With