From 9cf33a56c6dc9d9eaaf19f8f481b84f489126e3b Mon Sep 17 00:00:00 2001 From: Keyan Zhang Date: Mon, 1 Aug 2016 16:44:37 -0700 Subject: [PATCH 1/2] fixed with type date/time/etc. issue on iOS safari --- .../dom/client/wrappers/ReactDOMInput.js | 20 ++++++- .../wrappers/__tests__/ReactDOMInput-test.js | 53 +++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/renderers/dom/client/wrappers/ReactDOMInput.js b/src/renderers/dom/client/wrappers/ReactDOMInput.js index fa553306c3655..9aec9ebdb6b81 100644 --- a/src/renderers/dom/client/wrappers/ReactDOMInput.js +++ b/src/renderers/dom/client/wrappers/ReactDOMInput.js @@ -230,8 +230,24 @@ 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 'date': + case 'datetime': + case 'datetime-local': + case 'month': + case 'time': + case 'week': + // this fixes the no-show issue on iOS Safari: 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 diff --git a/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js b/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js index b65ad01eeebb3..ecd83e69f3627 100644 --- a/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js +++ b/src/renderers/dom/client/wrappers/__tests__/ReactDOMInput-test.js @@ -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(, container); + + expect(node.value).toBe('1980-01-01'); + + ReactDOM.render(, container); + + expect(node.value).toBe('1980-01-01'); + expect(node.defaultValue).toBe('2000-01-01'); + + ReactDOM.render(, 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(); + 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", "")', + ]); + }); }); From c6f8c3226b556fe04eceb1884bcefa24df70b9d9 Mon Sep 17 00:00:00 2001 From: Keyan Zhang Date: Tue, 2 Aug 2016 12:40:14 -0700 Subject: [PATCH 2/2] supported color type and improved comments --- src/renderers/dom/client/wrappers/ReactDOMInput.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/renderers/dom/client/wrappers/ReactDOMInput.js b/src/renderers/dom/client/wrappers/ReactDOMInput.js index 9aec9ebdb6b81..1b649f828d4ec 100644 --- a/src/renderers/dom/client/wrappers/ReactDOMInput.js +++ b/src/renderers/dom/client/wrappers/ReactDOMInput.js @@ -235,13 +235,15 @@ var ReactDOMInput = { 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: https://github.com/facebook/react/issues/7233 + // 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;