1

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.

enter image description here

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;
miserylord
  • 300
  • 2
  • 15
  • `socialMedia` by example, is expecting an object with 2 optional items. are you sending an empty object ? if not, make the `yup.object()` optional as well. – Kevin Gilbert Feb 10 '23 at 15:43

0 Answers0