I am using React Hook Form validation with Yup. I would like the validation on phone number to update as the user is typing but it is only showing once the user clicks out of the input or hits submit. I have the mode set to 'all'. This is a valid format for phone number:
(000) 000-0000
After the user types the first 3 digits, it is autoformatted with parenthesis. If the user clicks on the phone number input, then clicks out of it without typing a validation messages shows saying the phone number field is required. When the user then goes back to that field and starts typing that validation message should go away and the message from displaying the phone number in the correct format should display until that format condition is met then no validation messages should show. But that is not what is happening. The validation message doesn't update until the input loses focus.
const {control, handleSubmit, register, setValue, formState: {errors}} = useForm<IFormInput>({ mode: 'all', resolver: yupResolver(validationSchema)});
The validation schema I have setup for my other fields works just fine. It is the phone number field that I am having trouble with. I believe the issue is caused by the onChange function that I am passing into the input for phone number to format the phone number as they type.
This is how I am setting the validation schema:
export const validationSchema = Yup.object({
firstName: Yup.string().required('The first name field is required'),
phoneNumber: Yup.string()
.required('The phone number field is required')
.matches(/^\([\d]{3}\) [\d]{3}-[\d]{4}/,
'Please enter a valid US phone number formated as (000) 000-0000'
)
}).required();
This is the function I am using to format the phone number (imported from libphonenumber-js):
const onPhoneChange = (e: ChangeEvent<HTMLInputElement>) => {
let result = e.target.value;
if (/(.?\d){4,}/.test(result)) {
result = formatIncompletePhoneNumber(result, 'US');
}
setValue('phoneNumber', result);
};
This is my react hook form controller:
<Controller
name="phoneNumber"
control={control}
defaultValue=""
render={({ field }) => (
<StyledInput
{...field}
id="phoneNumber"
placeholder="(000) 000-0000"
type="text"
includeLabel={true}
placeLabelAfter={true}
onChange={onPhoneChange}
/>
)}
/>
I tried changing the mode from 'all' to 'onChange' and also tried 'onTouched' and so no impact.
Looking for help.