HTML vs. JavaScript Input Validation

If you want to validate a form input and so it only accepts integers, here is an easy way in HTML5:

<input type="number" pattern="[0-9]*" />

However, users can still type something invalid:

  1. In Firefox, you can basically type anything, like "fsielfs".
  2. In Chrome, you can type numbers with dots, like "1..2.2.2".

The input will have error appearance. But if you override the default appearance, you have to style it with :invalid selector:

input[type="number"]:invalid {
  border-color: red;
}

But for JavaScript, it is almost a black box:

  1. It won't trigger change event.
  2. value property is empty.
  3. validity property only provides a couple of boolean flags.

So JavaScript can neither know what the user inputs or correct them. Why?

By specifying type="number" and pattern="[0-9]*", you leave the validation job to browser. When the input value is invalid, it will urge users to correct them. JavaScript can know the input is invalid by checking e.target.validity. However, it won't tell JavaScript more details. HTML form validation is very friendly for screen reader and it is easy to implement. It is already a part of web standard. All these cannot be easily achieved by JavaScript-only form validation.

But if we still want to validate and filter the input with JavaScript…

Solution 1: use type="text".

Now you can capture every character that is typed. You can validate e.target.value in change event and filter out anything that you don't like. This is for sure the most powerful yet easy solution.

The disadvantage is that, when users typing in mobile devices, the normal keyboard will pop up instead the convenient number keyboard.

Solution 2: listen to input event.

Unlike change event, input event will be triggered whenever the content of input box is modified. You can check the content in e.data and store it.

The disadvantage is that, you don't know where the cursor is. When users type something, you know what they typed but not where they inserted these content. When users hit backspace or delete key, you won't know how many characters they deleted and where they deleted these characters. So you should know it is not 100% reliable.

In some cases, you can combine it with change event. You store every valid state. If something invalid was input, revert to previous state. However, not every input is always valid during typing. Email address is a good example.

Note: you should not use keydown or keyup because the input may from clipboard, voice control or virtual keyboard, which doesn't trigger keydown or keyup events.

In conclusion, yes, you can do JavaScript-only form validation, but I won't recommend it. Both solutions I write above have their limitations and are against the principles of web standard. Combining both HTML and JavaScript form validation can bring you a much better result.

Leave a Reply

Your email address will not be published. Required fields are marked *