Skip to content

Commit

Permalink
fix: pass onInvalidSubmit prop to submitForm closes #3841
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Jul 12, 2022
1 parent d760b78 commit b6cf543
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
11 changes: 8 additions & 3 deletions packages/vee-validate/src/Form.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { h, defineComponent, toRef, resolveDynamicComponent, PropType, VNode, UnwrapRef } from 'vue';
import { useForm } from './useForm';
import { SubmissionHandler, InvalidSubmissionHandler } from './types';
import { isEvent, normalizeChildren } from './utils';
import { isEvent, isFormSubmitEvent, normalizeChildren } from './utils';
import { FormContext } from '.';

type FormSlotProps = UnwrapRef<
Expand All @@ -15,7 +15,6 @@ type FormSlotProps = UnwrapRef<
| 'validate'
| 'validateField'
| 'handleReset'
| 'submitForm'
| 'setErrors'
| 'setFieldError'
| 'setFieldValue'
Expand All @@ -26,6 +25,7 @@ type FormSlotProps = UnwrapRef<
>
> & {
handleSubmit: (evt: Event | SubmissionHandler, onSubmit?: SubmissionHandler) => Promise<unknown>;
submitForm(evt?: Event): void;
};

const FormImpl = defineComponent({
Expand Down Expand Up @@ -85,7 +85,6 @@ const FormImpl = defineComponent({
handleReset,
resetForm,
handleSubmit,
submitForm,
setErrors,
setFieldError,
setFieldValue,
Expand All @@ -101,6 +100,12 @@ const FormImpl = defineComponent({
keepValuesOnUnmount: keepValues,
});

const submitForm = handleSubmit((_, { evt }) => {
if (isFormSubmitEvent(evt)) {
evt.target.submit();
}
}, props.onInvalidSubmit);

const onSubmit = props.onSubmit ? handleSubmit(props.onSubmit, props.onInvalidSubmit) : submitForm;
function handleFormReset(e?: Event) {
if (isEvent(e)) {
Expand Down
61 changes: 61 additions & 0 deletions packages/vee-validate/tests/Form.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2553,6 +2553,67 @@ describe('<Form />', () => {
expect(validSpy).not.toHaveBeenCalled();
});

test('handles invalid submissions with submitForm', async () => {
const invalidSpy = jest.fn();
const validSpy = jest.fn();
const wrapper = mountWithHoc({
setup() {
const schema = yup.object({
email: yup.string().required().email(),
password: yup.string().required().min(8),
});

return {
schema,
onInvalidSubmit: invalidSpy,
onSubmit: validSpy,
};
},
template: `
<VForm v-slot="{ submitForm, errors }" :validationSchema="schema" @invalid-submit="onInvalidSubmit">
<form @submit="submitForm">
<Field id="email" name="email" as="input" />
<span id="emailErr">{{ errors.email }}</span>
<Field id="password" name="password" as="input" type="password" />
<span id="passwordErr">{{ errors.password }}</span>
<button>Submit</button>
</form>
</VForm>
`,
});

const expectedEmailError = 'email is a required field';
const expectedPasswordError = 'password is a required field';
await flushPromises();
wrapper.$el.querySelector('button').click();
await flushPromises();
expect(invalidSpy).toHaveBeenCalledTimes(1);
expect(invalidSpy).toHaveBeenLastCalledWith({
values: {
email: undefined,
password: undefined,
},
errors: {
email: expectedEmailError,
password: expectedPasswordError,
},
evt: expect.anything(),
results: {
email: {
valid: false,
errors: [expectedEmailError],
},
password: {
valid: false,
errors: [expectedPasswordError],
},
},
} as InvalidSubmissionContext);
expect(validSpy).not.toHaveBeenCalled();
});

// #3551
test('resets checkboxes according to initial values', async () => {
const wrapper = mountWithHoc({
Expand Down

0 comments on commit b6cf543

Please sign in to comment.