I am creating a form using react-bootstrap
, react-hook-form
, and yup
for validation.
I have several fields that are not required like url
and radio
.
I have used a custom regex instead of yup
's url()
as it is really strict, for example not accepting google.com
or www.google.com
.
Also, there are radio
type fields like offerInternships
, offerVisaSponsorships
, offerRemoteWorking
which I have declared as notRequired
in yup
's schema.
The problem is when I press submit
button, errors are shown indicating that they must be filled, and I only be able to proceed if I filled them with correct values.
I am not really sure what could have gone wrong here.
Edit 1: I have modified the regex to accept empty strings by adding |^$
at the end of re
, and the url now can accept empty strings and act as if it's not required (I am not sure if this actually fixes the problem), but the radio
type's problem still exists.
import { Container, Row, Col, Button, Form } from "react-bootstrap";
import * as yup from "yup";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
/**
* Company's validation schema.
*/
const re =
/^((ftp|http|https):\/\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_-]+(\.[a-zA-Z]+)+((\/)[\w#]+)*(\/\w+\?[a-zA-Z0-9_]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/gm;
const formSchema = yup.object().shape({
url: yup.string().matches(re, "Enter a valid URL!").required(),
name: yup.string().required(),
location: yup.object().shape({
country: yup.string().required(),
state: yup.string().required(),
city: yup.string().required(),
address: yup.string().required(),
}),
offerInternships: yup.bool().default(false).notRequired(),
offerRemoteWork: yup.bool().default(false).notRequired(),
offerVisaSponsorship: yup.bool().default(false).notRequired(),
socialMedia: yup.object().shape({
Linkedin: yup.string().matches(re, "Enter a valid URL!").notRequired(),
GitHub: yup.string().matches(re, "Enter a valid URL!").notRequired(),
}),
});
const RequestForm = () => {
const {
register,
handleSubmit,
watch,
formState: { errors },
} = useForm({
resolver: yupResolver(formSchema),
mode: "all",
});
/**
* Handling the submittion of the form
*/
const onSubmit = async (data) => {
try {
console.log(errors);
console.log(data);
} catch (error) {
console.log(error);
}
};
return (
<>
<Container id="RequestForm-UserForm" className="mt-5 outer-border p-5">
<Form onSubmit={handleSubmit(onSubmit)}>
<Row id="company-details-row">
<Col id="company-details-row-input" sm={12} md={9}>
<Form.Group className="mb-2" controlId="formBasicEmail">
<Form.Label>Company's name</Form.Label>
<Form.Control
type="text"
placeholder="e.g. Microsoft"
{...register("name")}
isInvalid={!!errors?.name}
/>
</Form.Group>
<Form.Group className="mb-2" controlId="formBasicEmail">
<Form.Label>Company's website</Form.Label>
<Form.Control
type="text"
placeholder="e.g. https://www.microsoft.com"
{...register("url")}
isInvalid={!!errors.url}
/>
</Form.Group>
<h3 className="mb-0">Location</h3>
<Form.Group className="mb-2" controlId="formBasicEmail">
<Form.Label>Country</Form.Label>
<Form.Control
type="text"
placeholder="e.g. Egypt, United States of America,...etc."
{...register("location.country")}
isInvalid={!!errors.location?.country}
/>
</Form.Group>
<Form.Group className="mb-2" controlId="formBasicEmail">
<Form.Label>State/Governorate</Form.Label>
<Form.Control
type="text"
placeholder="e.g. Cairo, California, Berlin...etc."
{...register("location.state")}
isInvalid={!!errors.location?.state}
/>
</Form.Group>
<Form.Group className="mb-2" controlId="formBasicEmail">
<Form.Label>City</Form.Label>
<Form.Control
type="text"
placeholder="e.g. Maadi, San Francisco,...etc."
{...register("location.city")}
isInvalid={!!errors.location?.city}
/>
</Form.Group>
<Form.Group className="mb-2" controlId="formBasicEmail">
<Form.Label>Address</Form.Label>
<Form.Control
type="text"
placeholder="e.g. 14th Zaki Sayed St."
{...register("location.address")}
isInvalid={!!errors.location?.address}
/>
</Form.Group>
<h3 className="mt-2 mb-0">Social Media</h3>
<Form.Group className="mb-2" controlId="formBasicEmail">
<Form.Label>
<i className="icon ion-social-linkedin"></i> Linkedin
</Form.Label>
<Form.Control
type="text"
placeholder="e.g. https://www.linkedin.com/company/x"
{...register("socialMedia.Linkedin")}
isInvalid={!!errors.socialMedia?.Linkedin}
/>
</Form.Group>
<Form.Group className="mb-2" controlId="formBasicEmail">
<Form.Label>
<i className="icon ion-social-github"></i> GitHub
</Form.Label>
<Form.Control
type="text"
placeholder="e.g. https://www.github.com/company"
{...register("socialMedia.GitHub")}
isInvalid={!!errors.socialMedia?.GitHub}
/>
</Form.Group>
<h3 className="mt-2 mb-0">Culture & Environment</h3>
<div id="offer-Internship" key={"inline-radio-internships"}>
<Form.Label>Does your company offer internships? </Form.Label>
<br></br>
<Form.Check
inline
label="Yes"
value={"true"}
{...register("offerInternships", { required: false })}
type={"radio"}
isInvalid={!!errors.offerInternships}
/>
<Form.Check
inline
label="No"
value={"false"}
{...register("offerInternships", { required: false })}
type={"radio"}
isInvalid={!!errors.offerInternships}
/>
</div>
<div id="offer-VisaSponsorship" key={"inline-radio-visa"}>
<Form.Label>
Does your company offer visa sponsorship? ✈️
</Form.Label>
<br></br>
<Form.Check
inline
label="Yes"
value={"true"}
{...register("offerVisaSponsorship", { required: false })}
type={"radio"}
isInvalid={!!errors.offerVisaSponsorship}
/>
<Form.Check
{...register("offerVisaSponsorship", { required: false })}
inline
label="No"
value={"false"}
type={"radio"}
isInvalid={!!errors.offerVisaSponsorship}
/>
</div>
<div id="offer-remoteWork" key={"inline-radio-remote"}>
<Form.Label>
Does your company offer remote working? ️
</Form.Label>
<br></br>
<Form.Check
{...register("offerRemoteWork", { required: false })}
inline
label="Yes"
value={"true"}
type={"radio"}
isInvalid={!!errors.offerRemoteWork}
/>
<Form.Check
{...register("offerRemoteWork", { required: false })}
inline
label="No"
value={"false"}
type={"radio"}
isInvalid={!!errors.offerRemoteWork}
/>
</div>
</Col>
</Row>
<Row id="company-submit text-center">
<Col className={"text-center"} sm={12}>
<h2 className="fs-1 main-color-1-dark">
We have reached to the end of the form!
</h2>
<Button variant="success" type="submit" className="rubik-font">
Submit form
</Button>
</Col>
</Row>
</Form>
</Container>
</>
);
};
export default RequestForm;