skip to Main Content

I’m building a multi-step form where each step is its own form and has its own validation schema. im using react-hook-form for the form (don’t think that matters here) and yup for the validation so heres a simplified version of what im trying to do

export const page1Schema = yup.object().shape({
  ["signature"]: yup.string().required(),
});

export const page2Schema = yup.object().shape({
  ["dependentField"]: yup.string().when(["signature"], {
    is: (signature) => signature !== "",
    then: () => yup.string().required(),
    otherwise: () => yup.string().notRequired(),
  })
});

so in page2Schema i want to access the value of the field ‘signature’ which is in step 1 of the form and set the field to required only if field in step 1 meets some condition. is there a way to do this?

2

Answers


  1. Chosen as BEST ANSWER

    I found 2 ways to get around this problem in a case where i can get the value from inside the form and pass it in to the schema

    Solution 1: changing the schema to a function

    export const page1Schema = (value) => yup.object().shape({
      ["signature"]: yup.string().required(),
    });
    

    and pass in the prop resolver: yupResolver(page1Schema(value))

    Solution 2: using context

    export const page2Schema = yup.object().shape({
      ["dependentField"]: yup.string().when(["$signature"], {
        is: (signature) => signature !== "",
        then: () => yup.string().required(),
        otherwise: () => yup.string().notRequired(),
      })
    });
    

    then to pass the context using rhf

    const {} =useForm({
      resolver: yupResolver(page1Schema),
      context: { signature: reduxState.signature}
    });
    

    Note: both of these solutions do not solve the problem completely but in my case im using redux toolkit to hold all the form values so i can pass to the context the value of the field from form 1 (signature) to page2Schema


  2. You can try like this :

    export const page2Schema = yup.object().shape({
       dependentField: yup.string()
                   .test("Dependent field is required when signature is provided", 
                         function (value) {
                            //const signature = this.resolve(yup.ref("signature"));
                              const signature = this.parent.signature;
                                 if (signature) {
                                    return !!value;
                                 } else {
                                    return true;
                                 }
                         }),
                  }).
    
    

    In the this.resolve() function, you can get the value of the signature.

    If signature is true, can check whether dependentField has a value(!!value).

    If signature is false, this field is not provided and can allow any value for dependentField.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search