React Hook Form + Material UI Datepickers and Luxon output formatting

Viewed 1495

I am working on a React application using React Hook Form, Material UI, and Luxon for Date parsing.

I have made a number of form fields reusable and all work great but am having some troubles with DatePickers and output formatting.

Basically, I want to take the value of my outputted DatePicker and TimePicker and format it correctly to send to the backend.

I have the following components:

DatePicker:

import React from "react";
import PropTypes from "prop-types";
import {Controller, useFormContext} from "react-hook-form";
import DatePicker from '@mui/lab/DatePicker';
import DateAdapter from '@mui/lab/AdapterLuxon';
import LocalizationProvider from '@mui/lab/LocalizationProvider';
import TextInput from "../TextInput/TextInput";

export const DATE_INPUT_FORMAT = "MM/dd/yyyy";

export const DateInput = ({name, label, defaultValue, ...props}) => {
    const {control, register, formState: {errors}} = useFormContext();
    return (
        <Controller
            name={name}
            control={control}
            render={({field}) => (
                <LocalizationProvider dateAdapter={DateAdapter}>
                    <DatePicker
                        {...field}
                        inputFormat={DATE_INPUT_FORMAT}
                        renderInput={(props) => (
                            <TextInput
                                label={label}
                                defaultValue={defaultValue}
                                {...register(name)}
                                error={!!errors[name]}
                                helperText={errors[name] ? errors[name]?.message : ''}
                                {...props}
                            />
                        )}
                        {...props}
                    />
                </LocalizationProvider>
            )}
        />
    )
};

DateInput.propTypes = {
    name: PropTypes.string.isRequired,
    label: PropTypes.string,
    defaultValue: PropTypes.string
};

DateInput.defaultProps = {
    label: "",
    defaultValue: "",
};

export default DateInput;

and TimePicker:

import React from "react";
import PropTypes from "prop-types";
import {Controller, useFormContext} from "react-hook-form";
import TimePicker from '@mui/lab/TimePicker';
import DateAdapter from '@mui/lab/AdapterLuxon';
import LocalizationProvider from '@mui/lab/LocalizationProvider';
import TextInput from "../TextInput/TextInput";

export const TIME_INPUT_FORMAT = "hh:mm a";

export const TimeInput = ({name, label, defaultValue, ...props}) => {
    const {control, register, formState: {errors}} = useFormContext();
    return (
        <Controller
            name={name}
            control={control}
            render={({field}) => (
                <LocalizationProvider dateAdapter={DateAdapter}>
                    <TimePicker
                        {...field}
                        inputFormat={TIME_INPUT_FORMAT}
                        renderInput={(props) => (
                            <TextInput
                                label={label}
                                defaultValue={defaultValue}
                                {...register(name)}
                                error={!!errors[name]}
                                helperText={errors[name] ? errors[name]?.message : ''}
                                {...props}
                            />
                        )}
                        {...props}
                    />
                </LocalizationProvider>
            )}
        />
    )
};

TimeInput.propTypes = {
    name: PropTypes.string.isRequired,
    label: PropTypes.string,
    defaultValue: PropTypes.string
};

TimeInput.defaultProps = {
    label: "",
    defaultValue: "",
};

export default TimeInput;

which both use Luxon as the dateAdpater. The form works well and the values update fine. However, when handling my onSubmit, I am reading the form values and sending them back to the backend and my DatePicker and TimePicker are returning their values in the following format:

Date: "Sat Nov 13 2021 23:36:59 GMT-0500 (Eastern Standard Time)"

Time: "2021-11-02T18:30:03.317-04:00"

where the date is correctly set for the date and the time is correctly set for the time. I assumed the values coming from reading the values on the UI would return in a Luxon Date format or at least be easily parsable into a Luxon Date format. This way I could combine and format them to a datetime string such that the DB will accept them.

I understand I could manually parse the date string but I assumed there must be a better way to do this. However, I have searched for hours looking through Luxon and MUI docs and have not had any luck.

Any help with this would be greatly appreciated.

As an example:

I take the two form values and pass them into a function like:

export const formatDateAndTimeToDatetimeField = (date, time) => {
    const dateParsed = {Something here};
    const timeParsed = {Something here};
    const datetime = Datetime.fromObject({
        year: dateParsed.year,
        month: dateParsed.month,
        day: dateParsed.day,
        hour: timeParsed.hour,
        minute: timeParsed.minute,
    });
    return datetime.toUTC().toFormat("yyyy-MM-dd hh:mm:ss+00:00");
}

where I can't quite figure out the {Something here} without writing code to explicitly parse the string. I assume there must be a more robust/easier solution from Luxon but I couldn't find it anywhere

Thanks for any help in advance.

0 Answers
Related