Reputation: 1102
I have an input and can filter any letter if the input type is 'text'.
Also, I'm listening to an onKeyUp
event to increment/decrement the input value.
But there are 2 issues with this approach:
The text input does not show up/down buttons on the right side.
When the user presses the 'ArrowUp' button, the cursor 'jumps' back and forth (to the beginning of the input and then jumps back to the end of it).
When I try to implement the same logic for numeric input, the value coming from it is empty when the user types "e". EG: '12e' will be identified as "" (empty string). That would be acceptable, but I want the user to be able to delete any values he/she entered by selecting the range and pressing the "delete" button.
Here is the code example I created to demonstrate the issue:
https://codesandbox.io/s/peaceful-mcclintock-gd74y
Update:
According to an answer from Martin Wahlberg we should listen to an onKeyDown event. Here is the working version that filters "e","-" and "+". Might be useful for someone who faced the same issue.
https://codesandbox.io/s/throbbing-fast-5u2qq
Thanks for the help!
Upvotes: 0
Views: 2676
Reputation: 86
It looks to me like number type fields interpret the e
as part of a valid number using e notation. For example, 1e3
is the same as 1 x 10^3
or 1000
. It doesn't literally expand the number into the normal base 10 notation, but I guess when you end a number in e
, it isn't a valid number.
By the way, entering a +
also has the same effect as typing an e
.
You can address this by updating your onNumberInputChange
function to something like this:
const onNumberInputChange = useCallback(({ target: { value } }) => {
const updatedValue = (value === "") ? filteredValue.replace(/[^0-9]/g, '') : value;
setFilteredValue(updatedValue);
setUnfilteredValue(value);
}, [ filteredValue ]);
Edit: I added the regex replace to handle when an e
is inserted between numerals
Upvotes: 0
Reputation: 113
This should work:
const onNumberInputChange = useCallback(({ target: { value } }) => {
if(!/\d*/.test(value)) return
setFilteredValue(value);
setUnfilteredValue(value);
}, []); const onNumerInputKeyDown = (event) => {
if(event.key === "e") event.preventDefault();
}
And if you update your number input to use this function on keyDown we should be able to stop the user from inputing e aswell
const onNumerInputKeyDown = (event) => {
if(event.key === "e") event.preventDefault();
}
Here the user will be able to delete their input completely and the user is prevented from using e.
Upvotes: 1