Skip to content

Commit 4d8ed7e

Browse files
committed
feat: added reset opts to force values closes #4440
1 parent 4addb47 commit 4d8ed7e

File tree

5 files changed

+67
-4
lines changed

5 files changed

+67
-4
lines changed

.changeset/great-students-tie.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'vee-validate': patch
3+
---
4+
5+
feat: added reset opts to force values closes #4440

docs/src/pages/api/use-form.mdx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ The number of submission attempts by the user, it increments whenever `submitFor
508508

509509
<CodeTitle level="4">
510510

511-
`resetForm: (state?: Partial<FormState>) => void`
511+
`resetForm: (state?: Partial<FormState>, opts?: ResetFormOpts) => void`
512512

513513
</CodeTitle>
514514

@@ -553,6 +553,20 @@ function onSubmit(values) {
553553
}
554554
```
555555

556+
By default `resetForm` merges the previous initial values with the new one provided, meaning only the provided ones will be overwritten. You can overwrite all the fields by passing `force: true` in the second argument.
557+
558+
```js
559+
const { values, resetForm } = useForm({
560+
initialValues: { fname: '123', lname: '456' },
561+
});
562+
563+
// values: { fname: '123', lname: '456' }
564+
resetForm({ values: { fname: 'test' } });
565+
566+
// values: { fname: 'test' }
567+
resetForm({ values: { fname: 'test' } }, { force: true });
568+
```
569+
556570
<CodeTitle level="4">
557571

558572
`handleReset: () => void`

packages/vee-validate/src/types/forms.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ export interface FormState<TValues> {
169169
export type FormErrors<TValues extends GenericObject> = Partial<Record<Path<TValues>, string | undefined>>;
170170
export type FormErrorBag<TValues extends GenericObject> = Partial<Record<Path<TValues>, string[]>>;
171171

172+
export interface ResetFormOpts {
173+
force: boolean;
174+
}
175+
172176
// eslint-disable-next-line @typescript-eslint/no-unused-vars
173177
export interface FormActions<TValues extends GenericObject, TOutput = TValues> {
174178
setFieldValue<T extends Path<TValues>>(field: T, value: PathValue<TValues, T>, shouldValidate?: boolean): void;
@@ -177,7 +181,7 @@ export interface FormActions<TValues extends GenericObject, TOutput = TValues> {
177181
setValues(fields: PartialDeep<TValues>, shouldValidate?: boolean): void;
178182
setFieldTouched(field: Path<TValues>, isTouched: boolean): void;
179183
setTouched(fields: Partial<Record<Path<TValues>, boolean>> | boolean): void;
180-
resetForm(state?: Partial<FormState<TValues>>): void;
184+
resetForm(state?: Partial<FormState<TValues>>, opts?: Partial<ResetFormOpts>): void;
181185
resetField(field: Path<TValues>, state?: Partial<FieldState>): void;
182186
}
183187

packages/vee-validate/src/useForm.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
ComponentBindsConfig,
5151
LazyInputBindsConfig,
5252
LazyComponentBindsConfig,
53+
ResetFormOpts,
5354
} from './types';
5455
import {
5556
getFromPath,
@@ -631,6 +632,22 @@ export function useForm<
631632
}
632633
}
633634

635+
function forceSetValues(fields: PartialDeep<TValues>, shouldValidate = true) {
636+
// clean up old values
637+
keysOf(formValues).forEach(key => {
638+
delete formValues[key];
639+
});
640+
641+
// set up new values
642+
keysOf(fields).forEach(path => {
643+
setFieldValue(path as Path<TValues>, fields[path], false);
644+
});
645+
646+
if (shouldValidate) {
647+
validate();
648+
}
649+
}
650+
634651
/**
635652
* Sets multiple fields values
636653
*/
@@ -726,7 +743,7 @@ export function useForm<
726743
/**
727744
* Resets all fields
728745
*/
729-
function resetForm(resetState?: Partial<FormState<TValues>>) {
746+
function resetForm(resetState?: Partial<FormState<TValues>>, opts?: ResetFormOpts) {
730747
let newValues = resetState?.values ? resetState.values : originalInitialValues.value;
731748
newValues = isTypedSchema(schema) && isCallable(schema.cast) ? schema.cast(newValues) : newValues;
732749
setInitialValues(newValues);
@@ -737,8 +754,8 @@ export function useForm<
737754
setFieldValue(state.path as Path<TValues>, getFromPath(newValues, state.path), false);
738755
setFieldError(state.path as Path<TValues>, undefined);
739756
});
740-
setValues(newValues, false);
741757

758+
opts?.force ? forceSetValues(newValues, false) : setValues(newValues, false);
742759
setErrors(resetState?.errors || {});
743760
submitCount.value = resetState?.submitCount || 0;
744761
nextTick(() => {

packages/vee-validate/tests/useForm.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,4 +1349,27 @@ describe('useForm()', () => {
13491349
expect(form.errors.value.fname).toBe(undefined);
13501350
expect(form.errors.value.lname).toBe(undefined);
13511351
});
1352+
1353+
test('values can be reset to specifically only include the provided fields', async () => {
1354+
let form!: FormContext<{ fname: string; lname: string }>;
1355+
1356+
mountWithHoc({
1357+
setup() {
1358+
form = useForm({
1359+
initialValues: { fname: '123', lname: '456' },
1360+
});
1361+
1362+
return {};
1363+
},
1364+
template: `
1365+
<div></div>
1366+
`,
1367+
});
1368+
1369+
await flushPromises();
1370+
1371+
form.resetForm({ values: { fname: 'test' } }, { force: true });
1372+
expect(form.values.lname).toBeUndefined();
1373+
expect(form.values.fname).toBe('test');
1374+
});
13521375
});

0 commit comments

Comments
 (0)