https://stackoverflow.blog/2022/09/15/why-the-number-input-is-the-worst-input/
*
Essays, opinions, and advice on the act of computer programming from
Stack Overflow.
Search for: [ ] [Search]
Latest Newsletter Podcast Company
[090922-Stack-Overflow-Why-number-input-is-the-worst-input-1200x630]
code-for-a-living September 15, 2022
Why the number input is the worst input
Think that web form has got your number? If you used input type=
"number", you may be surprised to find that it doesn't.
Avatar for
Jared Toporek
I've been writing code for at least 15 years. While I've used a lot
of technologies and built a lot of stuff over the years, the thing I
have done the most is the front end, i.e. HTML, CSS, and JavaScript.
And of all the things I've built on the front end, the thing that
I've built most often is forms.
I won't pretend to be the expert on all things related to forms.
However I will say this: of all the difficult, unconventional, and
unusual requirements I've been asked to deliver over the past 15
years, most of those tasks revolved around building forms. Each one
presented a challenge that required some sort of out-of-the-box or
non-standard solution. I've learned a lot of ways to overcome those
challenges: what you should do, and more importantly, what you should
not do when trying to meet those challenges.
Of all the things that I've learned about what not to do, one of the
easiest and best pieces of advice I can share is this: unless the use
case is drop-dead simple, you should avoid using the number input.
I've seen so many forms that I felt compelled to build my own form
builder that could handle at least some of the more challenging
requests without the hassle of writing code from scratch every time.
Keenforms is a drag-and-drop form builder with a no-code rules
engine. It makes it easier to create dynamic and conditional
functionality without having to write code from scratch.
Recently I got some feedback about Keenforms, and the criticism I
heard the most was the fact that Keenforms does not use the .* We do have an input that's labeled as a number,
but when you add it to your form, it actually renders as .
*Please note that Keenforms actually does use the number input inside
our app. However, we only use it in the dashboard and for only the
simplest inputs.
The pro-number input crowd has legitimate concerns, primarily around
accessibility. A number input has native increment/decrement buttons.
It has built-in validation to verify it is a number. Certain mobile
devices will show a number keypad instead of the full keyboard,
making it easier to enter data. Using the number input makes it
easier for screen readers as well.
There were also some valid complaints about developers overusing
JavaScript (guilty!). I understand some people's aversion to
JavaScript. However those aforementioned forms that I've built with
those challenging requirements all required heavy use of JavaScript.
It's the only way to provide instant real-time feedback when creating
dynamic conditional logic. Keenforms relies heavily on JavaScript and
specifically React.
There are so many drawbacks related to number inputs when dealing
with complex and conditional logic, much of it related to JavaScript
issues, that for the past few years I've decided to avoid using it.
It should be noted I am not alone in the anti-number input camp. The
UK Government posted an article detailing some of the problems
related to the number input.
The thing is, the issues cited in that article weren't even the
primary reasons why I decided to avoid it. After receiving that
feedback on Keenforms, it occurred to me that there are quite a few
programmers out there who are completely unaware of the problems the
number input presents. The list isn't long, but the issues are rather
jaw-dropping. So here's a short list of all the horrible things about
the number input (at least the ones that I know about) that every
developer should know:
1. When the number input contains an invalid value and you retrieve
the value, you get a blank string.
2. Valid numbers include more than just digits (i.e,. scientific
notation like the letter e).
3. The min/max attributes can easily be bypassed.
4. Different browsers accept different characters.
When the number input contains an invalid value and you retrieve the
value, you get a blank string
There are a couple of ways you might go about retrieving the value.
It could be on an event listener, which would store the field value
in event.target.value. Or you could get it through the DOM element.
Either way when the number is invalid you can't get the actual value
that appears on screen in the field:
const numberInput = document.getElementById('id_here');
console.log(numberInput.value); // will return empty string if invalid
If you are building a form that requires conditional validations or
calculations, it is hard to understate just how big of a problem this
is. The fact that the number input will allow a user to enter an
invalid number value but not actually retrieve that invalid value
(getting a blank string instead), makes the kind of validation I
routinely get asked to deliver impossible.
If you are just using a number input for someone's age or the
quantity of a product, this might not seem like that big of a
problem. However, consider an example of a form I was tasked with
building where the number input either affects or is affected by
other inputs, such as a life insurance form with the following
requirements:
* A number input for the quantity of dependents. The number value
will determine the quantity of nested forms for each dependent.
* A number input for each household member that indicates the
percentage this person would receive in the event of a payout. If
the quantity of dependents is one, then this particular input
would be hidden and automatically set to 100. If the quantity is
greater than 1, then the input should be visible, and have a
value of no less than 0.01, and contain a value less than 100.
* A hidden number input that would sum total the percentage of each
dependent listed, validating that the subtotal is exactly 100.
All of these requirements necessitate using JavaScript. Generally,
those might be the minimum requirements, and additional requests
usually come in after some user testing. I can't do my job without
being able to access those values, whether they are valid or not.
A highly usable form will leverage JavaScript to prevent users from
entering or submitting invalid data. Back-end data validation is not
just enough any more. Most of us find it annoying when we go through
the trouble of entering data into a form without issue, only to click
submit and find out some input was invalid. Using JavaScript for this
kind of validation is absolutely essential for the kind of quality
user experience most of us have come to expect.
Valid numbers are more than digits
This is the flipside of the invalid number value issue: the number
input allows you to enter values that are technically acceptable
numbers, but there is a good chance you don't want them and didn't
anticipate that they could be considered "valid."
Chances are likely that you used the input type="number" because you
expected an integer to represent age or quantity. However, the number
input will allow for scientific notation values; for example, 2.3e4,
which represents 2.3 times 10 to the power of 4, or 23,000. If the
number input value grows large enough, some browsers will
automatically convert your input into exponential notation.
Different browsers accept different characters
All browsers are not the same. Let's start with the best case
scenarios.
Chrome and (surprise!) Microsoft Edge
The following characters are permitted (based on my hastily-done
first-hand testing);
* Numbers 0-9
* Decimal point
* "-" (for negative values)
* characters "+" and "e" for exponential notation
Screenshot of Keenforms in Chrome with invalid number value after
clicking submitScreenshot of Keenforms in Chrome with invalid number
value after clicking submit
Both of these browsers will prevent you from entering the accepted
non-numeric characters more than once. However, you can place those
symbols anywhere in the input, like putting the minus symbol in
between digits, which would make the number invalid and therefore
making that value inaccessible via JavaScript.
Firefox and Safari
There are no limits whatsoever. You can type whatever you want.
All of these browsers will show a built-in popup to indicate that the
value you've entered is not a valid number, and the Submit button
will not work without the user fixing those input values. The
built-in validation is visually inconsistent to whatever UX when you
are building for your app. As a programmer, you might find this
acceptable, but there's a good chance your designer and/or product
manager will not.
Screenshot of Keenforms in Firefox with invalid number value after
clicking submit Same as above on Firefox
Min/max limits can be bypassed
The ability to set the minimum and maximum number values in the
number input is a nice feature to have. The increment/decrement
buttons will keep the number value within these range parameters.
However, you cannot completely trust it to prevent out of range
values; it is possible to copy/paste a value beyond those limits.
If this seems petty, I want you to know I totally agree with you. But
it's not always my call.
Imagine a software tester finds this issue and logs a bug. Imagine
the product manager hears about the bug. Imagine discussing this bug
during sprint planning, but then pleading your case to that same
product manager: "This is an edge case and the number will still be
validated on the back end." And besides, you said this was MVP and
this "bug" is actually standard behavior of the number input. Imagine
losing that battle and having to fix it anyway.
The bottom line is that it's not always the developer's choice, and
the number input is not your friend.
What to use instead of number inputs
Before I go into detail about when to use the number input, it's
important to establish something that many experienced programmers
know, but which is worth repeating; You should only use the number
input when dealing with mathematically relevant numeric values, i.e.
the quantity of a product or someone's age. That means you never use
the number input for things like ZIP codes, phone numbers, social
security numbers, etc.
On to the more interesting stuff. Whether to use the number input
must be decided on a case-by-case basis, and the calculus will change
based on requirements, risks, and stakeholders.
If you need a number input that has no conditional validation (i.e.
number is always within a certain range of min/max) and has no
relationship with any other inputs on the form, then using the number
input is not a big deal. As mentioned, Keenforms does use the number
input for the position value of a form attribute. The risks and
consequences of a user wanting to do something malicious (like
putting invalid number on the position value) to their own form is
low enough that it's a worthwhile tradeoff.
Make sure the stakeholders are aware of this issue of visual
inconsistencies across different browsers as well as inconsistencies
of whatever messaging you are using to indicate invalid number input
values.
If you are dealing with conditional validation or that number is
being used elsewhere for a calculation, that's when you need to ditch
the number input. There are a couple of options on how to deal with
this issue:
The Gov.UK article mentions a possible solution: Using is a nice option for
integers, but it won't work for floating point decimal numbers.
Your last option is to do what I built for Keenforms: use a simple
input type="text", which will always give you its value, and do all
your validation via JavaScript. It requires more effort on the part
of the programmer and you lose the increment/decrement buttons. As
someone who has learned the hard way, though, it's a tradeoff that
I've had to accept. For advanced use cases I have not found another
viable option.
That is not to advocate for sacrificing all accessibility for the
sake of advanced requirements, visual consistency, and ease of use. I
recently spoke with Avram Sand from Access Armada to discuss some of
the problems related to the number input.
"The purpose of digital accessibility is to ensure that your forms
are understandable and usable for everyone," said Avram. "Number
input fields can help, but there are other ways to get to our desired
outcomes, for example, by forcing a numeric keypad on a text input,
adding descriptive field labels that indicate the requirements to
enter a number, and form validation and errors that work seamlessly
with screen readers and other assistive technologies."
My best recommendation for trying to maintain as much as
accessibility as possible is to use an online tool that will check
your webpages for accessibility, such as the WAVE accessibility tool.
If there's one takeaway here, it's that it's impossible to deliver
the kinds of complex functionality many projects demand while
simultaneously using the number input. It's an either/or choice, and
the way I see it, you're better off ditching the number input.
Tags: front-end, input type, javascript, web forms
Podcast logo The Stack Overflow Podcast is a weekly conversation
about working in software development, learning to code, and the art
and culture of computer programming.
Related
[Web3_Blog_Cover] stackoverflowknows April 20, 2022
New data: Do developers think Web3 will build a better internet?
Are blockchain and Web3 the future or are they just a fad? We asked
the developer community about Web3, blockchain, crypto, and whether
they are all hype or truly the future of the internet.
Avatar for David Gibson
David Gibson Senior Data Scientist
[020622-Stack-Overflow-Understanding-JSON-1200x630] code-for-a-living
June 2, 2022
A beginner's guide to JSON, the data format for the internet
When APIs send data, chances are they send it as JSON objects. Here's
a primer on why JSON is how networked applications send data.
Avatar for
Sam Robbins
[081222-Stack-Overflow-How-to-interrogate-unfamiliar-code-1200x630]
code-for-a-living August 15, 2022
How to interrogate unfamiliar code
Readable code is great, but not all code will be immediately
readable. That's when you get your interrogation tools.
Avatar for
Isaac Lyman
[170622-Stack-Overflow-Upping-our-unit-testing-game-1200x630]
code-for-a-living July 4, 2022
How Stack Overflow is leveling up its unit testing game
We neglected unit tests for a long time because our code base made
them difficult. But now we're putting in the work to change that.
Avatar for Wouter de Kort
Wouter de Kort
1 Comment
[ab7] Yahav says:
15 Sep 22 at 10:18
Next: why the "date" input is even worse!
Reply
Leave a Reply Cancel reply
Your email address will not be published. Required fields are marked
*
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
Comment * [ ]
Name * [ ]
Email * [ ]
Website [ ]
[ ] Save my name, email, and website in this browser for the next
time I comment.
[Post Comment]
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
D[ ]
This site uses Akismet to reduce spam. Learn how your comment data is
processed.
(c) 2022 All Rights Reserved.
Proudly powered by WordPress
Stack Overflow
About Press Work Here Contact Us Questions
Products
Teams Advertising Collectives Talent
Policies
Legal Privacy Policy Terms of Service Cookie Settings Cookie Policy
Channels
Blog Podcast Newsletter Twitter LinkedIn Instagram
*