Fix <input> with type date/time/etc. issue on mobile browsers (#7397)

Fix <input> with type date/time/etc. issue on mobile browsers
This commit is contained in:
Keyan Zhang
2016-08-02 12:56:05 -07:00
committed by GitHub
parent 0fb8febd0a
commit 8af6f9e5a2
2 changed files with 73 additions and 2 deletions

View File

@@ -230,8 +230,26 @@ var ReactDOMInput = {
// are not resetable nodes so this operation doesn't matter and actually
// removes browser-default values (eg "Submit Query") when no value is
// provided.
if (props.type !== 'submit' && props.type !== 'reset') {
node.value = node.value;
switch (props.type) {
case 'submit':
case 'reset':
break;
case 'color':
case 'date':
case 'datetime':
case 'datetime-local':
case 'month':
case 'time':
case 'week':
// This fixes the no-show issue on iOS Safari and Android Chrome:
// https://github.com/facebook/react/issues/7233
node.value = '';
node.value = node.defaultValue;
break;
default:
node.value = node.value;
break;
}
// Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug

View File

@@ -82,6 +82,21 @@ describe('ReactDOMInput', function() {
expect(node.defaultValue).toBe('1');
});
it('should update `defaultValue` for uncontrolled date/time input', function() {
var container = document.createElement('div');
var node = ReactDOM.render(<input type="date" defaultValue="1980-01-01" />, container);
expect(node.value).toBe('1980-01-01');
ReactDOM.render(<input type="date" defaultValue="2000-01-01" />, container);
expect(node.value).toBe('1980-01-01');
expect(node.defaultValue).toBe('2000-01-01');
ReactDOM.render(<input type="date" />, container);
});
it('should take `defaultValue` when changing to uncontrolled input', function() {
var container = document.createElement('div');
@@ -790,4 +805,42 @@ describe('ReactDOMInput', function() {
expect(node.value).toEqual('Test');
});
it('resets value of date/time input to fix bugs in iOS Safari', function() {
// https://github.com/facebook/react/issues/7233
if (!ReactDOMFeatureFlags.useCreateElement) {
return;
}
function strify(x) {
return JSON.stringify(x, null, 2);
}
var log = [];
var originalCreateElement = document.createElement;
spyOn(document, 'createElement').and.callFake(function(type) {
var el = originalCreateElement.apply(this, arguments);
if (type === 'input') {
Object.defineProperty(el, 'value', {
set: function(val) {
log.push(`node.value = ${strify(val)}`);
},
});
spyOn(el, 'setAttribute').and.callFake(function(name, val) {
log.push(`node.setAttribute(${strify(name)}, ${strify(val)})`);
});
}
return el;
});
ReactTestUtils.renderIntoDocument(<input type="date" defaultValue="1980-01-01" />);
expect(log).toEqual([
'node.setAttribute("data-reactroot", "")',
'node.setAttribute("type", "date")',
'node.setAttribute("value", "1980-01-01")',
'node.value = ""',
'node.value = ""',
'node.setAttribute("checked", "")',
'node.setAttribute("checked", "")',
]);
});
});