Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
21
rated 0 times [  27] [ 6]  / answers: 1 / hits: 18172  / 3 Years ago, thu, june 24, 2021, 12:00:00

I want to create a custom validation starting from the validation below. But I'm not successful so far. I had visited this site and followed the codes in his "Custom validation rules" but I can't replicate it.


The isBefore method is working fine, but the validation does not. And also how can we put a custom message with this custom validation?


const isBefore = (date1, date2) => moment(date1).isBefore(moment(date2));

const rules = {
publishedDate: {
required: 'The published date is required.',
before: isBefore(scheduledDate, expiredDate)
},
}

<Controller
control={control}
name="publishedDate"
rules={rules.publishedDate}
render={({ onChange }) => (
<DatePicker
className="mb-px-8"
onChange={(value) => {
setPublishedDate(value);
onChange(value);
}}
minDate={new Date()}
value={publishedDate}
/>
)}
/>

More From » reactjs

 Answers
24

Here is my attempt:


you need to use the hook useEffect and a controller.
at the top of the page you need these two imports:


import React, { useEffect } from "react";
import { Controller, useForm } from "react-hook-form";

then you need the validation function this lives outside of the component.


const isBefore = (date) => {
if (!date) {
return false;
}
const today = new Date();
today.setHours(0, 0, 0, 0);
return date > today;
};

The above function checks that the date you picked is in the future and not the past.


Under your component you set everything to useForm


const {
register,
handleSubmit,
control,
setValue,
watch,
errors,
setError,
clearError
} = useForm();

You then setup variables to watch for the datepicker to update, along with useEffect to watch for the change:


  const startDate = watch("startDate");
useEffect(() => {
register({ name: "startDate", type: "custom" }, { validate: { isBefore } });
});



You then define a handler inside of the component that handles the data change along with the validation.


  const handleDateChange = (dateType) => (date) => {
if (!isBefore(date)) {
setError(dateType, "isBefore");
} else {
setError(dateType, "isBefore");
}
setValue(dateType, date);
alert(date);
};


the custom error message can exist anywhere in the form and you don't need to tie a ref to it. the useForm() and watch('startDate') control the data for you.


Here is the custom error message that can live anywhere within the form component.


Please see updated codesandbox where I have the custom error message displayed near the submit button


              {errors.startDate && (
<div variant="danger">
{errors.startDate.type === "isBefore" && (
<p>Please choose present or future date!</p>
)}
</div>


Here is a working codesandbox that I cleaned up a bit from yesterday, and added in some comments.
https://codesandbox.io/s/play-momentjs-forked-1hu4s?file=/src/index.js:1494-1802


If you click the input and then choose a date in the past, and then click submit, the custom error message will show. However, if you select a date in the future and hit submit the message doesn't show.


Here is a resource I used:
https://eincode.com/blogs/learn-how-to-validate-custom-input-components-with-react-hook-form


Also more information on watch that you get from useForm function:
https://react-hook-form.com/api/useform/watch/


[#50250] Tuesday, May 25, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
estefanib

Total Points: 508
Total Questions: 104
Total Answers: 83

Location: Lebanon
Member since Sun, Aug 2, 2020
4 Years ago
;