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 es with Android. Here the
type="number"
causes numeric keyboard to appear - and that's great - with also some other characters (ma, dot, hyphen...). When you press one of this special characters the behavior is strange:
- onkeypress event: absolutely not firing (why???)
- onkeydown event: the event is firing and the relative function is called. The problem is that the browser has already typed the character (why??) so is not possible to call the "preventDefault" function of "event".
- on input event: the event is firing but "code" and "which" properties of "event" object are undefined. Moreover, like before, the browser has already typed the character.
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.
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 es with Android. Here the
type="number"
causes numeric keyboard to appear - and that's great - with also some other characters (ma, dot, hyphen...). When you press one of this special characters the behavior is strange:
- onkeypress event: absolutely not firing (why???)
- onkeydown event: the event is firing and the relative function is called. The problem is that the browser has already typed the character (why??) so is not possible to call the "preventDefault" function of "event".
- on input event: the event is firing but "code" and "which" properties of "event" object are undefined. Moreover, like before, the browser has already typed the character.
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.
Share edited Aug 11, 2019 at 8:32 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Feb 7, 2017 at 14:43 Ernesto SchiavoErnesto Schiavo 1,0602 gold badges14 silver badges36 bronze badges3 Answers
Reset to default 7The 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
use inputType="numberSigned" it will provide you only numbers between 0-9 , atleast in native android it works flawlessly.