setValue in react hook form not working with react-datepicker - reactjs

While i setting value dynamically to react-datepicker throwing an error "RangeError: Invalid time value"
This is my datepciker code
<Controller
control={control}
className="form-control"
name="from_date"
render={({ field }) => (
<DatePicker
onChange={(e) => field.onChange(e)}
selected={field.value}
dateFormat="dd-MM-yyyy"
minDate={new Date()}
/>
)}
{...register("from_date", { required: true })}/>
This is how i setting value to datepicker
var mydate = moment(date_from_db, 'DD-MM-YYYY').format("DD-MM-YYYY");
setValue('date_field', mydate)
Can anyone explain whats wrong with my code?

Try doing
<Controller
control={control}
className="form-control"
name="from_date"
render={({ field }) => (
<DatePicker
onChange={(e) => field.onChange(e)}
selected={field.value}
dateFormat="dd-MM-yyyy"
minDate={new Date()}
/>
)}
{...register("from_date", { required: true })}/>
var mydate = moment(date_from_db).format("DD-MM-YYYY");
setValue('from_date', mydate)

Related

how can i get the date inside inputDate and use it inside another inputDate - ReactJS

How can i use the date of "start_contract_time" in minValue of "end_contract_time".
The user will fill the field with his intended date. I need to get this date in the "start_contract_time" and then use it as a min value in "end_contract_time".
<FormControl>
<Controller
control={control}
name="start_contract_time"
render={({ field: { onChange, value } }) => (
<InputDate
label='InĂ­cio do contrato'
dateFormat="dd/MM/yyyy"
locale={ptBR}
onChange={onChange}
onBlur={onChange}
selected={value}
/>
)}
/>
</FormControl>
<FormControl>
<Controller
control={control}
name="end_contract_time"
render={({ field: { onChange, value } }) => (
<InputDate
minDate={DATE HERE}
label='Fim do contrato'
dateFormat="dd/MM/yyyy"
locale={ptBR}
onChange={onChange}
onBlur={onChange}
selected={value}
/>
)}
/>
</FormControl>

I want to disable end date picker before choosing start date picker in react js

Is it possible to disable the end date picker until the user enters the start date? Below I am sharing my code. Please tell me where I am doing wrong?
const startDate = new Date();
<Controller control={control} name="start_date" render={({ field }) => (
<DatePicker placeholderText="MM/dd/yyyy" dateFormat="MM/dd/yyyy"
onChange={(date) => field.onChange(date)} minDate={moment().toDate()}
selected={field.value}
id="start_dates"
required={true}
autoComplete='off'
onKeyDown={(e) => {
e.preventDefault();
}} />)}/>
<Controller control={control} name="end_date" render={({ field }) => (
<DatePicker dateFormat="MM/dd/yyyy"
onChange={(date) => field.onChange(date)}
disabled={startDate=== ""? true: false}
minDate={new Date(startDate)}
selected={field.value}
onKeyDown={(e) => {
e.preventDefault(); }} />)}/>
Create state variable dateStart.
In onChange event of startDate set its value, then disable endDate based on dateStart like this:
const [dateStart, setDateStart] = useState(null);
StartDate datepicker
<DatePicker placeholderText="MM/dd/yyyy" dateFormat="MM/dd/yyyy"
onChange={(date) => field.onChange(date); setDateStart(date)}
minDate={moment().toDate()}
selected={field.value}
id="start_dates"
required={true}
autoComplete='off'
onKeyDown={(e) => {
e.preventDefault();
}} />)}
/>
EndDate datepicker
<DatePicker dateFormat="MM/dd/yyyy"
onChange={(date) => field.onChange(date)}
disabled={dateStart ? false : true}
minDate={new Date(startDate)}
selected={field.value}
onKeyDown={(e) => {
e.preventDefault(); }} />)}
/>
Working example

react-datepicker and react-hook-forms: required not working

React-datepicker and react-hook-form. I am trying to make react-datepicker required, but its not working
<Controller
name="resetDateTime"
control={control}
required
render={({ field }) => (
<Datetime
onChange={(date) => field.onChange(date)}
selected={field.value}
inputProps={{
placeholder: "MM-DD-YYYY HH:mm",
}}
viewMode="time"
/>
)}
/>
{errors.resetDateTime && <span>This field is required</span>}
When I submit form without selecting any datetime, I am expecting the error to be show, but instead it submits the form
<Controller /> has no required prop, instead of you have to pass the validation rules via the rules prop. Check the docs for more info.
<Controller
name="resetDateTime"
control={control}
rules={{ required: true }}
render={({ field }) => (
<Datetime
onChange={(date) => field.onChange(date)}
selected={field.value}
inputProps={{
placeholder: "MM-DD-YYYY HH:mm",
}}
viewMode="time"
/>
)}
/>
{errors.resetDateTime && <span>This field is required</span>}

How to validate KeyboardDatePicker with react-hook-form when date is invalid

