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.