DEV Community

Idris Gadi
Idris Gadi

Posted on

Beyond Basics: Handling Numeric Inputs Like a Pro with `<input type="number">`

What is <input type="number">

According to MDN Docs Definition: <input> elements of type number are used to let the user enter a number. They include built-in validation to reject non-numerical entries.

So basically, it is a feature for enhancing User Experience on our crappy websites and web apps. While it is a nice feature for simplifying numeric inputs, it has a couple of behaviors that might not be obvious at first but we should be aware of as a web developer.

These behaviors are related to:

  1. Virtual Keyboard
  2. Scientific Notations

Virtual Keyboard

A virtual keyboard is a keyboard that appears on your screen, usually in touch input devices like mobile phones, tablets/ipads and some assistive technologies.

<input id="numeric-input" type="number" >
Enter fullscreen mode Exit fullscreen mode

Just using the type="number" might seem all right at first, but it has an issue when using a virtual keyboard. It might open a full-key keyboard instead of a numeric keyboard, which can hurt user experience and input accuracy.

A Gif demonstrating that input number can lead to full-key keyboard

Solution inputmode

While the virtual keyboard issue might not occur on newer OS and browser versions, it is still a good idea to use the inputmode attribute as it hints at the type of data that might be entered by the user while editing the element or its contents.
This allows browsers to display an appropriate virtual keyboard for all versions and devices, improving the application's overall user experience (UX).

inputmode can have many values, but for our use case with numeric inputs we should use one of these two values:
1.numeric

<input id="numeric-input" type="number" inputmode="numeric" >
Enter fullscreen mode Exit fullscreen mode

The input type number accepts any rational value. If you are not accepting fractional values and only accepting whole numbers, using a numeric value should be preferred for such scenarios.

2.decimal

<input id="numeric-input" type="number" inputmode="decimal" >
Enter fullscreen mode Exit fullscreen mode

If you are accepting fractional numbers, use decimal value as it will show a virtual keyboard containing the digits and decimal separator for the user's locale.

Always prefer using decimal value in your input unless you are not accepting fractional values.

A Gif demonstrating input type number with input mode of decimal

Scientific Notations

Many of us might have forgotten or not know that e or E are valid numeric values in scientific notations.

what meme

Yes, e or E means "exponent of ten" in scientific notations, and is used to represent very large or small values. e.g.

1e5 = 100000 
     or 
1e-5 = 0.00001
Enter fullscreen mode Exit fullscreen mode

The HTML input type number was designed with flexibility in mind, and it supports this scientific notation, allowing for the entry of exponents (e.g., 1e5). While this is not an issue in itself and can be useful in some contexts, it can become problematic when the input should only consist of basic numbers.

There are two ways to restrict the input to only numbers and not allow the scientific notations.

  1. Using Regex 🤮 pattern.
  2. Using Javascript (my preferred method).

Preventing Default Behaviour Using Javascript

In most scenarios, I don't want the users to enter the 'e' or 'E' notations, as they aren't needed, and allowing them can cause some unexpected issues.

There are many ways of achieving this, but my favorite method is to prevent the 'e' or 'E' key from being registered. We can achieve this using the keydown event and preventDefault.

 element.addEventListener("keydown", (e) => {
    if (["e", "E"].includes(e.key)) {
      // you can also add "+" and "-" if you want to prevent them from being registered.
      e.preventDefault();
    }
  });
Enter fullscreen mode Exit fullscreen mode

I particularly like this method because of three reasons:

  • It provides a clear message to anyone reading our code later that we don't want to register the e or E keys.
  • It also allows for a better UX because instead of changing the values we are not registering the key itself.
  • The type of keydown event is KeyboardEvent which gives us direct access to the key values improving the overall DX of the solution.

Not All Numeric Input Needs to be Input Type Number

Sometimes we can instinctively reach for an input type number if we see an input requirement that accepts numeric input but sometimes input type number is not the right solution for such scenarios.

A few examples of such scenarios are:

  • Credit Card/Debit Card: When we have an input field for Credit/Debit Card, instead of using input type number it is better to use input type text with input mode of numeric and validation using your preferred method, as a credit card can have leading zero values and some browsers might not allow that, also we might want to add some card specific validations or allow spacing between a group of four numbers (as it is printed on the card).

  • Postal Code: While most countries have numeric postal codes, some countries like Canada could have alphanumeric codes, it is important to use solutions according to your need, it could be of input type number or input type text.

  • Mobile Numbers: You should always use the input type of input="tel" with a regex pattern suitable for your use case.

Conclusion

Since modern HTML provides some really nice utilities, some things might feel very trivial to implement like input type number, however as developers, we should always pay attention to these utilities and how we can utilize them to create even better user experiences.

If you liked this article please leave a reaction and if you disliked something you can leave your feedback in the comments.

I like to connect and talk with people about tech and the events surrounding it. You can connect with me on Twitter/X and LinkedIn.

You can also follow me on Dev.to to get a notification whenever I publish a new article.

Top comments (0)