Published on

How to Do Password and Phone Validation with Yup and Formik ?

Authors
  • Name
    Ripal & Zalak
    Twitter

How to Do Password and Phone Validation with Yup and Formik ?

Validation Schema

Create a validation schema using Yup. This example enforces strong password rules:

import * as Yup from 'yup'

const validationSchema = Yup.object({
  password: Yup.string()
    .required('Password is required')
    .min(8, 'Password must be at least 8 characters')
    .matches(/[a-z]/, 'Password must contain at least one lowercase letter')
    .matches(/[A-Z]/, 'Password must contain at least one uppercase letter')
    .matches(/[0-9]/, 'Password must contain at least one number')
    .matches(/[!@#$%^&*(),.?":{}|<>]/, 'Password must contain at least one special character'),
  confirmPassword: Yup.string()
    .oneOf([Yup.ref('password'), null], 'Passwords must match')
    .required('Confirm Password is required'),
})

Adding Phone Number Validation

For phone number validation, we use a regular expression. This example demonstrates validation for international and standard phone number formats:

const phoneRegExp =
  /^((\+[1-9]{1,4}[ \-]*)|(\([0-9]{2,3}\)[ \-]*)|([0-9]{2,4})[ \-]*)*?[0-9]{3,4}?[ \-]*[0-9]{3,4}?$/

const validationSchema = Yup.object({
  phone: Yup.string()
    .matches(phoneRegExp, 'Phone number is not valid')
    .required('Phone number is required'),
})

Formik Form Component

Here’s how you can integrate the validation schema with Formik for both password and phone number validation:

import React from 'react'
import { Formik, Form, Field, ErrorMessage } from 'formik'
import * as Yup from 'yup'

const phoneRegExp =
  /^((\+[1-9]{1,4}[ \-]*)|(\([0-9]{2,3}\)[ \-]*)|([0-9]{2,4})[ \-]*)*?[0-9]{3,4}?[ \-]*[0-9]{3,4}?$/

const validationSchema = Yup.object({
  password: Yup.string()
    .required('Password is required')
    .min(8, 'Password must be at least 8 characters')
    .matches(/[a-z]/, 'Password must contain at least one lowercase letter')
    .matches(/[A-Z]/, 'Password must contain at least one uppercase letter')
    .matches(/[0-9]/, 'Password must contain at least one number')
    .matches(/[!@#$%^&*(),.?":{}|<>]/, 'Password must contain at least one special character'),
  confirmPassword: Yup.string()
    .oneOf([Yup.ref('password'), null], 'Passwords must match')
    .required('Confirm Password is required'),
  phone: Yup.string()
    .matches(phoneRegExp, 'Phone number is not valid')
    .required('Phone number is required'),
})

const ValidationForm = () => {
  const initialValues = {
    password: '',
    confirmPassword: '',
    phone: '',
  }

  const handleSubmit = (values) => {
    console.log('Form Submitted:', values)
  }

  return (
    <Formik
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={handleSubmit}
    >
      {({ isSubmitting }) => (
        <Form>
          <div>
            <label htmlFor="password">Password</label>
            <Field type="password" name="password" />
            <ErrorMessage name="password" component="div" />
          </div>
          <div>
            <label htmlFor="confirmPassword">Confirm Password</label>
            <Field type="password" name="confirmPassword" />
            <ErrorMessage name="confirmPassword" component="div" />
          </div>
          <div>
            <label htmlFor="phone">Phone Number</label>
            <Field type="text" name="phone" />
            <ErrorMessage name="phone" component="div" />
          </div>
          <button type="submit" disabled={isSubmitting}>
            Submit
          </button>
        </Form>
      )}
    </Formik>
  )
}

export default ValidationForm

Custom Error Handling

If you need to display errors in a more structured way, you can customize the ErrorMessage component or use formik.touched and formik.errors to manually handle error states.

FAQs

Q: What happens if I want to add more rules later?

A: You can easily extend the Yup schema by chaining additional .matches() or other validation methods.

Q: Can I reuse the validation schema?

A: Yes, you can define the schema in a separate file and import it wherever needed.

Q: Does this work with Material-UI or other component libraries?

A: Absolutely! Replace Field with your preferred input components and pass the necessary props.