Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling value of DateTimePicker in React Native with Formik

I am using Formik to create a reminder form that store some information, including date and time. And I've encountered a problem while using DateTimePicker from react-native-modal-datetime-picker in my form.

My main goal is when a user press a Date or Time input, DateTimePicker will be shown. After user choose the time, DateTimePicker will pass that value to the input and display that input onto screen. And when user press 'Submit' button, log console will print out the values props of Formik

Here is my code:

import React from 'react'
import {View, TouchableOpacity} from 'react-native'
import {Button, Input} from 'react-native-elements'
import ModalDropdown from 'react-native-modal-dropdown'
import DateTimePicker from 'react-native-modal-datetime-picker'
import {Formik} from 'formik'
import * as yup from 'yup'

export default class ReminderForm extends React.Component{
    constructor(props){
        super(props);
        this.state = {
           isDatePickerVisible: false,
           isTimePickerVisible: false,
           reminder: {
               date: '',
               time: '',
               //...more properties go here
           }
        }
    }
    showDatePicker = () => {//show the picker for Date input
        this.setState({ isDatePickerVisible: true });
    };

    hideDatePicker = () => {
        this.setState({ isDatePickerVisible: false });
    };
    handleDatePicked = date => {
        let newDate = new Date(date).toLocaleDateString();
        this.setState(prevState=> ({
            ...prevState,
            isDatePickerVisible: !prevState.isDatePickerVisible,
            reminder: {
                ...prevState.reminder,
                date: newDate
            }
        }));
        console.log(this.state);
    };
    showTimePicker = () => {//show the picker for time input
        this.setState({ isTimePickerVisible: true });
    };

    hideTimePicker = () => {
        this.setState({ isTimePickerVisible: false });
    };
    handleTimePicked = time => {
        let newTime = new Date(time).toLocaleTimeString();
        this.setState(prevState=> ({
            ...prevState,
            isTimePickerVisible: !prevState.isTimePickerVisible,
            reminder: {
                ...prevState.reminder,
                time: newTime
            }
        }))
        console.log(this.state)
    };
    render(){
        return(
            <View style = {{flex:1}}>
                 <Formik initialValues = {this.state.reminder}
                        onSubmit={()=> console.log('Submitted')}
                       >
                     {
                         ({values,handleChange,errors,setFieldTouched,touched,isValid,handleSubmit})=>(
                            <View style ={{flex:1, justifyContent:'space-around'}}>
                                <TouchableOpacity style ={{flex:1, marginTop: 10, marginBottom:10, backgroundColor:null}}
                                                  onPress={this.showDatePicker}>
                                    <Input value = {values.date}  inputContainerStyle={{height: '60%'}} onChangeText={handleChange('date')}
                                           onBlur={()=>setFieldTouched('date')} label = "Date" labelStyle = {{fontSize: 15}}/>
                                </TouchableOpacity>  
                                <DateTimePicker mode="date" isVisible={this.state.isDatePickerVisible} 
                                                 onConfirm={this.handleDatePicked} onCancel={this.hideDatePicker}/>
                                <TouchableOpacity style ={{flex:1, marginTop: 10, marginBottom:10, backgroundColor:null}}
                                                  onPress={this.showTimePicker}>
                                    <Input value = {values.time}  
                                           onChangeText={handleChange('time')} inputContainerStyle={{height: '60%'}}
                                           onBlur={()=>setFieldTouched('time')} label = "Time" labelStyle = {{fontSize: 15}}/>
                                </TouchableOpacity>          
                                <DateTimePicker mode="time" isVisible={this.state.isTimePickerVisible} 
                                                 onConfirm={this.handleTimePicked} onCancel={this.hideTimePicker}/>

                             //..more inputs go here
                                 <Button containerStyle = {{flex:1, marginTop: 10, marginBottom:0}} TouchableComponent={TouchableOpacity}
                                        onPress={()=> console.log(values)}  title = "Submit" titleStyle = {{fontSize: 15}}/> 


                            </View> 
                         )
                     }
                 </Formik>
            </View>
         )
    }

}

When I ran this code, date and time input did not show the value I chose in DateTimePikcker before, and when I submit form date and time property in values props got null. Then I tried to fix the input's attribute:

 <TouchableOpacity style ={{flex:1, marginTop: 10, marginBottom:10, backgroundColor:null}}
                                                  onPress={this.showDatePicker}>
                                    <Input value = {this.state.reminder.date}  inputContainerStyle={{height: '60%'}} onChangeText={handleChange('date')}
                                           onBlur={()=>setFieldTouched('date')} label = "Date" labelStyle = {{fontSize: 15}}/>
                                </TouchableOpacity>

In this time the input did show value I chose from DateTimePicker but when I submit form the date property still return to null. The problem is that I don't know how to change the property in the values props of Formik when user chooses date in DateTimePicker. Can you guy help me to figure it out?

And one more problem is that handleSubmit props does not work in here. I try to put the console.log() in onSubmit attribute (you can see in my code above) but it's not working.

like image 370
Quang Bình Đinh Avatar asked Sep 01 '25 03:09

Quang Bình Đinh


1 Answers

Below is an example. Notice the use of Formik's setFieldValue.

import React, { useState } from 'react';
import { Button, Text, View } from 'react-native';
import { Formik } from 'formik';
import DateTimePickerModal from 'react-native-modal-datetime-picker';
import moment from 'moment';

export default function Example() {
  return (
    <Formik initialValues={{ myDate: moment().format('YYYY-MM-DD') }} onSubmit={values => console.log(values)}>
      {({ handleSubmit, values, setFieldValue }) => (
        <MyForm values={values} setFieldValue={setFieldValue} handleSubmit={handleSubmit} />
      )}
    </Formik>
  );
}

export const MyForm = props => {
  const { handleSubmit, values, setFieldValue } = props;
  const [isDatePickerVisible, setDatePickerVisibility] = useState(false);

  const showDatePicker = () => {
    setDatePickerVisibility(true);
  };

  const hideDatePicker = () => {
    setDatePickerVisibility(false);
  };

  const handleConfirm = date => {
    setFieldValue('myDate', moment(date).format('YYYY-MM-DD'))
    hideDatePicker();
  };

  return (
    <View>
      <Text onPress={showDatePicker}>{moment(values.myDate).format('YYYY-MM-DD')}</Text>
      <DateTimePickerModal
        isVisible={isDatePickerVisible}
        mode="date"
        onConfirm={handleConfirm}
        onCancel={hideDatePicker}
        date={moment(values.myDate).toDate()}
      />
      <Button title="Submit" onPress={handleSubmit} />
    </View>
  );
}
like image 66
Peter Pompeii Avatar answered Sep 02 '25 17:09

Peter Pompeii