Yup validation based on another non-required field
Asked Answered
D

3

17

I'm building a form in React using Formik and React-bootstrap and I'm using Yup to validate the form.

I have 2 fields, let's say FieldA and FieldB. FieldA is not required but FieldB is required if FieldA is not empty.

FieldA is a textbox while FieldB is multiple select. My validation rule for FieldB must be:

FieldA !=='' ? FieldB is required : do nothing
Despotism answered 6/2, 2020 at 9:32 Comment(0)
Y
34

Try this:

const schema = Yup.object().shape({
       FieldA: Yup.string(),
       FieldB: Yup.string()
        .when('FieldA', {
          is: (FieldA) => FieldA.length > 0,
          then: Yup.string()
            .required('Field is required')            
        })
    });
Yolanthe answered 6/2, 2020 at 10:10 Comment(1)
Note that this will not work with nested objects: github.com/jquense/yup/issues/735Endogenous
T
1

Here is a solution if you need to conditionally validate more than one field against multiple fields. In this example FieldZ is the only required field. The other three fields A B C are required only if one of the other two fields is filled in. NOTE: you can add any kind of validation in the is function. Below I am just checking for the existence of the field value.

export const validationSchema = yup.object().shape({
    FieldZ: yup.string().required("Field Z is required"),

    // These three fields are All or nothing. If one is selected then they are all required.
    FieldA: yup
        .string()
        .when(['FieldB', 'FieldC'], {
            is: (FieldB, FieldC) =>
                FieldB || FieldC,
            then: yup.string().required('Field A is required')
        }),

    FieldB: yup
        .string()
        .when(['FieldA', 'FieldC'], {
            is: (FieldA, FieldC) =>
                FieldA || FieldC,
            then: yup.string().required('Field B is required')
        }),

    FieldC: yup
        .string()
        .when(['FieldA', 'FieldB'], {
            is: (FieldA, FieldB) =>
                FieldA || FieldB,
            then: yup.string().required('Field C is required')
        }),
}, 
// Resolve the dependency 'circle'. This tells yup which order to resolve the dependencies
// Failure to do this will result in a yup circular validation error.
[
  ['FieldA', 'FieldB'],
  ['FieldA', 'FieldC'],
  ['FieldB','FieldC' ]
]);
Tiphani answered 22/11, 2022 at 20:13 Comment(0)
P
0

Use the validate option in Formkit as mentioned here

const validate = values =>
  if (values.a > values.b){
    //return error message for assumed filed
    return {
      a: 'a is greater than b',
    };
  }

in Formkit:

<Formik
    initialValues={{
    a: 2,
    b: 1,
    }}
    validate={validate}
Prototrophic answered 7/10, 2020 at 12:48 Comment(1)
The question asks how to do the validation using yup.Tiphani

© 2022 - 2024 — McMap. All rights reserved.