Skip to content

Commit

Permalink
Merge ef3b407 into f3c2220
Browse files Browse the repository at this point in the history
  • Loading branch information
pointhalo committed Sep 12, 2024
2 parents f3c2220 + ef3b407 commit fdefb88
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 11 deletions.
3 changes: 2 additions & 1 deletion content/input/form/index-en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -2068,7 +2068,8 @@ render(WithFieldDemo2);
| labelPosition | Location of label in Field, optional 'top', 'left', 'inset' <br/> (inset label only partial component support) | string | 'top' |
| labelWidth | Width of field'r label | string\|number | |
| onChange | Callback invoked when form update, including Fields mount/unmount / value change / <br/> blur / validation status change / error status change. | function (formState: object) | |
| onValueChange | Callback invoked when form values update | function (values: object, changedValue: object) |
| onErrorChange | Callback when the validation state of form updated. The first parameter: formState.errors, second parameter: name of the field that has changed and it's error message (available after v2.66) | function(values:object, changedError: object) | |
| onValueChange | Callback invoked when form values update. The first parameter: formState.values, second parameter: name of the field and it's value | function (values: object, changedValue: object) |
| onReset | Callback invoked after clicked on reset button or executed `formApi.reset()` | function () | |
| onSubmit | Callback invoked after clicked on submit button or executed `formApi.submit()`, <br/>and all validation pass. | function (values: object, e: event) | |
| onSubmitFail | Callback invoked after clicked on submit button or executed `formApi.submit()`,<br/> but validate failed. | function (error: object, values: object, e: event) | |
Expand Down
1 change: 1 addition & 0 deletions content/input/form/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2066,6 +2066,7 @@ render(WithFieldDemo2);
| labelWidth | 统一配置label 宽度 | string\|number | |
| onChange | form 更新时触发,包括表单控件挂载/卸载/值变更/blur/验证状态变更/错误提示变更, 入参为 formState | function(formState:object) | |
| onValueChange | form 的值被更新时触发,仅在表单控件值发生变化时触发。第一个入参为 formState.values,第二个入参为当前发生变化的 field | function(values:object, changedValue: object) | |
| onErrorChange | form 的校验状态被更新时触发。第一个入参为 formState.errors,第二个入参为当前发生变化的 field 的名称与校验结果(v2.66后提供) | function(values:object, changedError: object) | |
| onReset | 点击 reset 按钮或调用 `formApi.reset()`时的回调函数 | function() | |
| onSubmit | 点击 submit 按钮或调用 `formApi.submitForm()`,数据验证成功后的回调函数 | function(values:object, e: event) | |
| onSubmitFail | 点击 submit 按钮或调用 `formApi.submitForm()`,数据验证失败后的回调函数 | function(errors:object, values:object, e: event) | |
Expand Down
9 changes: 7 additions & 2 deletions packages/semi-foundation/form/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ export default class FormFoundation extends BaseFoundation<BaseFormAdapter> {
} else {
this.data.errors = result;
this._adapter.notifyChange(this.data);

this.injectErrorToField(result);
this._adapter.forceUpdate();
this._autoScroll(100);
Expand All @@ -212,6 +213,7 @@ export default class FormFoundation extends BaseFoundation<BaseFormAdapter> {
this.data.errors = maybePromisedErrors;
this.injectErrorToField(maybePromisedErrors);
this._adapter.notifyChange(this.data);

this._adapter.forceUpdate();
this._autoScroll(100);
reject(maybePromisedErrors);
Expand Down Expand Up @@ -241,6 +243,7 @@ export default class FormFoundation extends BaseFoundation<BaseFormAdapter> {
Promise.all(promiseSet).then(() => {
// After the centralized verification is completed, trigger notify and forceUpdate once.
this._adapter.notifyChange(this.data);

this._adapter.forceUpdate();
const errors = this.getError();
if (this._isValid(targetFields)) {
Expand Down Expand Up @@ -493,12 +496,14 @@ export default class FormFoundation extends BaseFoundation<BaseFormAdapter> {
const notNotify = opts && opts.notNotify;
const notUpdate = opts && opts.notUpdate;
ObjectUtil.set(this.data.errors, field, error);


// The setError caused by centralized validation does not need to trigger notify, otherwise it will be called too frequently, as many times as there are fields
// 集中validate时,引起的setError不需要触发notify,否则会过于频繁调用,有多少个field就调用了多少次
if (!notNotify) {
this._adapter.notifyChange(this.data);
}

this._adapter.notifyErrorChange(this.data.errors, { [field]: error });

if (!notUpdate) {
this._adapter.forceUpdate(callback);
}
Expand Down
1 change: 1 addition & 0 deletions packages/semi-foundation/form/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface BaseFormAdapter<P = Record<string, any>, S = Record<string, any
forceUpdate: (callback?: () => void) => void;
notifyChange: (formState: FormState) => void;
notifyValueChange: (values: any, changedValues: any) => void;
notifyErrorChange: (errors: any, changedError: any) => void;
notifyReset: () => void;
getInitValues: () => Partial<Values>;
getFormProps: (keys: undefined | string | Array<string>) => any;
Expand Down
21 changes: 16 additions & 5 deletions packages/semi-ui/form/_story/Validate/validateDemo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ class ValidateFieldsDemo extends Component {
autoScrollToError
validateFields={this.syncValidate}
onReset={v => console.log('reset')}
onChange={v => console.log(v)}
onValueChange={v => console.log('onValueChange')}>
// onChange={v => console.log(v)}
onValueChange={(values, changedField) => console.log('onValueChange', values, changedField)}
onErrorChange={(errors, changedField) => console.log('onErrorChange', errors, changedField)}
>
<Form.InputGroup label="group" style={{ width: 600 }}>
<Input field="group.name" style={{ width: 280 }} />
<Input field="group.sort" style={{ width: 290 }} />
Expand Down Expand Up @@ -142,7 +144,10 @@ class CustomValidateDemo extends Component {

render() {
return (
<Form autoScrollToError>
<Form
autoScrollToError
onErrorChange={(errors, changedField) => console.log(errors, changedField)}
>
<Input field="name" validate={this.asyncValidate} trigger="blur" />
<Input field="familyName" validate={this.validateName} trigger="blur" name="familyName" />
<Input field="code" validate={this.asyncValidate} trigger={['change', 'mount']} />
Expand Down Expand Up @@ -203,7 +208,11 @@ class PartValidAndResetDemo extends Component {
render() {
let options = ['a', 'b', 'c', 'd', 'b.name'].map(item => ({ label: item, value: item }));
return (
<Form getFormApi={this.getFormApi} autoScrollToError>
<Form
getFormApi={this.getFormApi}
autoScrollToError
onErrorChange={(errors, changedField) => console.log(errors, changedField)}
>
<Input field="a[1]" validate={this.validate} trigger="blur" />
<Input field="a[0]" validate={this.validate} trigger="blur" />
<Input field="ackk" validate={this.validate} trigger="blur" />
Expand Down Expand Up @@ -258,7 +267,9 @@ class RulesValidateDemo extends Component {
autoScrollToError
onReset={v => console.log('reset')}
onChange={v => console.log(v)}
onValueChange={v => console.log('onValueChange')}>
onValueChange={v => console.log('onValueChange')}
onErrorChange={(errors, changedField) => console.log(errors, changedField)}
>
<Input field="panel[0].a" trigger="custom" rules={[{ required: true, message: '字段不能为空' }]} />
<Input field="panel[0].b" trigger="custom" rules={[{ required: true, message: '字段不能为空' }]} />
<Input field="panel[0].c" trigger="custom" rules={[{ required: true, message: '字段不能为空' }]} />
Expand Down
7 changes: 6 additions & 1 deletion packages/semi-ui/form/baseForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { cloneDeep } from '../_utils/index';
import Slot from './slot';
import Section from './section';
import Label from './label';
import ErrorMessage from './errorMessage';
import ErrorMessage, { ReactFieldError } from './errorMessage';
import FormInputGroup from './group';
import { noop } from 'lodash';
import '@douyinfe/semi-foundation/form/form.scss';
Expand Down Expand Up @@ -93,6 +93,7 @@ class Form<Values extends Record<string, any> = any> extends BaseComponent<BaseF
onSubmit: noop,
onReset: noop,
onValueChange: noop,
onErrorChange: noop,
layout: 'vertical',
labelPosition: 'top',
allowEmpty: false,
Expand Down Expand Up @@ -180,6 +181,9 @@ class Form<Values extends Record<string, any> = any> extends BaseComponent<BaseF
notifyValueChange: (values: Values, changedValues: Partial<Values>) => {
this.props.onValueChange(values, changedValues);
},
notifyErrorChange: (errors: Record<keyof Values, ReactFieldError>, changedError: Partial<Record<keyof Values, ReactFieldError>>) => {
this.props.onErrorChange(errors, changedError);
},
notifyReset: () => {
this.props.onReset();
},
Expand Down Expand Up @@ -269,6 +273,7 @@ class Form<Values extends Record<string, any> = any> extends BaseComponent<BaseF
onChange,
onSubmit,
onSubmitFail,
onErrorChange,
onValueChange,
component,
render,
Expand Down
4 changes: 2 additions & 2 deletions packages/semi-ui/form/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export type CommonexcludeType = {

export type RadioCheckboxExcludeProps = {
defaultValue?: any;
chekced?: boolean;
checked?: boolean;
defaultChecked?: boolean;
field: string
};
Expand Down Expand Up @@ -97,13 +97,13 @@ export interface FormFCChild<K extends Record<string, any> = any> {
}



export interface BaseFormProps <Values extends Record<string, any> = any> extends Omit<React.FormHTMLAttributes<HTMLFormElement>, 'children' | 'onChange' | 'onSubmit' | 'onReset'> {
'aria-label'?: React.AriaAttributes['aria-label'];
onSubmit?: (values: Values, e?: React.FormEvent<HTMLFormElement>) => void;
onSubmitFail?: (errors: Record<keyof Values, FieldError>, values: Partial<Values>, e?: React.FormEvent<HTMLFormElement>) => void;
onReset?: () => void;
onValueChange?: (values: Values, changedValue: Partial<Values>) => void;
onErrorChange?: (errors: Record<keyof Values, FieldError>, changedError?: Partial<Record<keyof Values, FieldError>>) => void;
onChange?: (formState: FormState<Values>) => void;
allowEmpty?: boolean;
validateFields?: (values: Values) => string | Partial<AllErrors<Values>>;
Expand Down

0 comments on commit fdefb88

Please sign in to comment.