0

I have an input field which I want to restrict to only input numbers. type="number" works fine on computer and my android mobile but fails on iOS and I can still enter text in it. I looked around online and found this solution for the input field:

<input onkeypress="return event.charCode >= 48 && event.charCode <= 57" id="priceInput" type="text">

It works on all devices I have tried so far. However, I want to use this code for many input fields, and also do more things when pressing on a key in those input field. Therefore I want to run it as a JavaScript function in a separate file. I found this answer which looked promising and worked for android and desktop:

function isNumber(evt) {
    evt = (evt) ? evt : window.event;
    var charCode = (evt.which) ? evt.which : evt.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57)) {
        return false;
    }
    return true;
}
<input type="text" onkeypress="return isNumber(event)" />

However, this still fails on iOS and I can still put in all characters.

Questions

  1. How can I limit input field to only accept numbers on iOS phones?
  2. Do iOS have some blocker for functions to run on onkeypress?
eligolf
  • 1,682
  • 1
  • 6
  • 22
  • just a suggestion here since I cannot test it.. did you try to add `event.preventDefault()` before returning false? – Diego D Jan 23 '23 at 08:25
  • @DiegoD, Good question, yes I did since I found it in another answer. No difference – eligolf Jan 23 '23 at 08:27
  • why not use pattern attribute? – Burham B. Soliman Jan 23 '23 at 08:27
  • @BurhamB.Soliman, why not show me what that is? :)) – eligolf Jan 23 '23 at 08:29
  • @eligolf I think he was referring to something like `` that on ios will trigger the virtual keyboard with numbers only but yet I don't think it would be a reliable solution. Probably the given answer given is going to work consistently in any scenario. – Diego D Jan 23 '23 at 08:37
  • @DiegoD, Ah I see! Could you elaborate on why it is not reliable? Because it seems like a nice way to avoid calling a JS function. – eligolf Jan 23 '23 at 08:40
  • because you could for example attach a physical keyboard via bluetooth to the iphone and you won't be restricted by the virtual keyboard. https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern it's not expected to ***prevent*** you from typing but to give a validation criteria. While the first given answer stated that those properties you are trying to fetch from the `event` are deprecated and were suggested instead which ones are now supported (included by iOS). Your approach is different.. you're strictly preventing typing some chars – Diego D Jan 23 '23 at 08:43
  • @DiegoD, thanks for the explanation. Yes I need to restrict the input value/innerHTML of the input field to get any other things than numbers. I will try some approach from the answers – eligolf Jan 23 '23 at 09:04
  • @eligolf as said, it will just fire a numbers keyboard instead of full keyboard, so the user will use numbers only, and about the physical keyboard scenario, you can restrict the submit using js validation in case the input text is not correct, it will turn the textbox outline to red and prevent submission, – Burham B. Soliman Jan 23 '23 at 14:15

2 Answers2

1

The snippet you find is quite old and uses the which and keyCode properties, which both are deprecated.

Instead use the code and / or key properties to determine which keyboard button has been pressed.

Note: with this method you'll have to whitelist every key that you want to be enabled for the input.

Since you're using a text input, consider using the inputmode attribute to force mobile users to use a specific keyboard, like a numeric keyboard which presents numbers.

const input = document.querySelector('input');
input.addEventListener('keydown', isNumber);

const allowedKeys = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Backspace'];

function isNumber(event) {
  if (!allowedKeys.includes(event.key)) {
    event.preventDefault();
  }
}
<input type="text" inputmode="numeric" />

Edit: alternatively you could use the input event which is triggered based on changes in the value of the input. This event will fire regardless the manner of input (keyboard, mouse, etc.). The snippet below will replace anything that is not a number with an empty string while typing.

const input = document.querySelector('input');
input.addEventListener('input', isNumber);

function isNumber(event) {
  event.target.value = event.target.value.replace(/[^0-9]/g, '');
}
<input type="text" inputmode="numeric" />
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32
  • Without inputmode="numeric" I can still write letters on the phone, even on android. But on desktop it works as expected. Why? I haven't tried if inputmode="numeric" works on iOS (it's my friend who has iPhone), I will get back soon. Just curious why the JS alone doesn't solve it for this case. – eligolf Jan 23 '23 at 09:36
  • The first one worked with some tweaks, thank you! – eligolf Jan 23 '23 at 14:17
-1
function isNumber(e) {
    event = e.value;
    if(event = ""){
        console.log("empty")
    }


    return true;
}
<input type="text" onkeypress="return isNumber(event)" />
Usitha Indeewara
  • 870
  • 3
  • 10
  • 21