-
Notifications
You must be signed in to change notification settings - Fork 46.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Losing control of <input type='number' /> #1549
Comments
Yeah, I've noticed when experimenting with raw |
@syranide yeah, that's what I am planning. The down side is that I lose the numeric keyboard on mobile devices though. |
For non-react apps, we've used this successfully:
Here are some other options and some caveats: http://stackoverflow.com/questions/6178556/iphone-numeric-keyboard-for-text-input I don't know if 'pattern' is supported by React though. |
@jefffriesen It's supported :) Also, that's really good to know, thanks! |
Hi guys, I'm also falling in this bug, I still want to use the native input number (native controls and change events), is there any way I can make this working again? Is this because React preventDefault for all events? Thanks |
@gre Sorry, this is literally a "bug" in the DOM (or Chrome at least), it's impossible to read the actual value of the input when it is non-numeric. |
not sure to get what do you mean but input.addEventListener("change", function (e) {
var value = parseFloat(input.value, 10);
...
}, false); works on Chrome. as a proof I've used some here: https://glsl.io/transition/b6720916aa3f035949bc <input type="number" step="0.1" /> |
@gre http://jsfiddle.net/44pnh/1/ try that in Chrome (it outputs below the input). As soon as you enter anything non-numeric, value becomes empty. |
So as I understand this Chrome behavior make it impossible to implement the sync in React? I don't know what says the spec, but I'm not sure to get (1) what is functionally wrong with that behaviour (it is a number input so non-number values doesn't make sense – but yeah maybe Chrome shouldn't allow inputing invalid text), If this Chrome "bug" is fixed, there is still a bug in React making the input number working right? Anyway, as you recommended previously, I'm gonna implement my own number component then ;-) |
@gre Don't know the specifics, but I guess it's the same as with auto-fill, the browser simply doesn't tell us when the user makes changes. If it's possible to listen to up/down then, yeah, seems reasonable that we should to it (but listening to PS. My point was basically that it's already kind of bad, if you implement it yourself you could easily even prevent invalid chars from being typed (you can for number too ofc). But like with selects, styling is always going to be an issue. Seemingly, there is also always going to be obscure bugs/behaviors. |
A little late to the discussion, but I found an easy solution with some jquery magic. change: function (event) {
if (event.target.validity.valid) {
this.setState({ v: event.target.value });
} else if (event.target.value == '') {
$(this.getDOMNode()).val('');
}
} |
Additionally, if you guys WANT the native numeric keyboard on mobile, you could wrap input in something like so: class Input extends React.Component {
render() {
var type = navigator.userAgent.match(/Mobi/) && this.props.type === 'number' ? 'number' : 'text';
return <input {...this.props} type={type} />
}
} or, react could do this if they dig the patch/hack. |
Here's my solution. handleUpdate(e) {
if (e.target.validity.valid) {
//input is numeric
this.setState({inputValue: e.target.value});
} else if (e.target.value == '') {
//input is not numeric
this.numberInput.value = ''; //suppress UI change
this.setState({inputValue: ''}); //reset state
}
}
render() {
return (
...
<input type="number" value={this.state.inputValue} onChange={handleUpdate}
ref={elm=>{this.numberInput=elm}}/>{/*use ref to expose underlying dom node*/}
...
)
} the idea is from @markusk88, but my version doesn't use jQuery |
How about this (see pen). The key here is setting _handleUpdate(e) {
if (!e.target.validity.valid) {
e.target.value = this.state.inputValue; // Set to last known valid value.
}
this.setState({ inputValue: e.target.value });
} <input type="number" value={this.state.inputValue} onChange={this._handleUpdate} step="any" /> The only side effect (as far as I've been able to detect) is that if on Safari and possibly FIrefox (untested), you type "1" then "2" then place the cursor between the "1" and the "2" (i.e. EDIT: I've shortened it to the following without consequence. It still works in Safari and without the "cursor to the end" issue I discribed above. _handleUpdate(e) {
if (e.target.validity.valid) {
this.setState({ inputValue: e.target.value });
}
} EDIT: Although I see that is exactly the case of the original post, so now I'm confused as to the problem. It works in Chrome and Safari. |
I have similar issue with this. I can type But if I has defaultValue |
+1 |
+1 |
2 similar comments
+1 |
+1 |
Please stop adding "+1" comments. If you want to support an issue, add a 👍 reaction to the original post. |
I believe that #7359 resolved this. If not, it definitely covers all of the cases I could find. We should move forward with new issues for particular edge cases if they are discovered. |
I still have this problem; text typed in appears in the input, but the onChange listener is skipped and the controlled value does not change. |
@CluEleSsUK would it be possible to file a new issue with a reproducing example? |
Sure, will do! |
I have similar issue with this. A controlled React input with type "number" clears its value when I add a dot to the end of the value.
See live demo here:
The bug is reproduced in Google Chrome (80.0.3987.87, 64-bit). P.S. An uncontrolled React input with type "number" allows adding a dot to the end of the value in all browsers mentioned above. An input with type "number" in pure HTML (without React) has the same behavior. Upd (2020-02-11) |
HI, Im having a similar issue where the onChange is not called in FireFox when the number input is not valid but the input maintains the value of the input and I cant get the change event to set the ref.current.value = ''; ` const NumInput = styled(Input) const NumberInput = ({ name, value, onChange, disabled, innerRef, pattern, step, ...rest }) => { const validateChange = event => { const validateOnBlur = event => { return ( NumberInput.propTypes = { NumberInput.defaultProps = { export default NumberInput; ` |
http://jsfiddle.net/kb3gN/2498/
In the example above when you start typing numbers and then a non-number character it wont update the input field which is expected. If you start typing a non-number character first though it seems that the input field becomes uncontrolled and starts excepting anything you type and onChange isn't fired anymore.
The text was updated successfully, but these errors were encountered: