Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): 支持用户配置 validator 在哪些 pattern & display 下生效 #4211

Open
wants to merge 1 commit into
base: formily_next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/core/docs/api/models/Form.md
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,8 @@ interface IFieldFactoryProps {
readPretty?: boolean //Whether the field is in the read state
dataSource?: any[] //Field data source
validateFirst?: boolean //Does the field verification only verify the first illegal rule?
validatePattern?: ('editable' | 'disabled' | 'readOnly' | 'readPretty')[] // Which patterns the validator can run in
validateDisplay?: ('none' | 'hidden' | 'visible')[] // Which displays the validator can run in
validator?: FieldValidator //Field validator
decorator?: any[] //Field decorator, the first element represents the component reference, the second element represents the component attribute
component?: any[] //Field component, the first element represents the component reference, the second element represents the component attribute
Expand Down
2 changes: 2 additions & 0 deletions packages/core/docs/api/models/Form.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,8 @@ interface IFieldFactoryProps {
readPretty?: boolean //字段是否为阅读态
dataSource?: any[] //字段数据源
validateFirst?: boolean //字段校验是否只校验第一个非法规则
validatePattern?: ('editable' | 'disabled' | 'readOnly' | 'readPretty')[] // validator 可以在哪些 pattern 下运行
validateDisplay?: ('none' | 'hidden' | 'visible')[] // validator 可以在哪些 display 下运行
validator?: FieldValidator //字段校验器
decorator?: any[] //字段装饰器,第一个元素代表组件引用,第二个元素代表组件属性
component?: any[] //字段组件,第一个元素代表组件引用,第二个元素代表组件属性
Expand Down
47 changes: 47 additions & 0 deletions packages/core/src/__tests__/field.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2402,3 +2402,50 @@ test('onFocus and onBlur with invalid target value', async () => {
'The field value is a invalid url',
])
})

test('validatePattern and validateDisplay', async () => {
const form = attach(
createForm<any>({
validatePattern: ['editable'],
validateDisplay: ['visible'],
})
)
const field1 = attach(
form.createField({
name: 'a',
required: true,
})
)
const field2 = attach(
form.createField({
name: 'b',
required: true,
validatePattern: ['readOnly'],
validateDisplay: ['hidden'],
})
)
const field3 = attach(
form.createField({
name: 'c',
required: true,
validatePattern: ['readOnly', 'editable'],
validateDisplay: ['hidden', 'visible'],
})
)

try {
await form.validate()
} catch {}
expect(field1.selfErrors.length).toBe(1)
expect(field2.selfErrors.length).toBe(0)
expect(field3.selfErrors.length).toBe(1)

form.setPattern('readOnly')
form.setDisplay('hidden')
try {
await form.validate()
} catch {}
expect(field1.selfErrors.length).toBe(0)
expect(field2.selfErrors.length).toBe(1)
expect(field3.selfErrors.length).toBe(1)
})
15 changes: 13 additions & 2 deletions packages/core/src/shared/internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -880,14 +880,25 @@ export const batchSubmit = async <T>(
return results
}

const shouldValidate = (field: Field) => {
const validatePattern = field.props.validatePattern ??
field.form.props.validatePattern ?? ['editable']
const validateDisplay = field.props.validateDisplay ??
field.form.props.validateDisplay ?? ['visible']
return (
validatePattern.includes(field.pattern) &&
validateDisplay.includes(field.display)
)
}

export const batchValidate = async (
target: Form | Field,
pattern: FormPathPattern,
triggerType?: ValidatorTriggerType
) => {
if (isForm(target)) target.setValidating(true)
else {
if (target.pattern !== 'editable' || target.display !== 'visible') return
if (!shouldValidate(target)) return
}
const tasks = []
target.query(pattern).forEach((field) => {
Expand Down Expand Up @@ -945,7 +956,7 @@ export const validateSelf = batch.bound(
}
}

if (target.pattern !== 'editable' || target.display !== 'visible') return {}
if (!shouldValidate(target)) return {}
start()
if (!triggerType) {
const allTriggerTypes = parseValidatorDescriptions(
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ export interface IFormProps<T extends object = any> {
readPretty?: boolean
effects?: (form: Form<T>) => void
validateFirst?: boolean
validatePattern?: FormPatternTypes[]
validateDisplay?: FormDisplayTypes[]
designable?: boolean
}

Expand Down Expand Up @@ -349,6 +351,8 @@ export interface IFieldProps<
readPretty?: boolean
dataSource?: FieldDataSource
validateFirst?: boolean
validatePattern?: FieldPatternTypes[]
validateDisplay?: FieldDisplayTypes[]
validator?: FieldValidator
decorator?: FieldDecorator<Decorator>
component?: FieldComponent<Component>
Expand Down
Loading