I am validating a material UI KeyboardDatePicker with react-hook-form:
<Controller
name="endDate"
control={control}
defaultValue={new Date()}
rules={{
required: "End date is required"
}}
render={({ field, fieldState }) => {
return (
<KeyboardDatePicker
autoOk
variant="inline"
inputVariant="standard"
label="End Date"
format="MM/dd/yyyy"
value={field.value}
InputAdornmentProps={{ position: "start" }}
onChange={() => {
field.onChange();
}}
error={(!!fieldState.error || field.value === 'Invalid Date')}
helperText={
fieldState.error ? fieldState.error.message : null
}
/>
);
}}
/>
It works fine and throws the message "End date is required" if KeyboardDatePicker is empty. However I also need to throw an error message "Invalid date format" if user edits the date and removes a couple of characters like '06/01/2021' to '06/01/20__'. This functionality works built-in and works fine in isolation i.e. if I don't combine date picker with react-hook-form.
However I am not getting how to achieve this in combination with react-hook-form. I tried to modify helperText but to no avail.
This is how I do it :
<Controller
name="endDate"
control={control}
defaultValue={new Date()}
rules={{ required: true }}
render={({ field: { ref, ...rest } }) => (
<KeyboardDatePicker
margin="normal"
id="date-picker-dialog"
format="dd/MM/yyyy"
disablePast={true}
initialFocusedDate={Date.now()}
KeyboardButtonProps={{
"aria-label": "change end date",
}}
invalidDateMessage={"End date is required"}
{...rest}
/>
)}
/>

React Hook Form with datepicker Range doesn't pick date

I got the following datepickers.
For the Start Date:
<Controller
as={
<DatePicker
selected={travelRoute?.dateStart || new Date()}
selectsStart
startDate={travelRoute?.dateStart}
endDate={travelRoute?.dateEnd}
inline
/>
}
control={control}
rules={{ required: true }}
valueName="selected"
onChange={date => handleStartDateOnChange(date)}
name="dateStart"
placeholderText="Select date"
defaultValue={null}
/>
For the End Date:
<Controller
as={
<DatePicker
name="dateEnd"
selected={travelRoute?.dateEnd || new Date()}
onChange={date => handleEndDateOnChange(date)}
selectsEnd
startDate={travelRoute?.dateStart}
endDate={travelRoute?.dateEnd}
minDate={travelRoute?.dateStart}
inline
/>
}
control={control}
rules={{ required: true }}
valueName="selected"
onChange={date => handleEndDateOnChange(date)}
name="dateEnd"
placeholderText="Select date"
defaultValue={null}
/>
Do I need to add the datepicker props to the datepicker component or to the Controller Component?
The start Datepicker doesn't select the date and the end Datepicker doesn't change the startdate and isn't displaying the range.
I'm saving the data into the travelRoute state with setTravelRoute which is happening in the handleOnChange functions.
EDIT:
Added onChange handler:
const handleStartDateOnChange = date => {
setTravelRoute(prevState => ({
...prevState,
dateStart: date
}))
};
const handleEndDateOnChange = date => {
setTravelRoute(prevState => ({
...prevState,
dateEnd: date
}))
};
Ciao, you are using the wrong approach to customize your onChange event in DatePicker. And onChange event on Controller can't work neihter. Because in this case, you don't have to use as= syntax, but render= syntax like:
<Controller
render={({ onChange }) => (
<DatePicker
...
onChange={date => handleStartDateOnChange(date)}
/>
)}
...
/>
So your code becomes:
Start Date
<Controller
render={({ onChange }) => (
<DatePicker
selected={travelRoute?.dateStart || new Date()}
selectsStart
startDate={travelRoute?.dateStart}
endDate={travelRoute?.dateEnd}
inline
onChange={date => handleStartDateOnChange(date)}
/>
)}
control={control}
rules={{ required: true }}
valueName="selected"
name="dateStart"
placeholderText="Select date"
defaultValue={null}
/>
End Date
<Controller
render={({ onChange }) => (
<DatePicker
name="dateEnd"
selected={travelRoute?.dateEnd || new Date()}
onChange={date => handleEndDateOnChange(date)}
selectsEnd
startDate={travelRoute?.dateStart}
endDate={travelRoute?.dateEnd}
minDate={travelRoute?.dateStart}
inline
/>
)}
control={control}
rules={{ required: true }}
valueName="selected"
name="dateEnd"
placeholderText="Select date"
defaultValue={null}
/>
Here a working example.
Note: I don't know why DatePicker in codesandbox looks so ugly. Could be the Controller because in this other codesandbox looks good.
I have had a different approach to the solution of this issue and wanted to share it.
I answered some related issue in the following post: https://stackoverflow.com/a/72585781/19320134
Anyway, one way to make the code more reusable is to put these controllers in separate files, so that only the function name is imported when calling them.
export const DateRange = ({ name, control, label }) => {
const [dateRange, setDateRange] = useState([null, null]);
const [startDate, endDate] = dateRange;
return (
<Controller
//is a prop that we get back from the useForm Hook and pass into the input.
control={control}
//is how React Hook Form tracks the value of an input internally.
name={name}
//render is the most important prop; we pass a render function here.
render={({
//The function has three keys: field , fieldState, and formState.
field, // The field object exports two things (among others): value and onChange
}) => (
<>
<DatePicker
selectsRange={true}
startDate={startDate}
endDate={endDate}
onChange={(e) => {
setDateRange(e);
field.onChange(e);
}}
isClearable={true}
className="form-control"
/>
</>
)}
rules={{
required: `The ${label} field is required`,
}}
/>
And you can call it in the necesary file like this
import { useForm, Controller, FormProvider } from "react-hook-form";
import {DateRange} from "./your file !"
const defaultValues = {
dateRange: [],
};
export default function ComponentUsingDateRange() {
const methods = useForm({
defaultValues,
mode: "onChange",
});
const { register, handleSubmit, control, setValue } = methods;
return(
<>
<FormProvider {...methods}>
<DateRange
control={control}
name="dateRange"
label="Range of dates"
/>
</FormProvider>
</>
);
}

Resources