Skip to content

Commit

Permalink
fix: reset form and field behaviors for unspecified values closes #4564
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Nov 28, 2023
1 parent c1c6f39 commit 36f6b9e
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-squids-deliver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vee-validate': patch
---

fix: reset form and field behaviors for unspecified values closes #4564
2 changes: 1 addition & 1 deletion packages/vee-validate/src/types/forms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ export interface PrivateFormContext<TValues extends GenericObject = GenericObjec
stageInitialValue(path: string, value: unknown, updateOriginal?: boolean): void;
unsetInitialValue(path: string): void;
handleSubmit: HandleSubmitFactory<TValues, TOutput> & { withControlled: HandleSubmitFactory<TValues, TOutput> };
setFieldInitialValue(path: string, value: unknown): void;
setFieldInitialValue(path: string, value: unknown, updateOriginal?: boolean): void;
createPathState<TPath extends Path<TValues>>(
path: MaybeRef<TPath>,
config?: Partial<PathStateConfig>,
Expand Down
2 changes: 1 addition & 1 deletion packages/vee-validate/src/useFieldState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export function _useFieldValue<TValue = unknown>(
return;
}

form.stageInitialValue(unref(path), value, true);
form.setFieldInitialValue(unref(path), value, true);
}

const initialValue = computed(resolveInitialValue);
Expand Down
8 changes: 6 additions & 2 deletions packages/vee-validate/src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ export function useForm<
pathState.__flags.pendingReset = true;
}

setFieldInitialValue(field, deepCopy(newValue));
setFieldInitialValue(field, deepCopy(newValue), true);
setFieldValue(field, newValue as PathValue<TValues, typeof field>, false);
setFieldTouched(field, state?.touched ?? false);
setFieldError(field, state?.errors || []);
Expand All @@ -768,6 +768,7 @@ export function useForm<
function resetForm(resetState?: Partial<FormState<TValues>>, opts?: ResetFormOpts) {
let newValues = deepCopy(resetState?.values ? resetState.values : originalInitialValues.value);
newValues = isTypedSchema(schema) && isCallable(schema.cast) ? schema.cast(newValues) : newValues;
newValues = opts?.force ? newValues : merge(originalInitialValues.value, newValues);
setInitialValues(newValues);
mutateAllPathState(state => {
state.__flags.pendingReset = true;
Expand Down Expand Up @@ -886,8 +887,11 @@ export function useForm<
}
}

function setFieldInitialValue(path: string, value: unknown) {
function setFieldInitialValue(path: string, value: unknown, updateOriginal = false) {
setInPath(initialValues.value, path, deepCopy(value));
if (updateOriginal) {
setInPath(originalInitialValues.value, path, deepCopy(value));
}
}

async function _validateSchema(): Promise<FormValidationResult<TValues, TOutput>> {
Expand Down
63 changes: 61 additions & 2 deletions packages/vee-validate/tests/useForm.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { FieldMeta, FormContext, FormMeta, useField, useForm, defineRule, configure } from '@/vee-validate';
import {
FieldMeta,
FormContext,
FormMeta,
useField,
useForm,
defineRule,
configure,
FieldContext,
} from '@/vee-validate';
import { mountWithHoc, setValue, flushPromises, dispatchEvent } from './helpers';
import * as yup from 'yup';
import { onMounted, ref, Ref } from 'vue';
import { ModelComp, CustomModelComp } from './helpers/ModelComp';
import { FieldContext } from '../dist/vee-validate';

describe('useForm()', () => {
const REQUIRED_MESSAGE = 'Field is required';
Expand Down Expand Up @@ -1292,4 +1300,55 @@ describe('useForm()', () => {
expect(form.values.lname).toBeUndefined();
expect(form.values.fname).toBe('test');
});

test('reset should not make unspecified values undefined', async () => {
let form!: FormContext<{ fname: string; lname: string }>;

mountWithHoc({
setup() {
form = useForm({
initialValues: { fname: '123', lname: '456' },
});

form.defineField('fname');
form.defineField('lname');

return {};
},
template: `
<div></div>
`,
});

await flushPromises();

form.resetForm({ values: { fname: 'test' } });
expect(form.values.lname).toBe('456');
expect(form.values.fname).toBe('test');
});

test('reset field should make the dirty state false', async () => {
let form!: FormContext<{ fname: string; lname: string }>;

mountWithHoc({
setup() {
form = useForm({
initialValues: { fname: '123', lname: '456' },
});

form.defineField('fname');
form.defineField('lname');

return {};
},
template: `
<div></div>
`,
});

await flushPromises();

form.resetField('fname', { value: 'test' });
expect(form.meta.value.dirty).toBe(false);
});
});

0 comments on commit 36f6b9e

Please sign in to comment.