javascripthtmllisteners

eventListener keypress does not work correcly for the <input>


I understand that using an keypress eventlistener for the keystrokes in an element of the input is pure madness. But I personally want to understand for myself what is I'm doing wrong in this case.

The objective of the code - is to allow only numbers to be displayed in the field input, prohibiting the appearance of letters, as well as the use of keyboard combinations (alt, shift, etc).

	function onDown(e) {
	  e = e || event;

	  if (e.ctrlKey || e.altKey || e.metaKey) return; // false for key cominations

	  var chr = getChar(e);

	  if (chr == null) return;

	  if (chr < '0' || chr > '9') { // if "chr" do not a digit - false
	    return false;
	  }
	}

	function getChar(event) { // support func to get the char from keyCode
		 if (event.which == null) { 
		   if (event.keyCode < 32) return null; 
		   return String.fromCharCode(event.keyCode)
		 }

		 if (event.which != 0 && event.charCode != 0) { 
		   if (event.which < 32) return null; 
		   return String.fromCharCode(event.which);
		 }

		 return null; 
	}

	inp.addEventListener( 'keypress', onDown );
	<input type="text"  id="inp">


Solution

  • You need to call e.preventDefault(); when the entered value is not a number.

    function onDown(e) {
      e = e || event;
      if (e.ctrlKey || e.altKey || e.metaKey) return; // false for key cominations
    
      var chr = getChar(e);
      if (chr == null) return;
    
      if (chr < '0' || chr > '9') { // if "chr" do not a digit - false
        e.preventDefault();
      }
    }
    
    function getChar(event) { // support func to get the char from keyCode
      if (event.which == null) {
        if (event.keyCode < 32) return null;
        return String.fromCharCode(event.keyCode)
      }
    
      if (event.which != 0 && event.charCode != 0) {
        if (event.which < 32) return null;
        return String.fromCharCode(event.which);
      }
    
      return null;
    }
    
    inp.addEventListener('keypress', onDown);
    <input type="text" id="inp">