Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Field that aggregates errors from other fields into a "compound" error message #1548

Open
bschwartz757 opened this issue Jan 5, 2022 · 0 comments

Comments

@bschwartz757
Copy link

I'm using yup with Formik and I would like to have a "compound" error message field based on errors from several other related fields. I know I can get access to the field values themselves using .test(...,..., function(values){}), but I am curious if there is any built-in way to get the resolved field errors from other fields specified in the same overall schema.

I have 3 fields for a user to enter their date of birth (month, day, year); birthdate is optional but if the user fills out one field, they need to fill out the other two. I am able to validate these fields and got the .when() logic working to enforce conditional validation, and I can see in Formik context that the errors are getting set appropriately. With this, I am able to display contextual colors on each input when the field has an error. However, for display purposes I would like to also be able to display an aggregated error message in a fieldset wrapping the form inputs, rather than having each input have its own error message.

So, what I'd like to be able to do in Yup is something like:

  birthdate: object()
    .shape(
      {
        month: string().when(['day', 'year'], {
          is: (day, year) =>
            (day && day.length > 0) || (year && year.length > 0),
          then: string().test('length', 'Enter two digits for month', (value) =>
            /^\d{2}$/.test(value)
          ),
        }),
        day: string().when(['month', 'year'], {
          is: (month, year) =>
            (month && month.length > 0) || (year && year.length > 0),
          then: string().test('length', 'Enter two digits for day', (value) =>
            /^\d{2}$/.test(value)
          ),
        }),
        year: string().when(['month', 'day'], {
          is: (month, day) =>
            (month && month.length > 0) || (day && day.length > 0),
          then: string().test('length', 'Enter four digits for year', (value) =>
            /^\d{4}$/.test(value)
          ),
        }),
      },
      [
        ['day', 'year'],
        ['month', 'year'],
        ['month', 'day'],
      ]
    )
    .test('errors', 'Errors found: ${message}', function (values) {
      // Here I would like to get the errors from month, day, year (rather than the values), concatenate them, and return them as a string.
      return this.createError({
        message: 'concatenated error message',
      })
    }),

Alternatively, I tried creating a separate field outside of the birthdate parent field and using .test():

birthdate: ...,
fieldsetErrorMessage: string().test('errors', 'Errors found: ${message}', function (values) {
      // Here I would like to get the errors from month, day, year (rather than the values), concatenate them, and return them as a string.
      // I also tried referencing `this.parent.birthdate`, but again, I can only get the form field values, rather than the errors
      return this.createError({
        message: 'concatenated error message',
      })
    }),

If I could get this to work I would be able to grab the compound error field inside my custom Fieldset component using Formik Context, rather than having to manually parse the errors and assemble the message inside my form code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant