Skip to content

Commit 44fa2c8

Browse files
keyzzpao
authored andcommitted
Fix <input> with type date/time/etc. issue on mobile browsers (#7397)
Fix <input> with type date/time/etc. issue on mobile browsers (cherry picked from commit 8af6f9e)
1 parent bad1080 commit 44fa2c8

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

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

+20-2
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,26 @@ var ReactDOMInput = {
230230
// are not resetable nodes so this operation doesn't matter and actually
231231
// removes browser-default values (eg "Submit Query") when no value is
232232
// provided.
233-
if (props.type !== 'submit' && props.type !== 'reset') {
234-
node.value = node.value;
233+
234+
switch (props.type) {
235+
case 'submit':
236+
case 'reset':
237+
break;
238+
case 'color':
239+
case 'date':
240+
case 'datetime':
241+
case 'datetime-local':
242+
case 'month':
243+
case 'time':
244+
case 'week':
245+
// This fixes the no-show issue on iOS Safari and Android Chrome:
246+
// https://github.com/facebook/react/issues/7233
247+
node.value = '';
248+
node.value = node.defaultValue;
249+
break;
250+
default:
251+
node.value = node.value;
252+
break;
235253
}
236254

237255
// Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug

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

+53
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,21 @@ describe('ReactDOMInput', function() {
7373
expect(node.defaultValue).toBe('1');
7474
});
7575

76+
it('should update `defaultValue` for uncontrolled date/time input', function() {
77+
var container = document.createElement('div');
78+
79+
var node = ReactDOM.render(<input type="date" defaultValue="1980-01-01" />, container);
80+
81+
expect(node.value).toBe('1980-01-01');
82+
83+
ReactDOM.render(<input type="date" defaultValue="2000-01-01" />, container);
84+
85+
expect(node.value).toBe('1980-01-01');
86+
expect(node.defaultValue).toBe('2000-01-01');
87+
88+
ReactDOM.render(<input type="date" />, container);
89+
});
90+
7691
it('should take `defaultValue` when changing to uncontrolled input', function() {
7792
var container = document.createElement('div');
7893

@@ -781,4 +796,42 @@ describe('ReactDOMInput', function() {
781796
expect(node.value).toEqual('Test');
782797
});
783798

799+
it('resets value of date/time input to fix bugs in iOS Safari', function() {
800+
// https://github.com/facebook/react/issues/7233
801+
if (!ReactDOMFeatureFlags.useCreateElement) {
802+
return;
803+
}
804+
805+
function strify(x) {
806+
return JSON.stringify(x, null, 2);
807+
}
808+
809+
var log = [];
810+
var originalCreateElement = document.createElement;
811+
spyOn(document, 'createElement').and.callFake(function(type) {
812+
var el = originalCreateElement.apply(this, arguments);
813+
if (type === 'input') {
814+
Object.defineProperty(el, 'value', {
815+
set: function(val) {
816+
log.push(`node.value = ${strify(val)}`);
817+
},
818+
});
819+
spyOn(el, 'setAttribute').and.callFake(function(name, val) {
820+
log.push(`node.setAttribute(${strify(name)}, ${strify(val)})`);
821+
});
822+
}
823+
return el;
824+
});
825+
826+
ReactTestUtils.renderIntoDocument(<input type="date" defaultValue="1980-01-01" />);
827+
expect(log).toEqual([
828+
'node.setAttribute("data-reactroot", "")',
829+
'node.setAttribute("type", "date")',
830+
'node.setAttribute("value", "1980-01-01")',
831+
'node.value = ""',
832+
'node.value = ""',
833+
'node.setAttribute("checked", "")',
834+
'node.setAttribute("checked", "")',
835+
]);
836+
});
784837
});

0 commit comments

Comments
 (0)