Yup and Formik - how to set variables for different conditions on password field

Viewed 55

I have been searching through other posts and finding issues similar to but not quite what I am looking for.

I need to know simultaneously if the different conditions are met for a password to highlight the visual below.

What I'm seeing coming back right now is just the error message for the first condition that is not met.

The validation schema

validationSchema: Yup.object({
            password: Yup.string()
                .required('Required')
                .min(8, 'Must be 8 characters or more')
                .matches(/[A-Z]+/, 'One uppercase character')
                .matches(/[@$!%*#?&]+/, 'One special character')
                .matches(/\d+/, 'One number'),
        }),

Here is the ui I want to be able to update just to help in case I'm not explaining well enough enter image description here

1 Answers

First of all you need to create states for each condition like

const [isRequired, setRequired] = useState(false);
const [isMinLength, setMinLength] = useState(false);
const [isUppercase, setUppercase] = useState(false);
const [isSpecial, setSpecial] = useState(false);
//other validation states like isNumber...

You can use yup .when to check if password value satisfy your conditions or not.

validationSchema: Yup.object({
password: yup.string().when('password', (password, field) => {
            if (password == null) {
                setRequired(false)
                return field.required()
            } else {
                setRequired(true)
            }
        }).when('password', (password, field) => {
            if (password?.length <= 8) {
                setMinLength(false)
                return field.min(8, 'Must be 8 characters or more')
            } else {
               setMinLength(true)   //mark min length check as green
            }
        }).when('password', (password, field) => {
            if (!(/[A-Z]+/.test(password))) {
                setUppercase(false)
                return field.matches(/[A-Z]+/, 'One uppercase character')
            } else {
                setUppercase(true) //mark uppercase check as green
            }
        }).when('password', (password, field) => {
            if (!(/[@$!%*#?&]+/.test(password))) {
                setSpecial(false)
                return field.matches(/[@$!%*#?&]+/, 'One special character')
            } else {
                setSpecial(true)  //mark special character check as green
            }
        }),
}, ["password", "password"]),  //yup cyclic dependency 

Similarly, like above you can create states and use .when for other validations as well. Based on those states you can change state of checkboxes or whatever the GUI you are using.

Related