Skip to content

Commit

Permalink
feat: rules support warningOnly (#304)
Browse files Browse the repository at this point in the history
* 1.20.1

* feat: Support onError event

* fix: Every update errors should trigger event

* test: Test driven of onError

* feat: All message support variable

* fix: Fill template logic

* feat: support warning

* test: Test driven

* chore: export getFieldWarning

* fix: summary validate logic

* test: Update coverage

* test: Update coverage
  • Loading branch information
zombieJ committed Jun 2, 2021
1 parent 29be013 commit ec3a5bc
Show file tree
Hide file tree
Showing 15 changed files with 561 additions and 327 deletions.
12 changes: 9 additions & 3 deletions docs/examples/components/LabelField.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import * as React from 'react';
import Form from 'rc-field-form';
import { FieldProps } from '@/Field';
import type { FieldProps } from '@/Field';

const { Field } = Form;

const Error = ({ children }) => (
<ul style={{ color: 'red' }}>
interface ErrorProps {
warning?: boolean;
children?: React.ReactNode[];
}

const Error = ({ children, warning }: ErrorProps) => (
<ul style={{ color: warning ? 'orange' : 'red' }}>
{children.map((error: React.ReactNode, index: number) => (
<li key={index}>{error}</li>
))}
Expand Down Expand Up @@ -55,6 +60,7 @@ const LabelField: React.FunctionComponent<LabelFieldProps> = ({

<FieldState {...meta} />
<Error>{meta.errors}</Error>
<Error warning>{meta.warnings}</Error>
</div>
);
}}
Expand Down
18 changes: 17 additions & 1 deletion docs/examples/validate-perf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export default class Demo extends React.Component {
console.log('Failed:', errorInfo);
};

public onPasswordError = (errors: string[]) => {
console.log('🐞 Password Error:', errors);
};

public render() {
return (
<div>
Expand All @@ -49,7 +53,18 @@ export default class Demo extends React.Component {
<LabelField
name="password"
messageVariables={{ displayName: '密码' }}
rules={[{ required: true }]}
rules={[
{ required: true },
{
warningOnly: true,
validator: async (_, value: string = '') => {
if (value.length < 6) {
throw new Error('你的 ${displayName} 太短了……');
}
},
},
]}
onError={this.onPasswordError}
>
<Input placeholder="password" />
</LabelField>
Expand Down Expand Up @@ -118,6 +133,7 @@ export default class Demo extends React.Component {
>
Reset
</button>
<button type="reset">Reset Native</button>
</Form>
</div>
);
Expand Down
262 changes: 132 additions & 130 deletions docs/examples/validate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,139 +33,141 @@ const FieldState = ({ form, name }) => {
);
};

export default class Demo extends React.Component {
onFinish = values => {
export default () => {
const onFinish = (values: object) => {
console.log('Finish:', values);
};

render() {
return (
<div>
<h3>Validate Form</h3>
<Form style={{ padding: 16 }} onFinish={this.onFinish}>
{(values, form) => {
const usernameError = form.getFieldError('username');
const passwordError = form.getFieldError('password');
const password2Error = form.getFieldError('password2');
const errors = form.getFieldsError();
if (errors) {
console.log('Render with Errors:', values, form.getFieldsError());
}

return (
<React.Fragment>
<Field name="username" rules={[{ required: true }]}>
<Input
placeholder="Username"
onChange={({ target: { value } }) => {
console.log('Username change:', value);
}}
/>
</Field>
<FieldState form={form} name="username" />
<Error>{usernameError}</Error>

<Field
name="password"
rules={[
{ required: true },
context => ({
validator(_, __, callback) {
if (context.isFieldTouched('password2')) {
context.validateFields(['password2']);
callback();
return;
}
const onNameError = (errors: string[]) => {
console.log('🐞 Name Error Change:', errors);
};

return (
<div style={{ position: 'relative' }}>
<h3>Validate Form</h3>
<Form style={{ padding: 16 }} onFinish={onFinish}>
{(values, form) => {
const usernameError = form.getFieldError('username');
const passwordError = form.getFieldError('password');
const password2Error = form.getFieldError('password2');
const errors = form.getFieldsError();
if (errors) {
console.log('Render with Errors:', values, form.getFieldsError());
}

return (
<React.Fragment>
<Field name="username" rules={[{ required: true }]} onError={onNameError}>
<Input
placeholder="Username"
onChange={({ target: { value } }) => {
console.log('Username change:', value);
}}
/>
</Field>
<FieldState form={form} name="username" />
<Error>{usernameError}</Error>

<Field
name="password"
rules={[
{ required: true },
context => ({
validator(_, __, callback) {
if (context.isFieldTouched('password2')) {
context.validateFields(['password2']);
callback();
},
}),
]}
>
<Input placeholder="Password" />
</Field>
<FieldState form={form} name="password" />
<Error>{passwordError}</Error>

<Field
name="password2"
rules={[
{ required: true },
context => ({
validator(rule, value, callback) {
const { password } = context.getFieldsValue(true);
if (password !== value) {
callback('Not Same as password1!!!');
return;
}
callback();
},
}),
]}
>
<Input placeholder="Password" />
</Field>
<FieldState form={form} name="password" />
<Error>{passwordError}</Error>

<Field
name="password2"
rules={[
{ required: true },
context => ({
validator(rule, value, callback) {
const { password } = context.getFieldsValue(true);
if (password !== value) {
callback('Not Same as password1!!!');
}
callback();
},
}),
]}
>
<Input placeholder="Password 2" />
</Field>
<FieldState form={form} name="password2" />
<Error>{password2Error}</Error>

<Field name="renderProps" rules={[{ required: true }]}>
{(control, meta) => (
<div>
Use Meta:
<Input {...control} placeholder="render props" />
<FieldState form={form} name="renderProps" />
<Error>{meta.errors}</Error>
</div>
)}
</Field>

<Field
name="validateTrigger"
validateTrigger={['onSubmit', 'onChange']}
rules={[
{ required: true, validateTrigger: 'onSubmit' },
{
validator(rule, value, callback) {
setTimeout(() => {
if (Number(value).toString() === value) {
callback();
}
callback();
},
}),
]}
>
<Input placeholder="Password 2" />
</Field>
<FieldState form={form} name="password2" />
<Error>{password2Error}</Error>

<Field name="renderProps" rules={[{ required: true }]}>
{(control, meta) => (
<div>
Use Meta:
<Input {...control} placeholder="render props" />
<FieldState form={form} name="renderProps" />
<Error>{meta.errors}</Error>
</div>
)}
</Field>

<Field
name="validateTrigger"
validateTrigger={['onSubmit', 'onChange']}
rules={[
{ required: true, validateTrigger: 'onSubmit' },
{
validator(rule, value, callback) {
setTimeout(() => {
if (Number(value).toString() === value) {
callback();
}
callback('Integer number only!');
}, 1000);
},
validateTrigger: 'onChange',
callback('Integer number only!');
}, 1000);
},
]}
>
{(control, meta) => (
<div>
Multiple `validateTrigger`:
<ul>
<li>Required check on submit</li>
<li>Number check on change</li>
</ul>
<Input {...control} placeholder="validateTrigger" />
<FieldState form={form} name="validateTrigger" />
<Error>{meta.errors}</Error>
</div>
)}
</Field>

<br />

<button
type="button"
onClick={() => {
form.validateFields();
}}
>
Validate All
</button>

<button type="submit">Submit</button>
</React.Fragment>
);
}}
</Form>
</div>
);
}
}
validateTrigger: 'onChange',
},
]}
>
{(control, meta) => (
<div>
Multiple `validateTrigger`:
<ul>
<li>Required check on submit</li>
<li>Number check on change</li>
</ul>
<Input {...control} placeholder="validateTrigger" />
<FieldState form={form} name="validateTrigger" />
<Error>{meta.errors}</Error>
</div>
)}
</Field>

<br />

<button
type="button"
onClick={() => {
form.validateFields();
}}
>
Validate All
</button>

<button type="submit">Submit</button>
</React.Fragment>
);
}}
</Form>
</div>
);
};
Loading

1 comment on commit ec3a5bc

@vercel
Copy link

@vercel vercel bot commented on ec3a5bc Jun 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.