diff --git a/packages/vee-validate/src/types/forms.ts b/packages/vee-validate/src/types/forms.ts index 8cb63bd27..e571ffc0b 100644 --- a/packages/vee-validate/src/types/forms.ts +++ b/packages/vee-validate/src/types/forms.ts @@ -4,9 +4,10 @@ import { FieldValidationMetaInfo } from '../../../shared'; import { Path, PathValue } from './paths'; import { PartialDeep } from 'type-fest'; -export interface ValidationResult { +export interface ValidationResult { errors: string[]; valid: boolean; + value?: TValue; } export interface TypedSchemaError { diff --git a/packages/vee-validate/src/useForm.ts b/packages/vee-validate/src/useForm.ts index bd6bdf989..d6f3398ef 100644 --- a/packages/vee-validate/src/useForm.ts +++ b/packages/vee-validate/src/useForm.ts @@ -839,6 +839,7 @@ export function useForm< key: state.path, valid: true, errors: [], + value: state.value, }); } @@ -847,6 +848,7 @@ export function useForm< key: state.path, valid: result.valid, errors: result.errors, + value: result.value ?? state.value, }; }); }), @@ -856,12 +858,16 @@ export function useForm< const results: Partial> = {}; const errors: Partial> = {}; + const values: Partial> = {}; + for (const validation of validations) { results[validation.key as Path] = { valid: validation.valid, errors: validation.errors, }; + values[validation.key as Path] = validation.value as any; + if (validation.errors.length) { errors[validation.key as Path] = validation.errors[0]; } @@ -869,6 +875,7 @@ export function useForm< return { valid: validations.every(r => r.valid), + values: values as any, results, errors, }; diff --git a/packages/vee-validate/src/validate.ts b/packages/vee-validate/src/validate.ts index aa7315751..3dfb50522 100644 --- a/packages/vee-validate/src/validate.ts +++ b/packages/vee-validate/src/validate.ts @@ -49,7 +49,7 @@ export async function validate( | GenericValidateFunction[] | TypedSchema, options: ValidationOptions = {}, -): Promise { +): Promise> { const shouldBail = options?.bails; const field: FieldValidationContext = { name: options?.name || '{field}', @@ -65,6 +65,7 @@ export async function validate( return { errors, valid: !errors.length, + value: result.value, }; } @@ -108,12 +109,14 @@ async function _validate(field: FieldValidationContext if (field.bails) { return { + value: undefined, errors, }; } } return { + value: undefined, errors, }; } @@ -136,6 +139,7 @@ async function _validate(field: FieldValidationContext errors.push(result.error); if (field.bails) { return { + value: undefined, errors, }; } @@ -143,6 +147,7 @@ async function _validate(field: FieldValidationContext } return { + value: undefined, errors, }; } @@ -217,6 +222,7 @@ async function validateFieldWithTypedSchema(value: unknown, schema: TypedSchema } return { + value: result.value, errors: messages, }; } diff --git a/packages/zod/tests/zod.spec.ts b/packages/zod/tests/zod.spec.ts index ed6a863aa..ca140b2a0 100644 --- a/packages/zod/tests/zod.spec.ts +++ b/packages/zod/tests/zod.spec.ts @@ -356,7 +356,49 @@ test('uses zod default values for initial values', async () => { ); }); -test('uses zod transforms values for submitted values', async () => { +test('uses zod field transforms for submitted values', async () => { + const onSubmitSpy = vi.fn(); + let onSubmit!: () => void; + + const wrapper = mountWithHoc({ + setup() { + const { handleSubmit } = useForm<{ + test: string; + }>(); + + const testRules = toTypedSchema(z.string().transform(value => `modified: ${value}`)); + const { value } = useField('test', testRules); + + // submit now + onSubmit = handleSubmit(onSubmitSpy); + + return { + value, + }; + }, + template: ` +
+ +
+ `, + }); + + const input = wrapper.$el.querySelector('input'); + + setValue(input, '12345678'); + await flushPromises(); + onSubmit(); + await flushPromises(); + await expect(onSubmitSpy).toHaveBeenCalledTimes(1); + await expect(onSubmitSpy).toHaveBeenLastCalledWith( + expect.objectContaining({ + test: 'modified: 12345678', + }), + expect.anything(), + ); +}); + +test('uses zod form transforms for submitted values', async () => { const onSubmitSpy = vi.fn(); let onSubmit!: () => void; let model!: Ref;