Issue
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?
Solution
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:
- text is used to display the current value or "No Date Selected".
- When the user clicks the text, the date time picker is shown to let them select a date
- There is a button to click if the user wants to clear the date and go back to null
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'
}
}
)
Answered By - David Schwartz
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.