Skip to content

Commit 8ab56e5

Browse files
pingan1927nhunzaker
authored andcommitted
[#9712] fix <input type="number" /> value '.98' should not be equal to '0.98'. (#9714)
* [#9712] fix <input type="number" /> value ".98" should not be equal to "0.98". * fix eslint error * fix label error
1 parent 3daabf1 commit 8ab56e5

File tree

6 files changed

+78
-4
lines changed

6 files changed

+78
-4
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const React = window.React;
2+
3+
import Fixture from '../../Fixture';
4+
5+
class NumberInputDecimal extends React.Component {
6+
state = { value: '.98' };
7+
changeValue = () => {
8+
this.setState({
9+
value: '0.98',
10+
});
11+
}
12+
render() {
13+
const {value} = this.state;
14+
return (
15+
<Fixture>
16+
<div>{this.props.children}</div>
17+
18+
<div className="control-box">
19+
<input
20+
type="number"
21+
value={value}
22+
onChange={(e) => {
23+
this.setState({value: e.target.value});
24+
}}
25+
/>
26+
<button onClick={this.changeValue}>change.98 to 0.98</button>
27+
</div>
28+
</Fixture>
29+
);
30+
}
31+
}
32+
33+
export default NumberInputDecimal;

fixtures/dom/src/components/fixtures/number-inputs/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const React = window.React;
33
import FixtureSet from '../../FixtureSet';
44
import TestCase from '../../TestCase';
55
import NumberTestCase from './NumberTestCase';
6+
import NumberInputDecimal from './NumberInputDecimal';
67

78
function NumberInputs() {
89
return (
@@ -158,6 +159,20 @@ function NumberInputs() {
158159
</TestCase.ExpectedResult>
159160
<NumberTestCase />
160161
</TestCase>
162+
<TestCase
163+
title="Decimal numbers"
164+
description="eg: initial value is '.98', when format to '0.98', should change to '0.98' "
165+
>
166+
<TestCase.Steps>
167+
<li>initial value is '.98'</li>
168+
<li>setState to '0.98'</li>
169+
</TestCase.Steps>
170+
171+
<TestCase.ExpectedResult>
172+
the input value should be '0.98'.
173+
</TestCase.ExpectedResult>
174+
<NumberInputDecimal />
175+
</TestCase>
161176
</FixtureSet>
162177
);
163178
}

scripts/fiber/tests-passing.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,7 @@ src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
15241524
* does change the number 2 to "2.0" with no change handler
15251525
* does change the string "2" to "2.0" with no change handler
15261526
* changes the number 2 to "2.0" using a change handler
1527+
* does change the string ".98" to "0.98" with no change handler
15271528
* should display `defaultValue` of number 0
15281529
* only assigns defaultValue if it changes
15291530
* should display "true" for `defaultValue` of `true`

src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,12 @@ var ReactDOMInput = {
203203
// Simulate `input.valueAsNumber`. IE9 does not support it
204204
var valueAsNumber = parseFloat(node.value) || 0;
205205

206-
// eslint-disable-next-line
207-
if (value != valueAsNumber) {
206+
if (
207+
// eslint-disable-next-line
208+
value != valueAsNumber ||
209+
// eslint-disable-next-line
210+
(value == valueAsNumber && node.value != value)
211+
) {
208212
// Cast `value` to a string to ensure the value is set correctly. While
209213
// browsers typically do this as necessary, jsdom doesn't.
210214
node.value = '' + value;

src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,23 @@ describe('ReactDOMInput', () => {
233233
});
234234
});
235235

236+
it('does change the string ".98" to "0.98" with no change handler', () => {
237+
class Stub extends React.Component {
238+
state = {
239+
value: '.98',
240+
};
241+
render() {
242+
return <input type="number" value={this.state.value} />;
243+
}
244+
}
245+
246+
var stub = ReactTestUtils.renderIntoDocument(<Stub />);
247+
var node = ReactDOM.findDOMNode(stub);
248+
stub.setState({value: '0.98'});
249+
250+
expect(node.value).toEqual('0.98');
251+
});
252+
236253
it('should display `defaultValue` of number 0', () => {
237254
var stub = <input type="text" defaultValue={0} />;
238255
stub = ReactTestUtils.renderIntoDocument(stub);

src/renderers/dom/stack/client/wrappers/ReactDOMInput.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,12 @@ var ReactDOMInput = {
195195
// Simulate `input.valueAsNumber`. IE9 does not support it
196196
var valueAsNumber = parseFloat(node.value, 10) || 0;
197197

198-
// eslint-disable-next-line
199-
if (value != valueAsNumber) {
198+
if (
199+
// eslint-disable-next-line
200+
value != valueAsNumber ||
201+
// eslint-disable-next-line
202+
(value == valueAsNumber && node.value != value)
203+
) {
200204
// Cast `value` to a string to ensure the value is set correctly. While
201205
// browsers typically do this as necessary, jsdom doesn't.
202206
node.value = '' + value;

0 commit comments

Comments
 (0)