diff --git a/src/components/DatePicker/datepickerPropTypes.js b/src/components/DatePicker/datepickerPropTypes.js
index 8f3bd03c75e0..4a681ec90c49 100644
--- a/src/components/DatePicker/datepickerPropTypes.js
+++ b/src/components/DatePicker/datepickerPropTypes.js
@@ -9,10 +9,16 @@ const propTypes = {
/**
* The datepicker supports any value that `moment` can parse.
- * `onChange` would always be called with a Date (or null)
+ * `onInputChange` would always be called with a Date (or null)
*/
value: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
+ /**
+ * The datepicker supports any defaultValue that `moment` can parse.
+ * `onInputChange` would always be called with a Date (or null)
+ */
+ defaultValue: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
+
/* Restricts for selectable max date range for the picker */
maximumDate: PropTypes.instanceOf(Date),
};
diff --git a/src/components/DatePicker/index.android.js b/src/components/DatePicker/index.android.js
index bc6a8ea54222..77d7bbc705a2 100644
--- a/src/components/DatePicker/index.android.js
+++ b/src/components/DatePicker/index.android.js
@@ -1,6 +1,7 @@
import React from 'react';
import RNDatePicker from '@react-native-community/datetimepicker';
import moment from 'moment';
+import _ from 'underscore';
import TextInput from '../TextInput';
import CONST from '../../CONST';
import {propTypes, defaultProps} from './datepickerPropTypes';
@@ -14,31 +15,31 @@ class DatePicker extends React.Component {
};
this.showPicker = this.showPicker.bind(this);
- this.raiseDateChange = this.raiseDateChange.bind(this);
- }
-
- /**
- * @param {Event} event
- */
- showPicker(event) {
- this.setState({isPickerVisible: true});
- event.preventDefault();
+ this.setDate = this.setDate.bind(this);
}
/**
* @param {Event} event
* @param {Date} selectedDate
*/
- raiseDateChange(event, selectedDate) {
+ setDate(event, selectedDate) {
if (event.type === 'set') {
- this.props.onChange(selectedDate);
+ this.props.onInputChange(selectedDate);
}
this.setState({isPickerVisible: false});
}
+ /**
+ * @param {Event} event
+ */
+ showPicker(event) {
+ this.setState({isPickerVisible: true});
+ event.preventDefault();
+ }
+
render() {
- const dateAsText = this.props.value ? moment(this.props.value).format(CONST.DATE.MOMENT_FORMAT_STRING) : '';
+ const dateAsText = this.props.defaultValue ? moment(this.props.defaultValue).format(CONST.DATE.MOMENT_FORMAT_STRING) : '';
return (
<>
@@ -46,18 +47,24 @@ class DatePicker extends React.Component {
label={this.props.label}
value={dateAsText}
placeholder={this.props.placeholder}
- hasError={this.props.hasError}
errorText={this.props.errorText}
containerStyles={this.props.containerStyles}
onPress={this.showPicker}
editable={false}
disabled={this.props.disabled}
+ onBlur={this.props.onBlur}
+ ref={(el) => {
+ if (!_.isFunction(this.props.innerRef)) {
+ return;
+ }
+ this.props.innerRef(el);
+ }}
/>
{this.state.isPickerVisible && (
)}
@@ -69,4 +76,7 @@ class DatePicker extends React.Component {
DatePicker.propTypes = propTypes;
DatePicker.defaultProps = defaultProps;
-export default DatePicker;
+export default React.forwardRef((props, ref) => (
+ /* eslint-disable-next-line react/jsx-props-no-spreading */
+
+));
diff --git a/src/components/DatePicker/index.ios.js b/src/components/DatePicker/index.ios.js
index 6a1bd98de987..879a102ac1ad 100644
--- a/src/components/DatePicker/index.ios.js
+++ b/src/components/DatePicker/index.ios.js
@@ -3,6 +3,7 @@ import React from 'react';
import {Button, View} from 'react-native';
import RNDatePicker from '@react-native-community/datetimepicker';
import moment from 'moment';
+import _ from 'underscore';
import TextInput from '../TextInput';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';
import Popover from '../Popover';
@@ -16,13 +17,13 @@ const datepickerPropTypes = {
...withLocalizePropTypes,
};
-class Datepicker extends React.Component {
+class DatePicker extends React.Component {
constructor(props) {
super(props);
this.state = {
isPickerVisible: false,
- selectedDate: props.value ? moment(props.value).toDate() : new Date(),
+ selectedDate: props.defaultValue ? moment(props.defaultValue).toDate() : new Date(),
};
this.showPicker = this.showPicker.bind(this);
@@ -49,11 +50,11 @@ class Datepicker extends React.Component {
/**
* Accept the current spinner changes, close the spinner and propagate the change
- * to the parent component (props.onChange)
+ * to the parent component (props.onInputChange)
*/
selectDate() {
this.setState({isPickerVisible: false});
- this.props.onChange(this.state.selectedDate);
+ this.props.onInputChange(this.state.selectedDate);
}
/**
@@ -65,19 +66,25 @@ class Datepicker extends React.Component {
}
render() {
- const dateAsText = this.props.value ? moment(this.props.value).format(CONST.DATE.MOMENT_FORMAT_STRING) : '';
+ const dateAsText = this.props.defaultValue ? moment(this.props.defaultValue).format(CONST.DATE.MOMENT_FORMAT_STRING) : '';
return (
<>
{
+ if (!_.isFunction(this.props.innerRef)) {
+ return;
+ }
+ this.props.innerRef(el);
+ }}
/>
(
+ /* eslint-disable-next-line react/jsx-props-no-spreading */
+
+)));
diff --git a/src/components/DatePicker/index.js b/src/components/DatePicker/index.js
index a324c25ae878..0077e4cf9add 100644
--- a/src/components/DatePicker/index.js
+++ b/src/components/DatePicker/index.js
@@ -1,5 +1,6 @@
import React from 'react';
import moment from 'moment';
+import _ from 'underscore';
import TextInput from '../TextInput';
import CONST from '../../CONST';
import {propTypes, defaultProps} from './datepickerPropTypes';
@@ -12,18 +13,18 @@ const datePickerPropTypes = {
...windowDimensionsPropTypes,
};
-class Datepicker extends React.Component {
+class DatePicker extends React.Component {
constructor(props) {
super(props);
- this.raiseDateChange = this.raiseDateChange.bind(this);
+ this.setDate = this.setDate.bind(this);
this.showDatepicker = this.showDatepicker.bind(this);
/* We're using uncontrolled input otherwise it wont be possible to
* raise change events with a date value - each change will produce a date
* and make us reset the text input */
- this.defaultValue = props.value
- ? moment(props.value).format(CONST.DATE.MOMENT_FORMAT_STRING)
+ this.defaultValue = props.defaultValue
+ ? moment(props.defaultValue).format(CONST.DATE.MOMENT_FORMAT_STRING)
: '';
}
@@ -40,15 +41,15 @@ class Datepicker extends React.Component {
* Trigger the `onChange` handler when the user input has a complete date or is cleared
* @param {String} text
*/
- raiseDateChange(text) {
+ setDate(text) {
if (!text) {
- this.props.onChange(null);
+ this.props.onInputChange(null);
return;
}
const asMoment = moment(text);
if (asMoment.isValid()) {
- this.props.onChange(asMoment.format(CONST.DATE.MOMENT_FORMAT_STRING));
+ this.props.onInputChange(asMoment.format(CONST.DATE.MOMENT_FORMAT_STRING));
}
}
@@ -69,22 +70,31 @@ class Datepicker extends React.Component {
return (
this.inputRef = input}
+ ref={(el) => {
+ this.inputRef = el;
+
+ if (_.isFunction(this.props.innerRef)) {
+ this.props.innerRef(el);
+ }
+ }}
onFocus={this.showDatepicker}
label={this.props.label}
- onChangeText={this.raiseDateChange}
+ onInputChange={this.setDate}
defaultValue={this.defaultValue}
placeholder={this.props.placeholder}
- hasError={this.props.hasError}
errorText={this.props.errorText}
containerStyles={this.props.containerStyles}
disabled={this.props.disabled}
+ onBlur={this.props.onBlur}
/>
);
}
}
-Datepicker.propTypes = datePickerPropTypes;
-Datepicker.defaultProps = defaultProps;
+DatePicker.propTypes = datePickerPropTypes;
+DatePicker.defaultProps = defaultProps;
-export default withWindowDimensions(Datepicker);
+export default withWindowDimensions(React.forwardRef((props, ref) => (
+ /* eslint-disable-next-line react/jsx-props-no-spreading */
+
+)));
diff --git a/src/pages/EnablePayments/AdditionalDetailsStep.js b/src/pages/EnablePayments/AdditionalDetailsStep.js
index b4842ca7792a..2d679b1118f4 100644
--- a/src/pages/EnablePayments/AdditionalDetailsStep.js
+++ b/src/pages/EnablePayments/AdditionalDetailsStep.js
@@ -320,8 +320,8 @@ class AdditionalDetailsStep extends React.Component {
this.clearErrorAndSetValue('dob', val)}
- value={this.props.walletAdditionalDetailsDraft.dob || ''}
+ onInputChange={val => this.clearErrorAndSetValue('dob', val)}
+ defaultValue={this.props.walletAdditionalDetailsDraft.dob || ''}
placeholder={this.props.translate('common.dob')}
errorText={this.getErrorText('dob')}
maximumDate={new Date()}
diff --git a/src/pages/ReimbursementAccount/CompanyStep.js b/src/pages/ReimbursementAccount/CompanyStep.js
index 384a7bfeba05..59dd4149abcb 100644
--- a/src/pages/ReimbursementAccount/CompanyStep.js
+++ b/src/pages/ReimbursementAccount/CompanyStep.js
@@ -119,8 +119,7 @@ class CompanyStep extends React.Component {
* @param {String} value
*/
clearDateErrorsAndSetValue(value) {
- this.clearError('incorporationDate');
- this.clearError('incorporationDateFuture');
+ this.clearErrors(['incorporationDate', 'incorporationDateFuture']);
this.setValue({incorporationDate: value});
}
@@ -277,8 +276,8 @@ class CompanyStep extends React.Component {
{
label={`${props.translate('common.dob')}`}
containerStyles={[styles.mt4]}
placeholder={props.translate('common.dateFormat')}
- value={props.values.dob}
- onChange={value => props.onFieldChange({dob: value})}
+ defaultValue={props.values.dob}
+ onInputChange={value => props.onFieldChange({dob: value})}
errorText={dobErrorText}
maximumDate={new Date()}
/>
diff --git a/src/stories/Datepicker.stories.js b/src/stories/Datepicker.stories.js
index 0fb3cd31c2b6..08f39b104c7e 100644
--- a/src/stories/Datepicker.stories.js
+++ b/src/stories/Datepicker.stories.js
@@ -13,7 +13,7 @@ export default {
onChange: {action: 'date changed'},
},
args: {
- value: '',
+ defaultValue: '',
label: 'Select Date',
placeholder: 'Date Placeholder',
errorText: '',
@@ -34,7 +34,7 @@ Default.args = {
PreFilled.args = {
label: 'Select Date',
- value: new Date(2018, 7, 21),
+ defaultValue: new Date(2018, 7, 21),
};
export {
diff --git a/src/stories/Form.stories.js b/src/stories/Form.stories.js
index 262a9f3a1c90..5e45076a8c7a 100644
--- a/src/stories/Form.stories.js
+++ b/src/stories/Form.stories.js
@@ -3,6 +3,7 @@ import {View} from 'react-native';
import TextInput from '../components/TextInput';
import Picker from '../components/Picker';
import AddressSearch from '../components/AddressSearch';
+import DatePicker from '../components/DatePicker';
import Form from '../components/Form';
import * as FormActions from '../libs/actions/FormActions';
import styles from '../styles/styles';
@@ -22,6 +23,7 @@ const story = {
AddressSearch,
CheckboxWithLabel,
Picker,
+ DatePicker,
},
};
@@ -54,6 +56,12 @@ const Template = (args) => {
containerStyles={[styles.mt4]}
isFormInput
/>
+