如何使崩溃打开,具体取决于是否存在错误-Ectionjs

发布于 2025-01-24 17:49:50 字数 3854 浏览 2 评论 0原文

嗨,我所遵循代码

我有两个输入,两个输入是强制性的。

第一个输入名称为名称,当我提交任何值时,它说请输入名称!。这部分工作很棒。

第二个输入,哪个名称为简短信息位于Collapse中。而且崩溃是< form.item>,这意味着用户可以按+,并添加多个简短信息输入。

我的问题是简短信息。当用户按仅提交时,首先输入显示错误。对于简短信息用户应打开该崩溃以查看错误,这不好。

现在,如果有错误,如何自动打开该崩溃面板?

这是我的代码。


    const [dataFromBackend, setDataFromBackend] = useState([]);

    const addNewField = () => {
     setDataFromBackend([...dataFromBackend]);
    };

    const submitForm = (values) => {
     console.log('Received values of form: ', values);
    };

    const Header = ({ remove, index }) => {
     return (
      <Col align="center" span={1} justify="end">
        <MinusCircleFilled
          onClick={(e) => {
            e.stopPropagation();
            remove(index);
          }}
        />
      </Col>
     );
    };


     return (
      <>
      <Form
        name="validate_other"
        onFinish={submitForm}
        initialValues={{ values: [''] }}
      >
        <Form.Item
          name="name"
          label="Name"
          rules={[
            {
              required: true,
              message: 'Please input Name!',
            },
          ]}
        >
          <Input />
        </Form.Item>
        <Form.List name="values">
          {(fields, { add, remove }) => {
            return (
              <Row gutter={24}>
                <Col span={24} md={24}>
                  <Card
                    title="Price"
                    extra={
                      <PlusCircleFilled
                        style={{
                          cursor: 'pointer',
                          fontSize: '20px',
                          color: '#00AEE6',
                        }}
                        onClick={() => {
                          add();
                          addNewField();
                        }}
                      />
                    }
                  >
                    <div key={fields.key}>
                      {fields.map((field, i) => (
                        <div key={i}>
                          <Collapse accordion={true}>
                            <Panel
                              key={i}
                              header={<Header remove={remove} index={i} />}
                            >
                              <Col span={24} md={24}>
                                <Form.Item
                                  name={[field.name, 'shortinfo']}
                                  fieldKey={[field.fieldKey, 'shortinfo']}
                                  label={'Short Info'}
                                  rules={[
                                    {
                                      required: true,
                                      message: 'Please input short info!',
                                    },
                                  ]}
                                >
                                  <Input />
                                </Form.Item>
                              </Col>
                            </Panel>
                          </Collapse>
                        </div>
                      ))}
                    </div>
                  </Card>
                </Col>
              </Row>
            );
          }}
        </Form.List>
        <Button htmlType="submit">Save</Button>
      </Form>
      </>
    )

请帮助我解决这个问题,谢谢。

Hi all I have following code.

I have two inputs and that two inputs are mandatory.

First input name is Name and when I am submit with any values it says Please input Name! . This part was working great.

Second input, which name is Short Info was located in collapse. And that collapse is <Form.Item>, it's mean that user can press + and add multiple Short Info inputs.

My problem is with that Short Info. When user press submit only first input shows error. For Short Info user should open that collapse to see error, which is not good.

Now how can I automatically open that collapse panel if there is error ?

Here is my code.


    const [dataFromBackend, setDataFromBackend] = useState([]);

    const addNewField = () => {
     setDataFromBackend([...dataFromBackend]);
    };

    const submitForm = (values) => {
     console.log('Received values of form: ', values);
    };

    const Header = ({ remove, index }) => {
     return (
      <Col align="center" span={1} justify="end">
        <MinusCircleFilled
          onClick={(e) => {
            e.stopPropagation();
            remove(index);
          }}
        />
      </Col>
     );
    };


     return (
      <>
      <Form
        name="validate_other"
        onFinish={submitForm}
        initialValues={{ values: [''] }}
      >
        <Form.Item
          name="name"
          label="Name"
          rules={[
            {
              required: true,
              message: 'Please input Name!',
            },
          ]}
        >
          <Input />
        </Form.Item>
        <Form.List name="values">
          {(fields, { add, remove }) => {
            return (
              <Row gutter={24}>
                <Col span={24} md={24}>
                  <Card
                    title="Price"
                    extra={
                      <PlusCircleFilled
                        style={{
                          cursor: 'pointer',
                          fontSize: '20px',
                          color: '#00AEE6',
                        }}
                        onClick={() => {
                          add();
                          addNewField();
                        }}
                      />
                    }
                  >
                    <div key={fields.key}>
                      {fields.map((field, i) => (
                        <div key={i}>
                          <Collapse accordion={true}>
                            <Panel
                              key={i}
                              header={<Header remove={remove} index={i} />}
                            >
                              <Col span={24} md={24}>
                                <Form.Item
                                  name={[field.name, 'shortinfo']}
                                  fieldKey={[field.fieldKey, 'shortinfo']}
                                  label={'Short Info'}
                                  rules={[
                                    {
                                      required: true,
                                      message: 'Please input short info!',
                                    },
                                  ]}
                                >
                                  <Input />
                                </Form.Item>
                              </Col>
                            </Panel>
                          </Collapse>
                        </div>
                      ))}
                    </div>
                  </Card>
                </Col>
              </Row>
            );
          }}
        </Form.List>
        <Button htmlType="submit">Save</Button>
      </Form>
      </>
    )

