[#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
pingan1927 committed
Jun 9, 2017 at 09:27 UTC
8ab56e5c8b8f797a6b2bdd4188b4082c55a5190b
6 files changed
+78
-4
fixtures/dom/src/components/fixtures/number-inputs/NumberInputDecimal.js
new
+33
@@ -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
+15
@@ -3,6 +3,7 @@ const React = window.React;
3
import FixtureSet from '../../FixtureSet';
4
import TestCase from '../../TestCase';
5
import NumberTestCase from './NumberTestCase';
6
+import NumberInputDecimal from './NumberInputDecimal';
7
8
function NumberInputs() {
9
return (
@@ -158,6 +159,20 @@ function NumberInputs() {
159
</TestCase.ExpectedResult>
160
<NumberTestCase />
161
</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>
176
</FixtureSet>
177
);
178
}
scripts/fiber/tests-passing.txt
+1
@@ -1524,6 +1524,7 @@ src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
1524
* does change the number 2 to "2.0" with no change handler
1525
* does change the string "2" to "2.0" with no change handler
1526
* changes the number 2 to "2.0" using a change handler
1527
+* does change the string ".98" to "0.98" with no change handler
1528
* should display `defaultValue` of number 0
1529
* only assigns defaultValue if it changes
1530
* should display "true" for `defaultValue` of `true`
src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js
+6
-2
@@ -203,8 +203,12 @@ var ReactDOMInput = {
203
// Simulate `input.valueAsNumber`. IE9 does not support it
204
var valueAsNumber = parseFloat(node.value) || 0;
205
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
+ ) {
212
// Cast `value` to a string to ensure the value is set correctly. While
213
// browsers typically do this as necessary, jsdom doesn't.
214
node.value = '' + value;
src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
+17
@@ -233,6 +233,23 @@ describe('ReactDOMInput', () => {
233
});
234
});
235
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
+
253
it('should display `defaultValue` of number 0', () => {
254
var stub = <input type="text" defaultValue={0} />;
255
stub = ReactTestUtils.renderIntoDocument(stub);
src/renderers/dom/stack/client/wrappers/ReactDOMInput.js
+6
-2
@@ -195,8 +195,12 @@ var ReactDOMInput = {
195
// Simulate `input.valueAsNumber`. IE9 does not support it
196
var valueAsNumber = parseFloat(node.value, 10) || 0;
197
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
+ ) {
204
// Cast `value` to a string to ensure the value is set correctly. While
205
// browsers typically do this as necessary, jsdom doesn't.
206
node.value = '' + value;