简体   繁体   English

如果在 yup Schema 验证中任何字段非空,则不需要任何字段或需要所有字段

[英]Either no field is required or all fields are required if any of the field is non-empty in yup Schema validation

Scenario: i have 4 fields and i want to validate using Yup validation schema场景:我有 4 个字段,我想使用 Yup 验证模式进行验证

  • Suppose if the user enters value for any of the above 1 field, the other 3 must be required假设如果用户为上述 1 个字段中的任何一个输入值,则必须要求其他 3 个

  • if the user does not enter value for any of the 4 fields then no field is required如果用户没有为 4 个字段中的任何一个输入值,则不需要任何字段

  • thus all i want to say is No fields are required if all fields are empty and suppose any one field is non-empty then all fields are required!因此,我想说的是,如果所有字段都为空,则不需要任何字段,并且假设任何一个字段都为非空,那么所有字段都是必需的!

Solution i tried我试过的解决方案

const validationSchema = Yup.object({
  field1: Yup.mixed().when(["field2", "field3", "field4"], {
    is: (...fields) => fields.some(Boolean),
    then: Yup.mixed().required(),
    otherwise: Yup.mixed().notRequired()
  }),
  field2: Yup.mixed().when(["field1", "field3", "field4"], {
    is: (...fields) => fields.some(Boolean),
    then: Yup.mixed().required(),
    otherwise: Yup.mixed().notRequired()
  }),
  field3: Yup.mixed().when(["field2", "field1", "field4"], {
    is: (...fields) => fields.some(Boolean),
    then: Yup.mixed().required(),
    otherwise: Yup.mixed().notRequired()
  }),
  field4: Yup.mixed().when(["field2", "field3", "field1"], {
    is: (...fields) => fields.some(Boolean),
    then: Yup.mixed().required(),
    otherwise: Yup.mixed().notRequired()
  })
});

Error i got我得到的错误

  • Cyclic dependency, node was:"field4"循环依赖,节点是:“field4”

This question is over a month old when writing this answer, but maybe it could help someone or at least point them in the right direction.这个问题在写这个答案时已经有一个多月了,但也许它可以帮助某人或至少为他们指明正确的方向。

I had the Cyclic issue, but I had three fields.我有循环问题,但我有三个字段。 I wanted either non of the fields to be entered, or all three must be required.我不想输入任何字段,或者必须输入所有三个字段。

This link: https://github.com/jquense/yup/issues/176#issuecomment-369925782 helped but did not work for me.此链接: https://github.com/jquense/yup/issues/176#issuecomment-369925782帮助但对我不起作用。 But after a few tweaks, I made it work;但经过一些调整后,我让它工作了; here is what worked for me.这对我有用。

const SettingsSchema = Yup.object().shape({
    password: Yup.string().ensure()
      .when(['new_password', 'confirm_password'], {
        is: (new_password, confirm_password) => new_password !== '' || confirm_password !== '',
        then: (SettingsSchema) => SettingsSchema.required(t('Password is required.')),
      }),
    new_password: Yup.string().ensure()
      .when(['password', 'confirm_password'], {
        is: (password, confirm_password) => password !== '' || confirm_password !== '',
        then: (SettingsSchema) => SettingsSchema.required(t('New Password is required.'))
          .min(8, t('Password cannot be shorted than 8 characters.')),
      }),
    confirm_password: Yup.string().ensure()
      .when(['password', 'new_password'], {
        is: (password, new_password) => password !== '' || new_password !== '',
        then: (SettingsSchema) => SettingsSchema.required(t('Confirm Password is required.'))
          .oneOf([Yup.ref('new_password')], t('New Password and Confirm Password must match.')),
      }),
  }, [['password', 'new_password'], ['password', 'confirm_password'], ['new_password', 'confirm_password']]);

What was required to remove the cyclic error and make the validation work was:消除循环错误并使验证工作所需的是:

  • The last parameter of shape it's an array containing arrays of pairs. shape的最后一个参数是一个包含 arrays 对的数组。

The documentation on that part is not very clear at the time of writing.在撰写本文时,该部分的文档还不是很清楚。 https://github.com/jquense/yup#objectshapefields-object-nosortedges-arraystring-string-schema https://github.com/jquense/yup#objectshapefields-object-nosortedges-arraystring-string-schema

Things to note:注意事项:

  1. On each field, I call .ensure() .在每个字段上,我调用.ensure() This ensures that if values are undefined or null , they will be transformed into empty strings.这确保如果值undefinednull ,它们将被转换为空字符串。
  2. Because you have four fields, you will need an extra pair in the array of pairs of fields as the last parameter of shape .因为您有四个字段,所以您需要在字段对数组中添加一对作为shape的最后一个参数。

So I think your example above could be rewritten as:所以我认为你上面的例子可以重写为:

const schema = Yup.object().shape({
  field1: Yup.mixed().ensure().when(["field2", "field3", "field4"], {
    is: (field2, field3, field4) => field2 !== '' || field3 !== '' || field4 !== '',
    then: (schema) => schema.required(),
    otherwise: (schema) => schema.notRequired()
  }),
  field2: Yup.mixed().ensure().when(["field1", "field3", "field4"], {
    is: (field1, field3, field4) => field1 !== '' || field3 !== '' || field4 !== '',
    then: (schema) => schema.required(),
    otherwise: (schema) => schema.notRequired(),
  }),
  field3: Yup.mixed().ensure().when(["field1", "field2", "field4"], {
    is: (field1, field2, field4) => field1 !== '' || field2 !== '' || field4 !== '',
    then: (schema) => schema.required(),
    otherwise: (schema) => schema.notRequired(),
  }),
  field4: Yup.mixed().ensure().when(["field1", "field2", "field3"], {
    is: (field1, field2, field3) => field1 !== '' || field2 !== '' || field3 !== '',
    then: (schema) => schema.required(),
    otherwise: (schema) => schema.notRequired(),
  })
}, [["field1", "field2"], ["field2", "field3"], ["field3", "field4"], ["field1", "field4"]]);

I know the example with three fields works as I am using it in my code.我知道具有三个字段的示例在我的代码中使用它时有效。 The example with four parameters is derived from the example of three parameters and I did not test it so I am not sure is totally correct.四个参数的例子是从三个参数的例子派生出来的,我没有测试,所以我不确定是否完全正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM