Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 596
Ernesto Schiavo Avatar asked Feb 07 '17 14:02

Ernesto Schiavo


People also ask

Which is type of key event * Onkeypress Onkeydown onKeyUp all of the above?

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

What does Onkeydown mean?

The onkeydown attribute fires when the user is pressing a key (on the keyboard).

What is the difference between Keyup and keypress?

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.


2 Answers

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);
        }
    });
}
like image 74
Zoryana Avatar answered Nov 02 '22 13:11

Zoryana


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

like image 20
Maxim Shoustin Avatar answered Nov 02 '22 13:11

Maxim Shoustin