如何验证使用语义下拉列表并允许添加的 Formik FieldArray

How to validate Formik FieldArray which uses Semantic dropdown with allow additions

我有一个 formik 字段数组,其中每一行都有 3 个下拉列表。我想要一个以这种方式工作的验证模式:

如果在第一个下拉列表中选择了电子邮件,则无论是否提供了有效的电子邮件 ID,都会验证第三个下拉列表中给出的值(它具有 allowAdditions)。

如果在第二个下拉列表中选择了 <、<=、>、>= 运算符,则在第三个下拉列表中给出的值(它有 allowAdditions)只有一个数字时才会被验证。

在实现这个之前,我尝试给出一个简单的验证来验证第一个下拉列表的长度是否大于 6。虽然验证有效,但没有显示警告消息,因为它与 formik 中的普通 FormInput 一起提供。不确定这是不是因为它是一个下拉菜单。

验证:

  const validationSchema = object().shape({
    rows: array().of(
      object().shape({
        value: string().min(4, "too short").required("Required")
      })
    )
  });

福米克:

<Formik
      initialValues={{ rows: initialValues }}
      onSubmit={(values) => {
        // transform the rows to add the condition key for each row object
        const output = values.rows.map((row, index) => {
          if (index === 0) {
            return { ...row, condition: "if" };
          } else {
            return { ...row, condition: "and" };
          }
        });

        console.log(output);
      }}
      validationSchema={validationSchema}
    >
      {({ handleSubmit, values, setFieldValue }) => (
        <Form onSubmit={handleSubmit} className={"rulesetForm"}>
          <pre>{JSON.stringify(values, null, 2)}</pre>
          <FieldArray
            name="rows"
            render={({ push, remove }) => {
              return (
                values.rows.length > 0 &&
                values.rows.map((row, index) => {
                  const mainFieldOptions = getMainFieldOptions(
                    values.rows,
                    index
                  );
                  return (
                    <Grid key={`mainfield-operation-value-${index}`}>
                      <Grid.Row className={"rulesetGrid fluid"}>
                        {index === 0 ? (
                          <p className="condition"> If</p>
                        ) : (
                          <p className="condition"> And</p>
                        )}

                        <Dropdown
                          name={`rows.${index}.mainField`}
                          className={"dropdown fieldDropdown"}
                          widths={2}
                          placeholder="Field"
                          fluid
                          selection
                          options={mainFieldOptions}
                          value={row.mainField || ""}
                          onChange={(e, { value }) => {
                            setFieldValue(`rows.${index}.mainField`, value);
                          }}
                        />

                        <Dropdown
                          name={`rows.${index}.operation`}
                          className={"dropdown operationDropdown"}
                          widths={2}
                          placeholder="Operation"
                          fluid
                          selection
                          options={operation}
                          value={row.operation}
                          onChange={(e, { value }) =>
                            setFieldValue(`rows.${index}.operation`, value)
                          }
                        />
                        <Dropdown
                          name={`rows.${index}.value`}
                          className={"dropdown valueDropdown"}
                          widths={1}
                          placeholder="Value"
                          fluid
                          search
                          allowAdditions
                          selection
                          multiple
                          options={dropDownOptions}
                          value={row.value}
                          onAddItem={handleAddition}
                          onChange={(e, { value }) =>
                            setFieldValue(`rows.${index}.value`, value)
                          }
                        />

                        {values.rows.length - 1 === index && (
                          <Icon
                            className={"  plus icon plusIcon"}
                            onClick={() => push(initialValues[0])}
                          />
                        )}
                        {values.rows.length !== 1 && (
                          <Icon
                            className={"minus crossIcon"}
                            onClick={() => remove(index)}
                          />
                        )}
                      </Grid.Row>
                    </Grid>
                  );
                })
              );
            }}
          />
          <div>
            <div style={{ marginTop: "1rem" }}>
              <Button
                floated="right"
                type="submit"
                variant="contained"
                primary={true}
              >
                Submit
              </Button>
            </div>
          </div>
        </Form>
      )}
    </Formik>

这里是沙箱 link:https://codesandbox.io/s/semantic-ui-example-forked-lmqi9?file=/example.js:1826-6181

非常感谢任何帮助,这意义重大。提前致谢

你需要使用 Yup When along with Test

工作沙盒

CodeSandbox