The source code for this blog is available on GitHub.
Note
Top

Getting Started with Yup for Form Validation in JavaScript

Cover Image for Getting Started with Yup for Form Validation in JavaScript
Chen Han
Chen Han

Yup

Yup is a JavaScript library that makes it easy to validate and sanitize data, such as form inputs. It provides a simple and flexible API for defining validation rules and checking if data is valid. Yup uses a schema-based approach, which means that you can define a set of rules for your data in the form of a schema, and then use that schema to validate and sanitize your data.

One of the benefits of using Yup is that it can be used with a wide range of libraries and frameworks, including React. In particular, Yup can be used in conjunction with React Hook Form, a popular library for managing forms in React. React Hook Form provides a set of hooks and components that make it easy to build and manage forms in a React application, and it integrates seamlessly with Yup to provide form validation.

To use Yup with React Hook Form, you can define a Yup schema for your form data and pass it to the validationSchema prop of the Form component provided by React Hook Form. Then, you can use the Controller component provided by React Hook Form to wrap each form input, and pass the name prop to the name prop of the Controller component to bind the input to the corresponding field in the Yup schema. This will cause React Hook Form to automatically validate the input based on the rules defined in the Yup schema, and provide feedback to the user if the input is invalid.

Overall, Yup is a powerful tool for form validation that can be easily integrated with React Hook Form to provide reliable and user-friendly form validation in a React application.

Examples

Sign up

const schema = yup
  .object({
    firstName: yup.string().required("First Name is mandatory"),
    lastName: yup.string().required("Last Name is mandatory"),
    email: yup.string().required().email(),
    password: yup
      .string()
      .required("No password provided.")
      .min(7, "Password must be at 7 char long")
      .matches(
        /[A-Za-z\d@$!%*#?&]/,
        "Only numbers and alphabetic characters are allowed"
      )
      .matches(
        /^(?=.*[A-Za-z])/,
        "Must contain at least one alphabetic  character"
      )
      .matches(/^(?=.*[0-9])/, "Must contain at least one number"),
    confirmPwd: yup
      .string()
      .oneOf([yup.ref("password")], "Passwords does not match"),
  })
  .required();

login

const schema = yup
  .object({
    email: yup.string().required().email(),
    password: yup.string().required(),
  })
  .required();

Update password

const schema = yup
  .object({
    oldPassword: yup.string().required("No password provided.")
      .min(7, "Password must be at 7 char long")
      .matches(
        /[A-Za-z\d@$!%*#?&]/,
        "Only numbers and alphabetic characters are allowed"
      )
      .matches(
        /^(?=.*[A-Za-z])/,
        "Must contain at least one alphabetic  character"
      )
      .matches(/^(?=.*[0-9])/, "Must contain at least one number"),
    password: yup.string().when("updatePassword", {
      is: true,
      then: yup
        .string()
        .required("No password provided.")
        .min(7, "Password must be at 7 char long")
        .matches(
          /[A-Za-z\d@$!%*#?&]/,
          "Only numbers and alphabetic characters are allowed"
        )
        .matches(
          /^(?=.*[A-Za-z])/,
          "Must contain at least one alphabetic  character"
        )
        .matches(/^(?=.*[0-9])/, "Must contain at least one number")
        .notOneOf([yup.ref("oldPassword")], "Cannot be same as the previous password"),
    }),
    confirmPwd: yup.string().when("updatePassword", {
      is: true,
      then: yup
        .string()
        .oneOf([yup.ref("password")], "Passwords does not match"),
    }),
  })
  .required();

promo code

/**
 * yup with api call:
 *   https://stackoverflow.com/questions/55811114/async-validation-with-formik-yup-and-react
 */
const schema = yup.object({
  promoCode: yup
    .string()
    .required("Promotion code is mandatory")
    .test(
      "checkCouponNameUnique",
      "The coupon is not exist.",
      function (value) {
        return new Promise((resolve, reject) => {
          fetch("/api/bc/coupons")
            .then((res) => res.json())
            .then((data) => {
              const codes = data.map((d) => d.code);
              util.c("list all codes:", codes);
              resolve(codes.includes(value));
            })
            .catch(() => {
              // note exists
              resolve(false);
            });
          // resolve(true);
        });
      }
    ).test(
      "checkCouponNameUnique",
      "The coupon is invalid.",
      function (value) {
        return new Promise(async (resolve, reject) => {
          try {
            const response = await httpService.post("/api/bc/coupons", {
              couponCode: value,
              cartId: getCookie("cartId")
            })

            resolve(response.statusText === "OK")
          } catch (e) {
            setCurrentSnackBar(() => ({
              display: true,
              type: "error",
              heroText: "error",
              bodyText: e.response?.data?.title || "The coupon is invalid.",
            }));
            resolve(false);
          }
        });
      }
    ),
});

checkout Information

const schema = yup
  .object({
    firstName: yup.string().required("First Name is mandatory").min(2,'must be 2 characters').matches(
      /[A-Za-z\d@$!%*#?&]/,
      "Only numbers and alphabetic characters are allowed"
    ),
    lastName: yup.string().required("Last Name is mandatory").min(2,'must be 2 characters').matches(
      /[A-Za-z\d@$!%*#?&]/,
      "Only numbers and alphabetic characters are allowed"
    ),
    shippingAddress: yup.string(),
    billingAddress: yup.string(),
    deliveryOptions: yup.string(),
    email: yup.string().required().email(),
    phone: yup.string().required(),
    password: yup.string().when('createAccount', {
      is: true,
      then: yup.string().required('No password provided.').min(7, 'Password must be at 7 char long').matches(
        /[A-Za-z\d@$!%*#?&]/,
        "Only numbers and alphabetic characters are allowed"
      ).matches(/^(?=.*[A-Za-z])/, 'Must contain at least one alphabetic  character').matches(/^(?=.*[0-9])/, 'Must contain at least one number')
    }),
    confirmPwd: yup.string().oneOf([yup.ref("password")], "Passwords does not match"),
    checkMark: yup.number().typeError("You should choose at least one option"),
  })
  .required();

password

/**
 * yup password:
 *   https://www.positronx.io/add-confirm-password-validation-in-react-with-hook-form/
 *
 * Caveats:
 *   When unregister the password, the validation still exists
 *
 * Examples:
 *   password: yup
 *     .string()
 *     .required('Please Enter your password')
 *     .matches(
 *       /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})/,
 *       "Must Contain 8 Characters, One Uppercase, One Lowercase, One Number and One Special Case Character"
 *     ),
 *
 *   password: yup
 *     .string()
 *     .required('Please Enter your password')
 *     .matches(
 *       /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/,
 *       "Must Contain 8 Characters, One Uppercase, One Lowercase, One Number and one special case Character"
 *     ),
 */

simple demo

undefined
© 2024 WOOTHINK. All Rights Reserved.
Site MapTerms and ConditionsPrivacy PolicyCookie Policy