Search code examples
datepickerformatmomentjsredux-form

DatePicker date input with custom format


I want to stote dates in my state using redux-form. I use react-datepicker. To make the datepicker compatible with my redux-form i write:

import React, { PropTypes } from 'react';
import DatePicker from 'react-datepicker';
import moment from 'moment';
import 'react-datepicker/dist/react-datepicker.css';

    const MyDatePicker = ({ input, meta: { touched, error } }) => (
      <div>
        <DatePicker
          {...input} dateFormat="YYYY-MM-DD"
          selected={input.value ? moment(input.value) : null}
        />
        {
          touched && error &&
          <span className="error">
            {error}
          </span>
        }
      </div>
    );

    MyDatePicker.propTypes = {
      input: PropTypes.shape().isRequired,
      meta: PropTypes.shape().isRequired
    };

    export default MyDatePicker;

The problem is that when i choose date i want it to show as DD-MM-YYYY but i want the date to be saved in my state with the YYYY-MM-DD HH:MM:SS format. How to do this? I use the moment's format function but it did not seem to work


Solution

  • You should use the value lifecycle methods that redux-form provides for this.

    Use parse to format the value coming from react-datepicker for storage and format to parse the value from the store back for react-datepicker to present it. Example:

    function formatDateForInput(storedDate) {
      // the returned value will be available as `input.value`
      return moment(pickedDate).format('right format for your input')
    }
    
    function parseDateForStore(pickedDate) {
      // the returned value will be stored in the redux store
      return moment(storedDate).format('desired format for storage')
    }
    
    <Field
      component={ MyDatePicker }
      format={ formatDateForInput }
      parse={ parseDateForStore }
    />
    

    If this does not work for your, I would recommend checking if you need to put a custom onChange handler between the DatePicker and input prop provided by redux-form. Because it could be that the values DatePicker is using to call onChange are ones that redux-form does not understand. Like this:

    const MyDatePicker = ({ input, meta: { touched, error } }) => {
    
      const onChange = event => {
        const pickedDate = event.path.to.value;
        input.onChange(pickedDate);
      }
    
      return (
        <div>
          <DatePicker
            dateFormat="YYYY-MM-DD"
            selected={input.value ? moment(input.value) : null}
            onChange={ onChange }
          />
          {
            touched && error &&
            <span className="error">
              {error}
            </span>
          }
        </div>
      );
    }
    
    MyDatePicker.propTypes = {
      input: PropTypes.shape().isRequired,
      meta: PropTypes.shape().isRequired
    };
    
    export default MyDatePicker;
    

    Hope this helps!