Inputs of type=”number” have below usability issues:
- In chrome it allows certain non-numeric characters like (‘e’, ‘+’, ‘-‘, ‘.’) and in Firefox it allows all non-numeric characters.
- It has up and down arrows which is used to increment or decrement the number but sometimes it is observed that user accidentally increase or decrease values.
In this blog, we will see that how to overcome these issues.
Below I have given examples for Material UI textfield in React and also for default input field in Vanilla Javascript.
Let’s consider two browsers Chrome and Firefox because both show different behaviour for type=number.
When we use input type=number
- In Chrome , you will observe that it does not allow the user to enter non-numeric values but it allows the characters like (‘e’, ‘+’, ‘-‘, ‘.’) . You can find the example for the same below.
- In Firefox, user can enter any value in the number field , so we need to add the check for the keyboard keys which we don’t want to be entered by the user.
How to disallow characters like (‘e’, ‘+’, ‘-‘, ‘.’) in type=number in chrome
In case of MUI TextField consider below example
If we want to restrict some particular keyboard keys then we can make use of the onKeyDown event property which is event.key to capture the key and prevent the user to enter that key in the textfield.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import TextField from "@mui/material/TextField"; import { useState } from "react"; const NumberTextField = () => { const [value, setValue] = useState(); const changeHandler = (e) => { setValue(Number(e.target.value)); }; return ( <> <TextField type="number" onKeyDown={(evt) => (evt.key === "-" || evt.key === "e") && evt.preventDefault() } value={value ? value : ""} onChange={changeHandler} /> </> ); }; export default NumberTextField; |
In case of Javascript input field consider below example
Here we will take use of keydown event of JS to achieve the required behaviour.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html> <html> <body> <input type="number" /> </body> <script> const input = document.querySelector("input"); input.addEventListener("keydown", checkfunc); function checkfunc(evt) { (evt.key === "-" || evt.key === "e") && evt.preventDefault(); } </script> </html> |
In chrome we only need to restrict some keys so we can use event.key.
How to disallow non-numeric values in type=number TextField in Firefox
In case of MUI TextField consider below example
In Firefox we need to restrict all the non-numeric values so we can use the onKeyDown event property event.keyCode to restrict the range of keyboard keys to be entered.
I have put the check for Backspace so that we can edit or delete the entered value from the Mui TextField if required.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import TextField from "@mui/material/TextField"; import { useState } from "react"; const NumberTextField = () => { const [value, setValue] = useState(); const changeHandler = (e) => { setValue(Number(e.target.value)); }; return ( <> <TextField type="number" onKeyDown={(evt) => { if (evt.keyCode < 48 || evt.keyCode > 57) { if (evt.key !== "Backspace") evt.preventDefault(); } }} value={value ? value : ""} onChange={changeHandler} /> </> ); }; export default NumberTextField; |
In case of Javascript input field consider below example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!DOCTYPE html> <html> <body> <input type="number" /> </body> <script> const input = document.querySelector("input"); input.addEventListener("keydown", checkfunc); function checkfunc(evt) { if (evt.keyCode < 48 || evt.keyCode > 57) { if (evt.key !== "Backspace") evt.preventDefault(); } } </script> </html> |
How to remove Up & Down Arrow from type=number TextField
Here we can use the css to achieve the required behaviour. We will use different css for FireFox and for other browsers.
In case of MUI TextField consider below example
In the below example, I have used <style> tag to use the css which is defined in the variable arrow_remove_css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import TextField from "@mui/material/TextField"; import { useState } from "react"; const NumberTextField = () => { const arrow_remove_css = ` /* Firefox */ input[type="number"] { -moz-appearance: textfield; } /* For Other Browsers */ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } `; const [value, setValue] = useState(); const changeHandler = (e) => { setValue(Number(e.target.value)); }; return ( <> <style>{arrow_remove_css}</style> <TextField type="number" value={value ? value : ""} onChange={changeHandler} /> </> ); }; export default NumberTextField; |
In case of Javascript input field consider below example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<!DOCTYPE html> <html> <head> <style> /* Firefox */ input[type="number"] { -moz-appearance: textfield; } /* For Other Browsers */ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } </style> </head> <body> <input type="number" /> </body> <script> const input = document.querySelector("input"); input.addEventListener("keydown", checkfunc); function checkfunc(evt) { if (evt.keyCode < 48 || evt.keyCode > 57) { if (evt.key !== "Backspace") evt.preventDefault(); } } </script> </html> |
Mui TextField is used as a nested component with the popular Mui component called Autocomplete.
You can use these customization with Autocomplete and also learn more about the different style and customization of Mui Autocomplete here.
Important Note
Using input type number is beneficial for the user experience on mobile devices because when the user clicks in this field the mobile keypad only shows the numeric keypad to the user.
But due to above issues in the input type=number, it is recommended by MUI to use the alternative of type=number as shown below
1 |
<TextField inputProps={{ inputMode: 'numeric', pattern: '[0-9]*' }} /> |
In Vanilla Javascript consider below
1 |
<input type="text" inputmode="numeric" pattern="[0-9]*"> |
To support this statement it also recommends to see this article by the GOV.UK Design System team.
NICE WORK TEAM