Skip to content

Commit

Permalink
Add willScrollToError to Form (#1559)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpylua authored Nov 24, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 7117d19 commit 4a8ab0a
Showing 2 changed files with 33 additions and 2 deletions.
33 changes: 32 additions & 1 deletion packages/zent/src/form/Form.tsx
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@ import { CombineErrors } from './CombineErrors';
import { ValidateOccasion, TouchWhen } from './shared';
import { Disabled } from '../disabled';
import getScrollPosition from '../utils/dom/getScollPosition';
import isPromise from '../utils/isPromise';

export {
IRenderError,
@@ -59,38 +60,51 @@ export interface IFormProps<T extends {}>
* @defaultValue `'vertical'`
*/
layout?: 'horizontal' | 'vertical';

/**
* `useForm`得到的`model`
*/
form: ZentForm<T>;

/**
* @deprecated
* 禁用表单输入,开启后表单内所有元素不可编辑。注意:自定义组件需要自己实现禁用逻辑和展示
*/
disabled?: boolean;

/**
* 表单校验报错时自动滚动到第一个错误的位置
*/
scrollToError?: boolean;

/**
* 触发滚动到第一个错误前的回调函数
* 如果返回一个 `Promise`,当 `Promise` `resolve` 时才会继续执行滚动,`reject` 将终止滚动操作
*/
willScrollToError?: (form: ZentForm<T>) => void | Promise<void>;

/**
* 表单提交回调函数,`form.submit` 或者原生的 `DOM` 触发的 `submit` 事件都会触发 `onSubmit`
*/
onSubmit?: (
form: ZentForm<T>,
e?: React.SyntheticEvent
) => void | Promise<unknown>;

/**
* 表单提交失败时的回调函数
*/
onSubmitFail?: (e: unknown) => void;

/**
* 表单提交成功时的回调函数
*/
onSubmitSuccess?: () => void;

/**
* 表单重置回调函数,`form.reset` 或者原生的 `DOM` 触发的 `reset` 事件都会触发 `onReset`
*/
onReset?: (e?: React.FormEvent<HTMLFormElement>) => void;

/**
* 禁用表单内 `input` 元素的回车提交功能
*/
@@ -196,6 +210,23 @@ export class Form<T extends {}> extends React.Component<IFormProps<T>> {
}

scrollToFirstError() {
const { willScrollToError, form } = this.props;
if (typeof willScrollToError !== 'function') {
this._scrollToFirstError();
} else {
const p = willScrollToError(form);
if (!isPromise<void>(p)) {
this._scrollToFirstError();
} else {
// Do not scroll if promise rejects
p.then(() => {
this._scrollToFirstError();
}).catch(() => {});
}
}
}

private _scrollToFirstError() {
let scrollX = Infinity;
let scrollY = Infinity;
for (let i = 0; i < this.children.length; i += 1) {
2 changes: 1 addition & 1 deletion packages/zent/src/utils/isPromise.ts
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
* @param {any} obj
* @returns {bool}
*/
export default function isPromise(obj: any): obj is Promise<unknown> {
export default function isPromise<T = unknown>(obj: any): obj is Promise<T> {
return (
!!obj &&
(typeof obj === 'object' || typeof obj === 'function') &&

0 comments on commit 4a8ab0a

Please sign in to comment.