{"id":130,"date":"2022-07-22T04:21:07","date_gmt":"2022-07-22T04:21:07","guid":{"rendered":"https:\/\/blog.keenforms.com\/?p=130"},"modified":"2022-07-22T14:54:33","modified_gmt":"2022-07-22T14:54:33","slug":"why-the-number-input-is-the-worst-input","status":"publish","type":"post","link":"https:\/\/blog.keenforms.com\/blog\/why-the-number-input-is-the-worst-input\/","title":{"rendered":"Why the number input is the worst input"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">I recently <a href=\"https:\/\/news.ycombinator.com\/item?id=32138719\">shared a post on hacker news<\/a> about the app I\u2019ve been building (<a href=\"https:\/\/keenforms.com\">keenforms<\/a>). It actually sparked a lively discussion, although the most heated issue was not really about my product. It was about the &lt;input type=\u201dnumber\u201d&gt;, or rather the fact that we\u2019re not using it.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">At some point early on I tried using the number input in the form rendering page, but I ran into so many problems that it was just easier and more predictable to avoid it completely. We just use the &lt;input type=\u201dtext\u201d&gt; for number data types, and use javascript to validate the value. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">*Please note that we actually do use &lt;input type=&#8221;number&#8221;&gt; inside our app. However we only use it in the dashboard, for fields form attribute files such as position and score multiplier, because those validations are unconditional.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"> I discovered a lot of odd behavior when you use &lt;input type=\u201dnumber\u201d&gt;, but it never occurred to me to share all the problems I ran into. That is, until the hacker news post comments.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The pro number input crowd was primarily focused on the accessibility argument. The number input has the native increment\/decrement buttons. It has built in validation as well. Some mobile devices will show a number keypad instead of the full keyboard.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">There were also some complaints about developers overusing Javascript (guilty!). Keenforms relies heavily on javascript and specifically React, and Javascript is critical to the dynamic interactions that can be created using our software. I understand some people\u2019s aversion to JavaScript. However JavaScript is the only way to create a decent user experience with real time responses for the forms that Keenforms was built for. There is no other way to provide the kind of real time dynamic feedback I wanted for Keenforms without JavaScript. If you want a form builder that will render properly for users who have disabled JavaScript, then you shouldn&#8217;t use Keenforms.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">However I was not alone in the anti-number input camp. One user posted an article issued by the UK Government detailing all the problems related to the number input.<\/span><\/p>\n<p><a href=\"https:\/\/technology.blog.gov.uk\/2020\/02\/24\/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">https:\/\/technology.blog.gov.uk\/2020\/02\/24\/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers\/<\/span><\/a><\/p>\n<p><span style=\"font-weight: 400;\">The mind blowing thing about this article is;<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The article didn\u2019t mention the biggest problems I personally experienced AND<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The article mentioned a lot of problems I wasn\u2019t even aware of until I read it, such as;<\/span>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">It cannot be dictated or selected when using Dragon Naturally Speaking<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Certain browsers will round off large numbers<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Scrolling with scroll wheel on the mouse<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">At one point I stated that the number input was more trouble than it&#8217;s worth, and I could write an article why the number input was quantifiably terrible. The response I got was actually great;<\/span><\/p>\n<p><a href=\"https:\/\/news.ycombinator.com\/item?id=32143208\"><span style=\"font-weight: 400;\">\u201cplease do write an article. Although I&#8217;m skeptical, I would read it with an open mind + in good faith.\u201d<\/span><\/a><\/p>\n<p><span style=\"font-weight: 400;\">So here is a short list of all the reasons the number input is terrible.<\/span><\/p>\n<h3>The number input allows for invalid number values<\/h3>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"580\" height=\"389\" class=\"alignnone size-medium wp-image-137\" src=\"https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=580%2C389&#038;ssl=1\" alt=\"\" srcset=\"https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?w=1650&amp;ssl=1 1650w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=300%2C201&amp;ssl=1 300w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=1024%2C688&amp;ssl=1 1024w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=768%2C516&amp;ssl=1 768w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=1536%2C1031&amp;ssl=1 1536w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=1200%2C806&amp;ssl=1 1200w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=250%2C168&amp;ssl=1 250w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=550%2C369&amp;ssl=1 550w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=800%2C537&amp;ssl=1 800w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=268%2C180&amp;ssl=1 268w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=447%2C300&amp;ssl=1 447w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=745%2C500&amp;ssl=1 745w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/p>\n<p>This by itself, while undesirable, is not the biggest issue, but it&#8217;s required information to understand the next problem.<\/p>\n<h3>When the number input contains an invalid number value, and you retrieve the value via JavaScript you will get a BLANK STRING, (not actual contents displayed)<\/h3>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.reactiongifs.us\/wp-content\/uploads\/2015\/02\/dealbreaker_30_rock.gif?w=580&#038;ssl=1\" alt=\"Dealbreaker (30 Rock)\" \/><\/p>\n<p>There are a couple of ways you might go about retrieving the value. Could be on an event listener, which would mean event.target.value. Or through the DOM element. Either way you can&#8217;t get the value that&#8217;s actually in the &lt;input type=&#8221;number&#8221;&gt;<\/p>\n<pre>const numberInput = document.getElementById('id_here');\r\nconsole.log(numberInput.value); \/\/ will return empty string if invalid<\/pre>\n<p><span style=\"font-weight: 400;\">The inability to see what the text input actually contains is a massive problem. It makes client side validation using Javascript impossible.<\/span><\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"580\" height=\"389\" class=\"alignnone size-medium wp-image-137\" src=\"https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=580%2C389&#038;ssl=1\" alt=\"number input with invalid value\" srcset=\"https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?w=1650&amp;ssl=1 1650w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=300%2C201&amp;ssl=1 300w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=1024%2C688&amp;ssl=1 1024w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=768%2C516&amp;ssl=1 768w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=1536%2C1031&amp;ssl=1 1536w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=1200%2C806&amp;ssl=1 1200w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=250%2C168&amp;ssl=1 250w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=550%2C369&amp;ssl=1 550w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=800%2C537&amp;ssl=1 800w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=268%2C180&amp;ssl=1 268w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=447%2C300&amp;ssl=1 447w, https:\/\/i0.wp.com\/blog.keenforms.com\/wp-content\/uploads\/2022\/07\/Screen-Shot-2022-07-22-at-8.34.16-AM.png?resize=745%2C500&amp;ssl=1 745w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/p>\n<p>While validation of form inputs on the back end is a must, client side form validation via <span style=\"font-weight: 400;\">Javascript<\/span> is a critical tool to be able to provide better UX. If you&#8217;re just making sure the number is a number you might be ok with the built in number validation. However the reason I built my own form builder is that I wanted something better than that. As a programmer I routinely get requests to build forms with complex and conditional validations. Getting a blank string for an invalid number value is a deal breaker.<\/p>\n<h3><b>It\u2019s WAY TOO EASY to enter invalid number values into the number input<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">The accepted characters when typing in the number input varies from browser to browser. Let\u2019s start with the best case scenarios, <\/span><\/p>\n<p><b>Chrome and (surpise!) Microsoft Edge;<\/b><\/p>\n<p><span style=\"font-weight: 400;\">The following characters are permitted (based on my hastily done first hand testing)<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">numbers 0-9<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">decimal point<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">\u201c-\u201d (minus for negative values)<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">\u201c+\u201d (plus because <\/span><span style=\"font-weight: 400;\">\u00af\\_(\u30c4)_\/\u00af <\/span><span style=\"font-weight: 400;\">\u200b\u200b)<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">the letter \u2018e\u2019 &#8211; for exponential notation<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Both of these browsers will prevent you from entering the accepted non-numeric characters more than once. You can however place those symbols anywhere in the input, i.e. putting the minus symbol in between digits, which of course would make the number invalid.<\/span><\/p>\n<p><b>For browsers Firefox and Safari;<\/b><\/p>\n<p><span style=\"font-weight: 400;\">There are no limits whatsoever, you can type whatever you want.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">All of these browsers will show a built-in popup to indicate that the value you\u2019ve entered is not a valid number, and the submit button will not work without the user fixing those input values to be valid. The built in validation though is visually inconsistent when you are building dynamic responsive apps.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The letter \u2018e\u2019 thing is annoying. The value 2.3e4, represents 2.3 times 10 to the power of 4, aka 23,000. Under most circumstances you don\u2019t want exponential notation. If you enter a number big enough the number input will automatically convert your number to this format. For numbers that big it would seem HTML forms are not the best way to handle it, but that&#8217;s not my business. If you don&#8217;t know this already you should never use a number input for things like credit cards or phone numbers.<\/span><\/p>\n<p>Lastly there is one more stumbling block with the number input.<\/p>\n<h2>Number input attributes like min and max help keep the value within range when typing or pressing native increment\/decrement buttons. However out of range numbers can be copied\/pasted into the input.<\/h2>\n<p>The ability to set the minimum and maximum number values in the number input is a nice to have feature. The increment\/decrement buttons will keep the number value within these range parameters. However you can copy\/paste a value that is beyond those limits.<\/p>\n<p><span style=\"font-weight: 400;\">If you are reading this last issue and saying this seems petty, I want you to know I totally agree with you. However it\u2019s not always my call.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Imagine a software tester finding this issue and logging a bug. Imagine the client product manager hearing about the bug. Imagine discussing this during sprint planning, but then pleading your case to that said product manager \u201cthis is an edge case and the number will be validated on the back end\u201d. And besides, you said this was MVP and this \u201cbug\u201d is actually standard behavior of the number input. Imagine losing that battle and having to fix it anyway. All I\u2019m saying is it\u2019s not always the developers choice. Hypothetically of course.<\/span><\/p>\n<p>I suspect there&#8217;s stuff I don&#8217;t even know about. If you know another issue with the number input not cited here or the UK article we&#8217;d love to hear about it. I hope you learned something. Thanks for listening. And thanks to <a class=\"hnuser\" href=\"https:\/\/news.ycombinator.com\/user?id=folkhack\" target=\"_blank\" rel=\"noopener\">folkhack<\/a> for prodding me into writing this article.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>I recently shared a post on hacker news about the app I\u2019ve been building (keenforms). It actually sparked a lively discussion, although the most heated issue was not really about my product. It was about the &lt;input type=\u201dnumber\u201d&gt;, or rather the fact that we\u2019re not using it. At some point early on I tried using [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[9,10],"tags":[11],"class_list":["post-130","post","type-post","status-publish","format-standard","hentry","category-javascript","category-programming","tag-javascript"],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.keenforms.com\/blog\/wp-json\/wp\/v2\/posts\/130","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.keenforms.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.keenforms.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.keenforms.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.keenforms.com\/blog\/wp-json\/wp\/v2\/comments?post=130"}],"version-history":[{"count":10,"href":"https:\/\/blog.keenforms.com\/blog\/wp-json\/wp\/v2\/posts\/130\/revisions"}],"predecessor-version":[{"id":144,"href":"https:\/\/blog.keenforms.com\/blog\/wp-json\/wp\/v2\/posts\/130\/revisions\/144"}],"wp:attachment":[{"href":"https:\/\/blog.keenforms.com\/blog\/wp-json\/wp\/v2\/media?parent=130"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.keenforms.com\/blog\/wp-json\/wp\/v2\/categories?post=130"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.keenforms.com\/blog\/wp-json\/wp\/v2\/tags?post=130"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}