需求:使用 rc-form 在一个大的页面中包含多个Form,验证如果有报错那么滚动到报错位置
首先说明一下,是不推荐这样做的,因为之前代码是这样的了,在平衡后期维护成本和代码优雅性等方面后,决定着手解决这个问题。
推荐尽量开发前期规划好,用一个Form处理整个表单,可以将一个大的Form分割为多个方法组件,放到不同的文件中,这样如果有报错滚动到报错位置会比较简单,单个文件也不会太大。
目前问题代码示例如下:
index.js render 中
<BasicInfo
{...basicInfo}
errorFlag={errorFlag}
onChange={this.handleFormChange}
/>
BasicInfo.js
import React from 'react';
import { Form, Input, Popover, Select, Icon } from 'antd';
import messages from './messages';
const { Option } = Select;
const BasicInfo = Form.create({
name: 'basicInfo',
onFieldsChange(props, changedFields) {
props.onChange(changedFields);
},
mapPropsToFields(props) {
return {
name: Form.createFormField({
...props.name,
value: props.name && props.name.value,
}),
},
})((props) => {
const { errorFlag, intl, form: { getFieldDecorator }, } = props;
return (
<Form
hideRequiredMark
className="rt-create-common-paddingLeft"
>
<div className={`rt-line-flex ${errorFlag ? 'has-error' : ''}`} style={{ alignItems: 'center' }}>
<Form.Item label={intl.formatMessage(messages.Name)}>
{getFieldDecorator('name', {
})(<Input style={{ width: 302, marginRight: '16px' }} autoComplete="off" />)}
</Form.Item>
{
errorFlag && (
<div className="ant-form-explain rt-position-errors">{intl.formatMessage(messages.Cannotbeempty)}</div>
)
}
</div>
</Form>
);
});
export default BasicInfo;
解决思路以及过程如下:
先检查了BasicInfo的ref如下:
<BasicInfo
ref={(ref)=>{
this.refBasicInfo = ref;
console.log('this.refBasicInfo',this.refBasicInfo);
}}
{...basicInfo}
errorFlag={errorFlag}
onChange={this.handleFormChange}
/>
看到了关键的方法 validateFieldsAndScroll
image.png
接下来看这个方法是否生效,添加如下代码
//点击按钮滚动到期望的报错位置
handleClick = () => {
if(this.refBasicInfo){
this.refBasicInfo.validateFieldsAndScroll(async (err, values) => {
console.log('this.refBasicInfo.validateFieldsAndScroll',err, values);
})
}
return ;
}
当点击按钮的时候报错位置的确滚动到了当前视野范围内,但是我们的项目顶部有一个导航栏把关键的报错位置刚刚好挡住了,所以想要让报错位置滚动到导航栏下方100px处,所以去查看了文档antd Form validateFieldsAndScroll 方法的使用方法和参数如下:
image.png image.png
看到如上内容后改动代码为:
//点击按钮滚动到期望的报错位置
handleClick = () => {
if(this.refBasicInfo){
this.refBasicInfo.validateFieldsAndScroll({
/**
这里可以添加force字段强制校验,对已经校验过的表单域,在 validateTrigger 再次被触发时是否再次校验;
可以传想传的任何参数过去,在自定义的validator中接收options,
const toValidate = (rule, value, callback, source, options) => {
if (options.hasError) {
callback(' ');
} else {
callback();
}
};
*/
scroll :{
offsetTop: 100,
onlyScrollIfNeeded: true,
allowHorizontalScroll: false,
}
},async (err, values) => {
console.log('this.refBasicInfo.validateFieldsAndScroll',err, values);
})
}
return ;
}
实现了预期的效果。
其他的多个form可以类似处理,依次判断即可。
参考:
https://ant.design/components/form-cn/#components-form-demo-validate-static
https://github.com/yiminghe/dom-scroll-into-view#function-parameter
网友评论