Formik – Yup验证取决于前一个数组字段的值

huangapple go评论78阅读模式
英文:

Formik - Yup validation depends of prev array field value

问题

有以下模式:

let validationSchema = Yup.object({
  modules: Yup.array(
    Yup.object({
      title: Yup.string()
        .required("模块标题不能为空")
        .min(1, "模块标题不能为空"),
      lessons: Yup.array(
        Yup.object({
          lessonTitle: Yup.string().required("课程标题不能为空"),
          lessonType: Yup.array()
            .min(1, "课程类型不能为空")
            .required("课程类型不能为空"),
        })
      ),
    })
  )
    .min(1, "您必须至少添加一个模块")
    .required("您必须至少添加一个模块"),
})

有一个条件验证我需要做,但无法做到:

  1. 如果lessonType字段(一个数组)包含单词“video”,则需要检查videoFile字段是否附有视频,否则应在videoFile字段下显示错误消息。
  2. 如果lessonType字段包含单词“document”,则需要检查documentFile字段是否附有文件,否则应在documentFile字段下显示错误消息。

我尝试了类似问题的一些建议,但没有任何效果,有人能指点我正确的方向吗?

带有2节课的模块的结构如下:

modules [
  {
    title: "模块标题", 
    lessons:[
      {lessonTitle:"视频标题", lessonType:["video"]}, 
      {lessonTitle:"文档标题", lessonType:["document"]}
    ]
  }
]

尝试过使用Yup.array().when(...),但不起作用,因为我不确定如何应用条件,如果我需要验证的字段是一个数组。

英文:

having the following schema:

let validationSchema = Yup.object({
modules: Yup.array(
      Yup.object({
        title: Yup.string()
          .required("A module title is required")
          .min(1, "A module title is required"),
        lessons: Yup.array(
          Yup.object({
            lessonTitle: Yup.string().required("A lesson title is required"),
            lessonType: Yup.array()
              .min(1, "Lesson type is required")
              .required("Lesson type is required"),
          })
        ),
      })
    )
      .min(1, "You must add at least one module")
      .required("You must add at least one module"),
})

there's a conditional validation I need to do, but wasn't able:

  1. if the lessonType field which is an array includes de word "video" then I need to check if the field videoFile has the video attached otherwise an error message should be displayed below the videoFile field.
  2. if the lessonType field includes de word "document" then I need to check if the field documentFile has a file attached otherwise an error message should be displayed below the documentFile field.

I tried some recommendations from similar questions here but nothing works, can someone here point me into the right direction?

the structure if the module with 2 lessons is like:

modules [
  {
    title: "module title", 
    lessons:[
      {lessonTitle:"video title", lessonType:["video"]}, 
      {lessonTitle:"document title", lessonType:["document"]}
    ]
  }
]

tried with
Yup.array().when(...) but doesn't work because im not sure how to apply the conditional if the field that I need to validate is an array.

答案1

得分: 2

Yup验证模式中的when方法可用于这种条件验证,但由于您的lessonType是一个数组,因此需要更复杂的处理。

以下是一个示例,用于在您的validationSchema中添加复杂处理,您可以添加到lessons数组中:

lessonType: Yup.array()
        .min(1, "课程类型是必需的")
        .required("课程类型是必需的")
        .test('file-test', '需要文件', function (value) {
          const { videoFile, documentFile } = this.parent;
          if (value.includes('video') && (!videoFile || videoFile.length === 0)) {
            return this.createError({ message: '当课程类型为视频时,需要视频文件' });
          }
          if (value.includes('document') && (!documentFile || documentFile.length === 0)) {
            return this.createError({ message: '当课程类型为文档时,需要文档文件' });
          }
          return true;
        }),
      videoFile: Yup.mixed(),
      documentFile: Yup.mixed(),

我已将videoFiledocumentFile添加为混合类型到模式中,并在测试函数中使用它们。此测试的错误消息将出现在lessonType字段下,因此您可能需要调整错误处理以在相应的文件字段下显示它。

测试函数中的this.parent属性指的是父对象,这在这种情况下是课程对象。因此,this.parent.videoFilethis.parent.documentFile指的是当前课程对象的videoFiledocumentFile。这将确保当lessonType为视频时,将检查videoFile的存在,同样对于文档lessonType,将检查documentFile的存在。如果相应的文件不存在,将生成错误消息。

英文:

The when method in Yup validation schema can be used for this kind of conditional validation, but since your lessonType is an array, it requires a bit more complex handling.

here's an example for adding complex handling inside your validationSchema you can add to lessons array:

lessonType: Yup.array()
        .min(1, "Lesson type is required")
        .required("Lesson type is required")
        .test('file-test', 'File required', function (value) {
          const { videoFile, documentFile } = this.parent;
          if (value.includes('video') && (!videoFile || videoFile.length === 0)) {
            return this.createError({ message: 'Video file required when lesson type is video' });
          }
          if (value.includes('document') && (!documentFile || documentFile.length === 0)) {
            return this.createError({ message: 'Document file required when lesson type is document' });
          }
          return true;
        }),
      videoFile: Yup.mixed(),
      documentFile: Yup.mixed(),

I have added videoFile and documentFile as mixed types to the schema and have used them inside the test function. The error message from this test will appear under the lessonType field, so you might need to adjust your error handling to display it under the respective file fields.

The this.parent property inside the test function refers to the parent object, which is the lesson object in this case. So this.parent.videoFile and this.parent.documentFile refer to the videoFile and documentFile of the current lesson object.

This will ensure that when the lessonType is video, the presence of videoFile is checked and likewise for document lessonType, the presence of documentFile is checked. If the respective file is not present, an error message will be generated.

huangapple
  • 本文由 发表于 2023年5月14日 04:18:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76244704.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定