From f1dc1359c4345c644fb90051a6478c7b6552f200 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 6 Jun 2023 03:05:32 +0300 Subject: [PATCH] fix: use event value if no checked value for checkbox/radio closes #4308 --- .changeset/lazy-years-mate.md | 5 +++ packages/vee-validate/src/useField.ts | 9 +++-- packages/vee-validate/tests/Form.spec.ts | 43 ++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 .changeset/lazy-years-mate.md diff --git a/.changeset/lazy-years-mate.md b/.changeset/lazy-years-mate.md new file mode 100644 index 000000000..038525dc7 --- /dev/null +++ b/.changeset/lazy-years-mate.md @@ -0,0 +1,5 @@ +--- +'vee-validate': patch +--- + +fix: use event value if no checked value for checkbox/radio closes #4308 diff --git a/packages/vee-validate/src/useField.ts b/packages/vee-validate/src/useField.ts index e9883749b..ad122eebe 100644 --- a/packages/vee-validate/src/useField.ts +++ b/packages/vee-validate/src/useField.ts @@ -518,12 +518,11 @@ function useFieldWithChecked( const path = toValue(name); const pathState = form?.getPathState(path); const value = normalizeEventValue(e); - let newValue!: TValue; + let newValue = unref(checkedValue) ?? value; if (form && pathState?.multiple && pathState.type === 'checkbox') { - newValue = resolveNextCheckboxValue(getFromPath(form.values, path) || [], value, undefined) as TValue; - } else { - // Single checkbox field without a form to toggle it's value - newValue = resolveNextCheckboxValue(unref(field.value), unref(checkedValue), unref(uncheckedValue)) as TValue; + newValue = resolveNextCheckboxValue(getFromPath(form.values, path) || [], newValue, undefined) as TValue; + } else if (opts?.type === 'checkbox') { + newValue = resolveNextCheckboxValue(unref(field.value), newValue, unref(uncheckedValue)) as TValue; } handleChange(newValue, shouldValidate); diff --git a/packages/vee-validate/tests/Form.spec.ts b/packages/vee-validate/tests/Form.spec.ts index 12599c878..a8a891127 100644 --- a/packages/vee-validate/tests/Form.spec.ts +++ b/packages/vee-validate/tests/Form.spec.ts @@ -3150,3 +3150,46 @@ test('unmounted fields should not be validated when keep-values is on', async () }; expect(spy).toHaveBeenLastCalledWith(expected); }); + +// #4308 +test('radio fields with single field component binding', async () => { + const submit = vi.fn(); + const model = ref(''); + const wrapper = mountWithHoc({ + setup() { + return { + onSubmit: submit, + model, + }; + }, + template: ` + + + + + + + + + `, + }); + + const inputs = wrapper.$el.querySelectorAll('input'); + const button = wrapper.$el.querySelector('button'); + + wrapper.$el.querySelector('button').click(); + await flushPromises(); + + setChecked(inputs[0]); + await flushPromises(); + button.click(); + await flushPromises(); + expect(model.value).toBe('Coffee'); + expect(submit).toHaveBeenLastCalledWith({ drink: 'Coffee' }, expect.anything()); + setChecked(inputs[1]); + await flushPromises(); + button.click(); + await flushPromises(); + expect(model.value).toBe('Tea'); + expect(submit).toHaveBeenLastCalledWith({ drink: 'Tea' }, expect.anything()); +});