I have a React Native application with a form for entering data. One of the fields is a DateTime value, but is optional. In other words, the user can choose a date if they want one, but can leave it blank/null if the field is not relevant.
However, when I assign null to the date prop of the DateTimePicker, I get an exception that null is not an object. How can allow the user to choose a date if they want to, but leave it "null" if they don't want a date in that field.
<DateTimePicker
isVisible={isDatePickerVisible}
mode={mode}
onConfirm={handleConfirm}
onCancel={hideDatePicker}
date={selectedDate}
onBlur={onBlur}
/>
Is there a property I am missing? Is there a different component I can use to accomplish this?
Thank you to @david-scholz for the insight into the react-native-datetimepicker library and the lack of null support. With that said, his answer doesn't provide the functionality requested.
I manage to implement it with a custom component which wraps the react-native-modal-datetimepicker library. The basic idea is to use the picker only when the user wants to pick a date.
To accomplish this:
Note: This was intended to be used with Formik (in my use case) so the date / time value being passed back is in string format (it works better with Formik).
Here is the code, in case anyone can use it. It should be considered MIT License.
import React, { useState } from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import DateTimePickerModal from 'react-native-modal-datetime-picker';
import moment from 'moment';
const isNullOrWhitespace = ( input ) => {
return !input || !input.trim();
}
export default function NullableDatePicker (props) {
const {value, onChange, onBlur} = props;
const [isDatePickerVisible, setDatePickerVisibility] = useState(false);
const [selectedDate, setSelectedDate] = useState(isNullOrWhitespace(value) ? new Date() : new Date(value));
const [hasDate, setHasDate] = useState(isNullOrWhitespace(value) ? false : true);
const showDatePicker = () => {
setDatePickerVisibility(true);
};
const hideDatePicker = () => {
setDatePickerVisibility(false);
};
const handleConfirm = date => {
hideDatePicker();
setHasDate(true);
setSelectedDate(new Date(date));
onChange(valueToString(date));
};
const valueToString = selectedDate => {
return moment(selectedDate).format('YYYY-MM-DD');
}
const clearDate = () => {
setHasDate(false);
onChange('');
}
return (
<View>
<View style={styles.fixToText}>
<Text style={styles.dateText} onPress={showDatePicker}>{hasDate ? valueToString(selectedDate) : 'No Date Selected'}</Text>
<Text> </Text>
<TouchableOpacity
title="Clear"
onPress={() => clearDate()}
disabled={!hasDate}
style={styles.button}
>
<Text>Clear</Text>
</TouchableOpacity>
</View>
<DateTimePickerModal
isVisible={isDatePickerVisible}
mode='date'
onConfirm={handleConfirm}
onCancel={hideDatePicker}
date={selectedDate}
onBlur={onBlur}
/>
</View>
);
}
const styles = StyleSheet.create(
{
fixToText: {
flexDirection: 'row'
},
button: {
alignItems: "center",
backgroundColor: "lightblue",
padding: 5,
height: 30,
width: 50
},
dateText:{
height: 30,
textAlignVertical: 'center'
}
}
)