Getting Started with Yup for Form Validation in JavaScript
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