ant design Form必填校验失败自动滚动到第一条 scrollToFirstError scrollIntoView

16 篇文章 0 订阅

老规矩,话不多说,直接上实现方式
注意:本帅用的版本 “antd”: “4.16.13”,
前提代码如下

 const generateUUID = () => {
    let d = new Date().getTime();
    const uuid = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, (c: any) => {
      const r = (d + Math.random() * 16) % 16 | 0;
      d = Math.floor(d / 16);
      return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
    });
    return uuid;
  };
  const arrs = [];
  for (let i = 20; i--; ) {
    const uuid = generateUUID();
    arrs.push({
      label: uuid,
      name: uuid,
      key: uuid,
    });
  }
  const [state, setstate] = useState([]);
  // setstate(arrs);
  useEffect(() => {
    setTimeout(() => {
      console.log(arrs, 'arrs');
      setstate(arrs);
    }, 200);
  }, []);

方式一:scrollToFirstError

//首先给Form添加一个属性 scrollToFirstError={true}
//然后给button按钮添加属性 htmlType="submit" 即可
//代码如下
<Form form={form} name="basic" scrollToFirstError={true}>
  <Form.Item
    id="sadfasf"
    label="asdfa"
    name="sadfasf"
    rules={[{ required: true, message: "Please input your password!" }]}
  >
    <Input.Password />
  </Form.Item>
  <Form.Item
    id="aaaa"
    label="aaaa"
    name="aaaa"
    rules={[{ required: true, message: "Please input your password!" }]}
  >
    <Input.Password />
  </Form.Item>
  {state.map((item) => {
    return (
      <Form.Item
        key={item.key}
        label={item?.label}
        name={item?.name}
        rules={[{ required: false, message: "Please input your password!" }]}
      >
        <Input.Password />
      </Form.Item>
    );
  })}
  <Button type="primary" htmlType="submit">
    Submit
  </Button>
</Form>;

方式二:onFinishFailed

//失败就会触发该方法
//代码如下:
<Form
  form={form}
  name="basic"
  onFinishFailed={() => {
  	//关键代码
    const errorList = (document as any).querySelectorAll(".ant-form-item-has-error");
    //由于校验失败ant会自动给失败表单项添加类名,直接获取即可
    errorList[0].scrollIntoView({
      block: "center",
      behavior: "smooth",
    });
  }}
  //注意:由于dom更新异步,可能会获取不到,可以在setTimeout()中操作,vue的使用nextTick()即可
>
  <Form.Item
    id="sadfasf"
    label="asdfa"
    name="sadfasf"
    rules={[{ required: true, message: "Please input your password!" }]}
  >
    <Input.Password />
  </Form.Item>
  <Form.Item
    id="aaaa"
    label="aaaa"
    name="aaaa"
    rules={[{ required: true, message: "Please input your password!" }]}
  >
    <Input.Password />
  </Form.Item>
  {state.map((item) => {
    return (
      <Form.Item
        key={item.key}
        label={item?.label}
        name={item?.name}
        rules={[{ required: false, message: "Please input your password!" }]}
      >
        <Input.Password />
      </Form.Item>
    );
  })}
  <Button type="primary" htmlType="submit">
    Submit
  </Button>
</Form>;

方式三:自定义表单项

很多情况下,表单项是通过接口获取渲染的,页面布局可能是自定义的,或嵌套多层div

//类似这种嵌套多层盒子,可能就会失效
           {state.map((item) => {
              return (
                <div>
                  <div>
                    <div>
                      <span></span>
                      <div>
                        <Form.Item
                          key={item.key}
                          label={item?.label}
                          name={item?.name}
                          rules={[{ required: false, message: 'Please input your password!' }]}
                        >
                          <Input.Password />
                        </Form.Item>
                      </div>
                    </div>
                  </div>
                </div>
              );
            })}
//这时候必须要改盒子绑定一定id才会生效
<Form form={form} name="basic" scrollToFirstError={true}>
  <Form.Item
    id="sadfasf"
    label="asdfa"
    name="sadfasf"
    rules={[{ required: true, message: "Please input your password!" }]}
  >
    <Input.Password />
  </Form.Item>
  <Form.Item
    id="aaaa"
    label="aaaa"
    name="aaaa"
    rules={[{ required: true, message: "Please input your password!" }]}
  >
    <Input.Password />
  </Form.Item>
  {state.map((item) => {
    return (
                <div id={item.name}>
                  <div>
                    <div>
                      <span></span>
                      <div>
                        <Form.Item
                          key={item.key}
                          label={item?.label}
                          name={item?.name}
                          rules={[{ required: false, message: 'Please input your password!' }]}
                        >
                          <Input.Password />
                        </Form.Item>
                      </div>
                    </div>
                  </div>
                </div>
    );
  })}
  <Button type="primary" htmlType="submit">
    Submit
  </Button>
</Form>;

在Tabs遇到的问题

