fix(Form): match error-pattern on input validation (#2606)

This commit is contained in:
Romain Hamel
2024-11-11 22:50:22 +01:00
committed by GitHub
parent 6d3dbdbee5
commit 3584a3328b
5 changed files with 19 additions and 10 deletions

View File

@@ -32,7 +32,7 @@ const schema = z.object({
slider: z.number().max(20, { message: 'Must be less than 20' })
})
type Schema = z.output<typeof schema>
type Schema = z.input<typeof schema>
const state = reactive<Partial<Schema>>({})

View File

@@ -94,13 +94,13 @@ onUnmounted(() => {
const errors = ref<FormErrorWithId[]>([])
provide('form-errors', errors)
const inputs = ref<Record<string, string>>({})
const inputs = ref<Record<string, { id?: string, pattern?: RegExp }>>({})
provide(formInputsInjectionKey, inputs)
function resolveErrorIds(errs: FormError[]): FormErrorWithId[] {
return errs.map(err => ({
...err,
id: inputs.value[err.name]
id: inputs.value[err.name]?.id
}))
}
@@ -129,7 +129,7 @@ async function getErrors(): Promise<FormErrorWithId[]> {
}
async function _validate(opts: { name?: string | string[], silent?: boolean, nested?: boolean } = { silent: false, nested: true }): Promise<T | false> {
const names = opts.name && !Array.isArray(opts.name) ? [opts.name] : opts.name
const names = opts.name && !Array.isArray(opts.name) ? [opts.name] : opts.name as string[]
const nestedValidatePromises = !names && opts.nested
? Array.from(nestedForms.value.values()).map(
@@ -143,9 +143,16 @@ async function _validate(opts: { name?: string | string[], silent?: boolean, nes
: []
if (names) {
const otherErrors = errors.value.filter(error => !names!.includes(error.name))
const pathErrors = (await getErrors()).filter(error => names!.includes(error.name)
)
const otherErrors = errors.value.filter(error => !names.some((name) => {
const pattern = inputs.value?.[name]?.pattern
return name === error.name || (pattern && error.name.match(pattern))
}))
const pathErrors = (await getErrors()).filter(error => names.some((name) => {
const pattern = inputs.value?.[name]?.pattern
return name === error.name || (pattern && error.name.match(pattern))
}))
errors.value = otherErrors.concat(pathErrors)
} else {
errors.value = await getErrors()

View File

@@ -68,7 +68,8 @@ provide(formFieldInjectionKey, computed(() => ({
name: props.name,
size: props.size,
eagerValidation: props.eagerValidation,
validateOnInputDelay: props.validateOnInputDelay
validateOnInputDelay: props.validateOnInputDelay,
errorPattern: props.errorPattern
}) as FormFieldInjectedOptions<FormFieldProps>))
</script>

View File

@@ -19,7 +19,7 @@ export const formOptionsInjectionKey: InjectionKey<ComputedRef<FormInjectedOptio
export const formBusInjectionKey: InjectionKey<UseEventBusReturn<FormEvent, string>> = Symbol('nuxt-ui.form-events')
export const formFieldInjectionKey: InjectionKey<ComputedRef<FormFieldInjectedOptions<FormFieldProps>>> = Symbol('nuxt-ui.form-field')
export const inputIdInjectionKey: InjectionKey<Ref<string | undefined>> = Symbol('nuxt-ui.input-id')
export const formInputsInjectionKey: InjectionKey<Ref<Record<string, string>>> = Symbol('nuxt-ui.form-inputs')
export const formInputsInjectionKey: InjectionKey<Ref<Record<string, { id?: string, pattern?: RegExp }>>> = Symbol('nuxt-ui.form-inputs')
export const formLoadingInjectionKey: InjectionKey<Readonly<Ref<boolean>>> = Symbol('nuxt-ui.form-loading')
export function useFormField<T>(props?: Props<T>, opts?: { bind?: boolean }) {
@@ -38,7 +38,7 @@ export function useFormField<T>(props?: Props<T>, opts?: { bind?: boolean }) {
inputId.value = props?.id
}
if (formInputs && formField.value.name && inputId.value) {
formInputs.value[formField.value.name] = inputId.value
formInputs.value[formField.value.name] = { id: inputId.value, pattern: formField.value.errorPattern }
}
}

View File

@@ -82,6 +82,7 @@ export interface FormFieldInjectedOptions<T> {
error?: string | boolean
eagerValidation?: boolean
validateOnInputDelay?: number
errorPattern?: RegExp
}
export class FormValidationException extends Error {