Please help me to resolve this problem, thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫性小仙女 2025-01-31 17:49:50

我的解决方案将如下:

  1. 首先,渲染所有&lt; panels&gt;在相同的&lt; colapse&gt;中,还删除aCRACTION = {true} < /code>来自colapse(因此可以一次打开多个字段),然后添加forcerender = {true} panels,否则在一个内部的项目面板是懒惰的加载(如果懒惰负载活跃,&lt; form.item&gt; 不会被渲染,并且不会显示为错误
<Collapse>
  {fields.map((field, i) => {
    return (
      <Panel
        ...
        forceRender={true}
        ...
      >
        ...
      </Panel>
    );
  })}
</Colapse>

  1. )跟踪当前活动键并将其添加到Colapse中,还删除&lt; div key = {i}&gt;不需要,因为&lt; panel key = {i} &gt;已经是一个容器,此外,它将阻止onChange colapse 触发并弄乱您的造型
const [activeKeysColapse, setactiveKeysColapse] = useState([]);

...

<Collapse
  activeKey={activeKeysColapse}
  onChange={(newActiveKeys) => {
    // otherwise panels couldn't be open/closed by click
    setactiveKeysColapse(newActiveKeys);
  }}
>
  {fields.map((field, i) => {
    return (
      <Panel
        key={i}
        forceRender={true}
      >
        ...
      </Panel>
    );
  })}
</Colapse>

  1. 添加onfinishfailed侦听器 表格
const submitFormFailed = (errors) => {
  // get all errorFields from the list and map the
  // `activeKeys` to the index (because `<Panel key={i}>`)
  const newShortInfoErrors = errors.errorFields
    .filter((el) => el.name[0] === 'values')
    .map((el) => el.name[1].toString());

  // setting the state will close all fields which
  // are valid and open all with an error message
  setactiveKeysColapse(newShortInfoErrors);
};

...

<Form
  ...
  onFinishFail={submitFormFailed}
>

基于您的Stackblitz上的代码

,这将确切地做您想要的事情,我希望这可以解决您的问题,如果有什么不清楚的话,请随时发表评论

My solution would be as follows:

  1. First of all, render all <Panels> inside the same <Colapse>, also remove accordion={true} from Colapse (so multiple Fields can be open at once) and add forceRender={true} to Panels, otherwise items inside a Panel are lazy loaded (if lazy load would be active, <Form.Item> wouldn't be rendered and don't show up as error)
<Collapse>
  {fields.map((field, i) => {
    return (
      <Panel
        ...
        forceRender={true}
        ...
      >
        ...
      </Panel>
    );
  })}
</Colapse>

  1. Add a state to keep track of currently active keys and add it to the colapse, also remove the <div key={i}> it is not needed, since <Panel key={i}> is already a container, furthermore it will prevent onChange of Colapse to trigger and mess up your styling
const [activeKeysColapse, setactiveKeysColapse] = useState([]);

...

<Collapse
  activeKey={activeKeysColapse}
  onChange={(newActiveKeys) => {
    // otherwise panels couldn't be open/closed by click
    setactiveKeysColapse(newActiveKeys);
  }}
>
  {fields.map((field, i) => {
    return (
      <Panel
        key={i}
        forceRender={true}
      >
        ...
      </Panel>
    );
  })}
</Colapse>

  1. Add onFinishFailed listener to form
const submitFormFailed = (errors) => {
  // get all errorFields from the list and map the
  // `activeKeys` to the index (because `<Panel key={i}>`)
  const newShortInfoErrors = errors.errorFields
    .filter((el) => el.name[0] === 'values')
    .map((el) => el.name[1].toString());

  // setting the state will close all fields which
  // are valid and open all with an error message
  setactiveKeysColapse(newShortInfoErrors);
};

...

<Form
  ...
  onFinishFail={submitFormFailed}
>

Based on the code on your StackBlitz, this will do exactly what you want

I hope this will solve your problem, if there is anything unclear, feel free to comment

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文