可能有个需求,切换对应的tabs,获取相应的表单列表,那么问题就来了,必填项校验失败后,自动滚到到第一个必填项只在第一个tab中生效,其他的不生效。所以我目前是通过销毁隐藏的dom来解决(destroyInactiveTabPane
完整代码如下

    <Tabs destroyInactiveTabPane defaultActiveKey="1" onChange={onChange} tabPosition="left">
      <TabPane tab="Tab 1" key="1">
        <div className={styles.con} id="crfDetailContent">
          <Form
            form={form}
            name="basic"
            labelCol={{ span: 8 }}
            wrapperCol={{ span: 16 }}
            onFinishFailed={() => {
            //注意,用方式一也是可以的---scrollToFirstError
              let str = 'sadfasf';
              const errorDom: any = document.getElementById(str);
              errorDom.scrollIntoView({
                block: 'center',
                behavior: 'smooth',
              });
            }}
          >
            {console.log('state', state)}
            <hr style={{ marginTop: 30 }} />

            <div>
              <div>
                <div id="sadfasf">
                  <Form.Item
                    id="sadfasf"
                    label="asdfa"
                    name="sadfasf"
                    rules={[{ required: true, message: 'Please input your password!' }]}
                  >
                    <Input.Password />
                  </Form.Item>
                </div>
              </div>
            </div>
            <div>
              <Form.Item
                id="aaaa"
                label="aaaa"
                name="aaaa"
                rules={[{ required: true, message: 'Please input your password!' }]}
              >
                <Input.Password />
              </Form.Item>
            </div>
            {state.map((item) => {
              return (
                <div>
                  <div>
                    <div>
                      <span></span>
                      <div>
                        <Form.Item
                          key={item.key}
                          label={item?.label}
                          name={item?.name}
                          rules={[{ required: false, message: 'Please input your password!' }]}
                        >
                          <Input.Password />
                        </Form.Item>
                      </div>
                    </div>
                  </div>
                </div>
              );
            })}
            <Button type="primary" htmlType="submit">
              Submit
            </Button>
          </Form>
        </div>
      </TabPane>
      <TabPane tab="Tab 2" key="2">
        <div className={styles.con} id="crfDetailContent">
          <Form
            form={form}
            name="basic"
            labelCol={{ span: 8 }}
            wrapperCol={{ span: 16 }}
            // onFinish={onFinish}
            onFinishFailed={() => {
              let str = 'sadfasf';
              const errorDom: any = document.getElementById(str);
              errorDom.scrollIntoView({
                block: 'center',
                behavior: 'smooth',
              });
            }}
          >
            <hr style={{ marginTop: 30 }} />

            <div>
              <div>
                <div id="sadfasf">
                  <Form.Item
                    id="sadfasf"
                    label="asdfa"
                    name="sadfasf"
                    rules={[{ required: true, message: 'Please input your password!' }]}
                  >
                    <Input.Password />
                  </Form.Item>
                </div>
              </div>
            </div>
            <div>
              <Form.Item
                id="aaaa"
                label="aaaa"
                name="aaaa"
                rules={[{ required: true, message: 'Please input your password!' }]}
              >
                <Input.Password />
              </Form.Item>
            </div>
            {state.map((item) => {
              return (
                <div>
                  <div>
                    <div>
                      <span></span>
                      <div>
                        <Form.Item
                          key={item.key}
                          label={item?.label}
                          name={item?.name}
                          rules={[{ required: false, message: 'Please input your password!' }]}
                        >
                          <Input.Password />
                        </Form.Item>
                      </div>
                    </div>
                  </div>
                </div>
              );
            })}
            <Button type="primary" htmlType="submit">
              Submit
            </Button>
          </Form>
        </div>
      </TabPane>
      <TabPane tab="Tab 3" key="3">
        Content of Tab Pane 3
      </TabPane>
  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在让DIV的滚动自动滚动到最底部这个需求中,我们可以采用以下三种方法来实现,并推荐使用第三种方法: 1. 使用scrollTop属性:通过设置DIV元素的scrollTop属性为其滚动高度的最大值,可以实现让滚动自动滚动到底部的效果。代码示例如下: ``` var divElement = document.getElementById("myDiv"); divElement.scrollTop = divElement.scrollHeight; ``` 2. 使用scrollIntoView方法:该方法可以将当前元素滚动到可见区域,通过将目标元素滚动到最底部的位置来实现滚动自动滚动到底部的效果。代码示例如下: ``` var divElement = document.getElementById("myDiv"); var lastElement = divElement.lastElementChild; lastElement.scrollIntoView(); ``` 3. 使用CSS属性scroll-behavior:该方法是CSS属性的方式来实现滚动自动滚动到底部的效果,值得推荐。代码示例如下: ``` #myDiv { scroll-behavior: smooth; } <div id="myDiv"> ... <div id="lastElement"></div> </div> // JavaScript代码 var lastElement = document.getElementById("lastElement"); lastElement.scrollIntoView({ behavior: "smooth" }); ``` 以上是三种常用的方法来实现让DIV的滚动自动滚动到最底部的效果,推荐使用第三种方法,因为它不需要通过JavaScript来修改滚动条的位置,直接使用CSS属性来实现,代码更为简洁,而且还能通过设置scroll-behavior属性来调整滚动的行为方式,提供了更好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值