Reputation: 2156
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}
/>
)}
/>
Upvotes: 14
Views: 49949
Reputation: 66
I found this helpful,
In a case you just want to add custom validation to your input:
const { register, handleSubmit, formState: { errors: formErrors }} = useForm()
const validateNoEmptySpaces = (value) => {
return value.trim().length > 3 || 'This field cannot contain only spaces';
};
Then in the input, insert like this:
<div className="onboarding-auth-form-grp">
<input className="" placeholder='Which Special name do him/her call you?' {...register('your_name', { required: 'This field is required', minLength: {value: 3, message: "This must exceed 3 characters"}, validate: validateNoEmptySpaces})} type="text" name="your_name" id="your_name" />
{formErrors.your_name && <span className="xui-form-error-msg">{formErrors.your_name.message}</span>}
</div>
Upvotes: 1
Reputation: 814
Try using rules of react-hook-form to add validations
<Controller
name="currentName"
control={control}
render={({ field }) => (
<TextField
value={field.value}
onChange={field.onChange}
inputRef={field.ref}
variant="outlined"
size="small"
fullWidth
autoComplete="off"
helperText={helperText}
/>
)}
rules={{
validate: {
required: (value) => {
if (value === "SomeValue") return 'Some Message';
if (!value) return '*Required';
}
},
maxLength: 5
}}
defaultValue=""
/>
Upvotes: 16
Reputation: 386
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/
Upvotes: 8