Skip to content

Commit

Permalink
fix: ignore validation of removed array elements closes #3748
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Apr 10, 2022
1 parent 67c2455 commit 3d49faa
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 0 deletions.
12 changes: 12 additions & 0 deletions packages/vee-validate/src/useField.ts
Expand Up @@ -96,6 +96,8 @@ function _useField<TValue = unknown>(

const form = !standalone ? injectWithSelf(FormContextKey) : undefined;

// a flag indicating if the field is about to be removed/unmounted.
let markedForRemoval = false;
const { id, value, initialValue, meta, setState, errors, errorMessage } = useFieldState(name, {
modelValue,
standalone,
Expand Down Expand Up @@ -138,6 +140,11 @@ function _useField<TValue = unknown>(
meta.pending = true;
meta.validated = true;
const result = await validateCurrentValue('validated-only');
if (markedForRemoval) {
result.valid = true;
result.errors = [];
}

setState({ errors: result.errors });
meta.pending = false;

Expand All @@ -146,6 +153,10 @@ function _useField<TValue = unknown>(

async function validateValidStateOnly(): Promise<ValidationResult> {
const result = await validateCurrentValue('silent');
if (markedForRemoval) {
result.valid = true;
}

meta.valid = result.valid;

return result;
Expand Down Expand Up @@ -290,6 +301,7 @@ function _useField<TValue = unknown>(
form.register(field);

onBeforeUnmount(() => {
markedForRemoval = true;
form.unregister(field);
});

Expand Down
92 changes: 92 additions & 0 deletions packages/vee-validate/tests/FieldArray.spec.ts
@@ -1,3 +1,6 @@
import { defineRule, useField } from '@/vee-validate';
import { defineComponent } from '@vue/runtime-core';
import { toRef } from 'vue';
import * as yup from 'yup';
import { mountWithHoc, setValue, getValue, dispatchEvent, flushPromises } from './helpers';

Expand Down Expand Up @@ -574,3 +577,92 @@ test('clears old errors path when item is removed when no form schema is present

expect(errorList.children).toHaveLength(2);
});

// #3748
test('clears old errors path when last item is removed and value update validation is on', async () => {
const onSubmit = jest.fn();
defineRule('required', (v: any) => (v ? true : REQUIRED_MESSAGE));
const InputField = defineComponent({
props: {
rules: {
type: String,
required: true,
},
name: {
type: String,
required: true,
},
label: String,
type: { type: String, default: 'text' },
},
setup(props) {
const { value, handleChange, errors } = useField(toRef(props, 'name'), props.rules, {
label: props.label,
type: props.type,
});

return {
value,
errors,
handleChange,
};
},
template: `
<label :for="name">{{ label }}</label>
<input :type="type" :name="name" :value="value" @input="handleChange" />
<span>{{ errors[0] }}</span>
`,
});

mountWithHoc({
components: {
InputField,
},
setup() {
const initialValues = {
users: ['first', 'second', 'third'],
};

const schema = yup.string().required();

return {
onSubmit,
schema,
initialValues,
};
},
template: `
<VForm @submit="onSubmit" :initial-values="initialValues" v-slot="{ errors }">
<FieldArray name="users" v-slot="{ remove, push, fields }">
<fieldset v-for="(field, idx) in fields" :key="field.key">
<legend>User #{{ idx }}</legend>
<label :for="'name_' + idx">Name</label>
<InputField :name="'users[' + idx + ']'" rules="required" />
<button class="remove" type="button" @click="remove(idx)">X</button>
</fieldset>
</FieldArray>
<ul class="errors">
<li v-for="error in errors">{{ error }}</li>
</ul>
<button class="submit" type="submit">Submit</button>
</VForm>
`,
});

await flushPromises();
const submitBtn = document.querySelector('.submit') as HTMLButtonElement;
const errorList = document.querySelector('ul') as HTMLUListElement;
const removeBtnAt = (idx: number) => document.querySelectorAll('.remove')[idx] as HTMLButtonElement; // remove the second item

submitBtn.click();
await flushPromises();
expect(errorList.children).toHaveLength(0);
removeBtnAt(2).click();
await flushPromises();

expect(errorList.children).toHaveLength(0);
});

0 comments on commit 3d49faa

Please sign in to comment.