1

I'm having problems with an input type number in HTML5 combining it with an oninput event to have an optional max length qith an optional n max decimals in it. I have the following example code:

<input type="number" name="name" step="any"
oninput=" this.value = (this.value.length > 8) ? this.value.slice(0,8) : this.value; /^[0-9]+(.[0-9]{1,3})?$/.test(this.value) ? this.value : this.value = this.value.slice(0,-1); ">

It works fine except that when a dot is pressed down it removes the entire number without any kind of error. It works with ',' but on mobile I will need the '.' for keyboard purposes. (I need that works too like now with ',')

CVO
  • 702
  • 1
  • 13
  • 31
  • `/^[0-9]+(\.[0-9]{1,3})?$/` –  Apr 02 '19 at 15:35
  • 1
    Please set up your code in a stackoverflow snippet so that everyone can see the problem you describe and directly work on it. – sjahan Apr 02 '19 at 15:35
  • 1
    But `/^[0-9]+(\.[0-9]{0,3})?$/` works better. –  Apr 02 '19 at 15:39
  • Thanks and sorry I have just updated it. I have the same problem with those 2 regex – CVO Apr 02 '19 at 15:42
  • however will work better than my regex, but still having the problem pressing dot. I don't really know if is a regex problem, because on chrome console it works fine /^[0-9]+(\.[0-9]{0,3})?$/.test('1.23') – CVO Apr 02 '19 at 15:48

2 Answers2

2

Your main problem is your text disappearing if you enter a non-numeric character. (Depending on your browsers localization settings, a dot could be considered non-numeric.) The problem is that entering a non-numeric value puts the element into an invalid state, and the element's value cannot be retrieved.

Fortunately, HTML can do this validation by itself, using the step attribute. You don't get the satisfaction of bad characters being immediately erased, but the input will show as invalid once it loses focus. And if needed, you can set custom error messages for the element.

<input
    id="identification"
    type="number"
    name="name"
    step="0.001"
    min="0"
    max="99999999"
/>
miken32
  • 42,008
  • 16
  • 111
  • 154
  • Lot of thanks. That works fine and probably could be a best practice, but I wanted to avoid accidentally inputs and have it visible before validation on submit form. This way could be interesting for me in some cases, but in this one I need that step aplies 1 whole number each time. (I would like to be able to accept both answers) – CVO Apr 03 '19 at 07:52
1

Since you only want to control the length of the total number and of its decimal part, I would recommend the keydown event instead of the input event. The following expression

<input type="number" name="name" step="any" onkeydown=
"return event.keyCode<32 || this.value.length<8 && /^\d*([.,]\d{0,2})?$/.test(this.value)"
>
  • suppresses input if more than 8 characters
  • suppresses input if more than 3 decimals are entered
  • allows special keys like backspace
  • disallows non-numeric input (automatic by type="number")
rplantiko
  • 2,698
  • 1
  • 22
  • 21
  • 1
    What if you want to paste something into the field? – miken32 Apr 02 '19 at 22:33
  • 1
    @miken32 You are right: one could extend the condition to allow key codes like Ctrl+V, but one could paste via context menu as well. So if it's just about restricting the number of digits and decimal places, the `min, `max`and `step` attributes of the html input element are to prefer over any javascript solution. – rplantiko Apr 03 '19 at 05:24
  • Lots of thanks. This solution works perfect for me. I have no problems when paste because I validate all fields on submit form so with this method I can restrict accidentally bad inputs and ensure that the value is correct when submit (with an extra validation on server side to avoid that any user could change the code on browser) – CVO Apr 03 '19 at 07:49