alibaba / formily

📱🚀 🧩 Cross Device & High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3
https://formilyjs.org/
MIT License
11.48k stars 1.49k forks source link

[Feature Request] 希望添加表单校验错误,页面滚动到第一个错误位置 #3261

Closed rudderstock closed 2 years ago

rudderstock commented 2 years ago

What problem does this feature solve?

表单内容较多超过一屏的时候,用户点击提交按钮后,如果校验错误的表单不在屏幕上,会无法感知到报错信息 image image

What does the proposed API look like?

scrollToFirstError: Boolean/Number;

field.validate的时候滚动到第一个出错的组件, 如果是整数会进行偏移

haoliangwu commented 2 years ago

这个问题按我的理解的话,不应该是 formily 来负责处理,因为这属于渲染层的逻辑,渲染层逻辑具有多样性,可能是在一个大页面中渲染(你这里的情况),也可能是按照 FormStep 或者 FormTabs 这种 layout 渲染,如果是后者的话,这个 api 就不够通用,自然不应属于 formily 应该负责的范畴。

这个需求在业务层其实非常好实现,只需要将 field.validate 按不同的 mvvm 框架封装一下即可。

liurongdong commented 2 years ago

滚动到错误位置需要用到scrollintoview 这个api 然后需要获取dom 这里field的dom该怎么获取呢?

frehaiku commented 2 years ago

@liurongdong 报错一般会有单独的 class,直接获取 DOM:

document.querySelector('.formily-element-form-item-error-help').scrollIntoView()
jo0ger commented 1 year ago

给元素绑定个

<div id={field.path.toString()}></div>

然后,调用 form.validate 时候 try/catch 一下,

try {
  await form.validate()
} catch(e) {
  const node = document.querySelector(`#${e[0].path}`)
  scrollIntoView(node, {
      scrollMode: 'if-needed',
      block: 'start',
    })
}

不过这里有个问题,e[0].path 可能比 e[1].path 的位置还要排在后面,这种情况出现在 有些 field 是异步挂载 或者需要条件判断才能挂载的,那么这些 field 的 mount 的顺序可能会排在后面