Do you want to request a feature or report a bug?
bug
What is the current behavior?
input[type=number] only allows entering numbers and letter "e" in the input. Native "input" input event is called for both numbers and the letter "e". With React the onChange
event is only called for numbers. There's no way to catch "e" with onChange
.
The "e" is even being filled when the input is controlled. The only way I can think of to work around this bug right now is to use onKeyDown
and preventDefault
when "e" or "E" is pressed.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:
https://codesandbox.io/s/ov3ql3ljwz
What is the expected behavior?
It should pass anything that is being filled into the input to the onChange handler and should not break controlled component.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React: 16.4.2
Chrome: 68.0.3440.106
Windows 10
That's the browser behavior, cause 1e1
is also valid-floating-point-number.
But if you set input.value = '1e'
, React will throw warning and just give empty to input.
From what I could experiment with your codesandbox, the onChange
is still being called (with an empty value) for when you type "e".
Additionally, if you type anything after the "e", it will send the value properly.
I believe this is happening because a string _ending_ with "e" is not a valid number (e.g. 12e
), but a string with "e" followed by an integer is (e.g. 12e2
). Remember that 12e2
is a valid number, as Ende93 pointed out.
Notice the onChange
will be called with an empty value for any other non-number string (e.g. foo
), so it looks quite consistent to me.
@Yurickh is spot on. Thanks!
If I type the characters 1e2
I see three change events:
1e
is not a valid number)I believe everything is behaving as intended. However please let me know if there's a case we've missed. Also this is a super confusing part of inputs, so I'm happy to continue the conversation if anything else needs clarification (or I've missed something).
Thanks guys for having a look at this, but this is all I am getting: https://drive.google.com/file/d/1Tq7fF3e2w3QyAwE4mLTpHKz__GYYK0wF/view
The onChange
never gets called and the input becomes uncontrolled.
I believe this is a bug as the native input
event gets called correctly.
onChange
get called, you can just see the console log, but when you input 1e
, e.target.value
is '', and setState
get ''(empty string), so e.target.value
is the same to setState, so React will not see the diff, and input will not change.
That's correct. Numbers that start with e
are invalid, so Chrome reports an empty string as input.value
. As more numbers are added, the value reports the same (an empty string), so no change occurs.
@nhunzaker the problem here is that React's onChange
doesn't allow to distinguish between empty inputs of type number and non-empty invalid ones. This is often needed, e.g. to implement Material Design-style floating labels that descend into the input when it's empty; see e.g. https://github.com/mui-org/material-ui/issues/12764. I assume this is because in both cases value
is an empty string.
Modifying your steps, the scenario is as follows:
To implement Material UI inputs you need to check input's validity.badInput
field. But you won't have a chance to actually see it.
Could onChange
be fired not only if the input value changes but also if its validity.badInput
field changes? It seems that if anything else is not valid with the input (e.g. the value is below min
or step
is not respected) the value
field is not zeroed out.
Note that IE doesn't support validity.badInput
but IE also doesn't always clear value
for non-number values in a number input. For example, according to:
https://github.com/angular/angular.js/issues/10981#issuecomment-73231004
0a
is not cleared in IE but a0
is. This problem might not be solvable, though.
@mgol Would #9657 resolve this?
@gaearon If I understand it correctly, this line:
onInput
(...) It is allowed to over-fire many events even if nothing changed.
suggests it should solve the issue as the browser fires the input
event for each change, even if it doesn't change the value
property because, for example, you type e
into an empty <input type="number">
.
I don't know what's the difference between the polyfilled and non-polyfilled onInput
, is that relevant here? This particular issue affects both controlled and uncontrolled inputs.
@mgol Is this issue about controlled or uncontrolled component? Or both?
Both.
Tentatively reopening for future consideration.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution.
This is still an issue.
Most helpful comment
This is still an issue.