Home » Android » javascript – Event listeners (onkeypress, onkeydown) on input not working in Android numeric keyboard

javascript – Event listeners (onkeypress, onkeydown) on input not working in Android numeric keyboard

Posted by: admin June 15, 2020 Leave a comment

Questions:

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:

  • 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.

How to&Answers:

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

Answer:

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);
        }
    });
}

Answer:

use inputType=”numberSigned” it will provide you only numbers between 0-9 , atleast in native android it works flawlessly.