I am building a form in React using React-form-hook and validation using yup.
I am using a watch() to check if the checkbox is clicked or not and if it is clicked it will display another input field in the form which was not visible before.
Even when I haven’t clicked the checkbox which means that refer input field is not visible or rendered, it still does not perform the handlesubmit.
I can’t think of a way to get around this.
<div className="form-check"> <input type="checkbox" id="askRefer" {...register("askRefer")} /> <label className="form-check-label" htmlFor="askRefer"> Refered ? </label> </div> {referedStatus && ( <div className="form-group"> <label htmlFor="referedNumber">Refereed Number</label> <input type="text" className="form-control" placeholder="refer number" {...register("refer")} /> {errors.refer && ( <p className="error-message">{errors.refer.message}</p> )} </div> )}
Validation code in yup.
const valSchema = yup.object().shape({ email: yup.string() .required("email is required") .email("only accepts an email"), password: yup.string().required("password cannot be empty"), confirmPassword: yup.string() .required("confirmation of password is important") .oneOf([yup.ref("password"), null], "password doesn't match"), refer:yup.number() .required("please input refer number") .positive("entry should be greater than 0") .integer("input integer value")) });
Reat-hook-form:
const {register, handleSubmit, watch, formState: { errors }} = useForm({ resolver: yupResolver(valSchema), mode: "onTouched", }); let referedStatus= watch("askRefer", false);
If it helps, the complete code is here:
import React from "react"; import { useForm } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; import * as yup from "yup"; function Rform() { const valSchema = yup.object().shape({ email: yup .string() .required("email is required") .email("only accepts an email"), password: yup.string().required("password cannot be empty"), confirmPassword: yup .string() .required("confirmation of password is important") .oneOf([yup.ref("password"), null], "password doesn't match"), refer:(yup .number() .required("please input refer number") .positive("entry should be greater than 0") .integer("input integer value")) }); console.log(valSchema) const { register, handleSubmit, watch, formState: { errors }, } = useForm({ resolver: yupResolver(valSchema), mode: "onTouched", }); let referedStatus= watch("askRefer", false); const onSubmit = (formData) => { let url = "http://localhost:4000/things/register"; fetch(url, { method: "POST", headers: {'Content-Type': 'application/json'}, body: JSON.stringify(formData) }) .then((response) => response.json()) .then((result) => console.log(result)); }; console.log(referedStatus); return ( <div className="container" onSubmit={handleSubmit(onSubmit)}> <form> <div className="form-group"> <label>Email address</label> <input className="form-control" aria-describedby="emailHelp" placeholder="Enter email" {...register("email")} /> <small className="form-text text-muted"> We don't share the credential. </small> {errors.email && ( <p className="error-message">{errors.email.message}</p> )} </div> <div className="form-group"> <label>Password</label> <input type="password" className="form-control" placeholder="Password" {...register("password")} /> {errors.password && ( <p className="error-message">{errors.password.message}</p> )} </div> <div className="form-group"> <label>Password</label> <input type="password" className="form-control" placeholder="Password" {...register("confirmPassword")} /> {errors.confirmPassword && ( <p className="error-message">{errors.confirmPassword.message}</p> )} </div> <div className="form-check"> <input type="checkbox" id="askRefer" {...register("askRefer")} /> <label className="form-check-label" htmlFor="askRefer"> Refered ? </label> </div> {referedStatus && ( <div className="form-group"> <label htmlFor="referedNumber">Refereed Number</label> <input type="text" className="form-control" placeholder="refer number" {...register("refer")} /> {errors.refer && ( <p className="error-message">{errors.refer.message}</p> )} </div> )} <button type="submit" className="btn btn-primary"> Submit </button> </form> </div> ); } export default Rform;
This is what form looks like in the browser.
Advertisement
Answer
This is because the optional field “refer” (as long as “askRefer” is false
) is required in your yup schema. You have to add your “askRefer” checkbox to the yup schema and then you can check via the when
method, to set validation for “refer” if “askRefer” is true
.
const valSchema = yup.object().shape({ email: yup .string() .required("email is required") .email("only accepts an email"), password: yup.string().required("password cannot be empty"), confirmPassword: yup .string() .required("confirmation of password is important") .oneOf([yup.ref("password"), null], "password doesn't match"), askRefer: yup.boolean(), refer: yup.number().when("askRefer", { is: true, then: yup .number() .required("please input refer number") .positive("entry should be greater than 0") .integer("input integer value") }) });