Reputation: 1516
I have a simple react class which renders a controlled input box of type number.
var Form = React.createClass({
getInitialState: function() {
return { value: 12.12 };
},
handleChange: function(e) {
this.setState({ value: e.target.value });
},
render: function() {
return (
<input
onChange = {(e) => this.handleChange(e)}
type = "number"
value = {this.state.value}
/>
);
}
});
ReactDOM.render( <Form /> , document.getElementById('container'));
This code is present in this jsfiddle.
To change the value, when I delete the numbers one by one and delete the decimal point, the focus suddenly shifts to the start of the input box.
This happens on latest Chrome browser (54.0.2840.87) but not on Firefox.
If I use a defaultValue instead of value in state, on Chrome, even when I add a decimal value to the number, the focus shifts to the start. (The issue happens both on adding decimal value or on deleting the decimal part) Please refer to this jsfiddle.
I saw the answer to a similar question here. But the problem persists in Chrome when I try to delete numbers till decimal point.
Is there a way to get around this problem?
Thanks in advance for your help.
Upvotes: 1
Views: 858
Reputation: 1516
I wanted to use an input box of type 'number' (for stepper, etc.), so did a work around by using refs
.
I took this idea of using refs from an answer to a similar question here.
I do not use defaultValue in the input tag but set the initial value in componentDidMount
. And on change, I set value in a variable for future use.
var Form = React.createClass({
componentDidMount() {
this.input.value = "123.12";
},
handleChange: function(e) {
this.value = e.target.value;
},
render: function() {
return (
<input
onChange = {(e) => this.handleChange(e)}
type = "number"
ref={(elem) => this.input = elem}
/>
);
}
});
ReactDOM.render( <Form /> , document.getElementById('container'));
Please find jsfiddle code here.
Upvotes: 1
Reputation: 7672
It happens because your type="number"
. The e.target.value
variable will have type of number too. Since there is no number that has value 12.
(happens when you delete last decimal number after decimal point), then e.target.value
will simply has value of 12
, so the value jump from 12.1
to 12
(note that two characters deleted at the same time). It seems that Chrome doesn't like that change and behave strangely.
The solution for this problem is to simply change your input
type to text, and validate your text box on submit.
Or simply strip invalid characters on text box change.
var Form = React.createClass({
getInitialState: function() {
return { value: 12.12 };
},
handleChange: function(e) {
this.setState({
value: e.target.value.replace(/([^0-9\.])/g, '')
});
},
render: function() {
return (
<input
onChange = {(e) => this.handleChange(e)}
type = "text"
value = {this.state.value}
/>
);
}
});
ReactDOM.render( <Form /> , document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
Upvotes: 0