Skip to content

Commit fffad4b

Browse files
committed
fix: avoid toggling field array checkboxes values closes #3844
1 parent 7437612 commit fffad4b

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

packages/vee-validate/src/useField.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -453,14 +453,6 @@ function useCheckboxField<TValue = unknown>(
453453
handleChange(newValue, shouldValidate);
454454
}
455455

456-
onBeforeUnmount(() => {
457-
const shouldKeepValue = unref(field.keepValueOnUnmount) ?? unref(form?.keepValuesOnUnmount) ?? false;
458-
// toggles the checkbox value if it was checked and the unset behavior is set
459-
if (checked.value && !shouldKeepValue) {
460-
handleCheckboxChange(unref(checkedValue), false);
461-
}
462-
});
463-
464456
return {
465457
...field,
466458
checked,

packages/vee-validate/src/useForm.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,6 @@ export function useForm<TValues extends Record<string, any> = Record<string, any
400400

401401
fieldAtPath.splice(idx, 1);
402402

403-
if (fieldAtPath.length === 1) {
404-
fieldsByPath.value[fieldPath] = fieldAtPath[0];
405-
return;
406-
}
407-
408403
if (!fieldAtPath.length) {
409404
delete fieldsByPath.value[fieldPath];
410405
}
@@ -458,17 +453,39 @@ export function useForm<TValues extends Record<string, any> = Record<string, any
458453
const isGroup = !!fieldInstance && isFieldGroup(fieldInstance);
459454
removeFieldFromPath(field, fieldName);
460455

456+
// clears a field error on unmounted
457+
// we wait till next tick to make sure if the field is completely removed and doesn't have any siblings like checkboxes
461458
nextTick(() => {
462-
// clears a field error on unmounted
463-
// we wait till next tick to make sure if the field is completely removed and doesn't have any siblings like checkboxes
459+
const shouldKeepValue = unref(field.keepValueOnUnmount) ?? unref(keepValuesOnUnmount);
460+
const currentGroupValue = getFromPath(formValues, fieldName);
461+
// The boolean here is we check if the field still belongs to the same control group with that name
462+
// if another group claimed the name, we should avoid handling it since it is no longer the same group
463+
// this happens with `v-for` over some checkboxes and field arrays.
464+
// also if the group no longer exist we can assume this group was the last one that controlled it
465+
const isSameGroup =
466+
isGroup && (fieldInstance === fieldsByPath.value[fieldName] || !fieldsByPath.value[fieldName]);
467+
468+
// group field that still has a dangling value, the field may exist or not after it was removed.
469+
// This used to be handled in the useField composable but the form has better context on when it should/not happen.
470+
// if it does belong to it that means the group still exists
471+
// #3844
472+
if (isSameGroup && Array.isArray(currentGroupValue) && !shouldKeepValue) {
473+
const valueIdx = currentGroupValue.findIndex(i => isEqual(i, unref(field.checkedValue)));
474+
if (valueIdx > -1) {
475+
const newVal = [...currentGroupValue];
476+
newVal.splice(valueIdx, 1);
477+
setFieldValue(fieldName, newVal as any, { force: true });
478+
}
479+
}
480+
481+
// Field was removed entirely, we should unset its path
464482
// #3384
465483
if (!fieldExists(fieldName)) {
466484
setFieldError(fieldName, undefined);
467485

468486
// Checks if the field was configured to be unset during unmount or not
469487
// Checks both the form-level config and field-level one
470488
// Field has the priority if it is set, otherwise it goes to the form settings
471-
const shouldKeepValue = unref(field.keepValueOnUnmount) ?? unref(keepValuesOnUnmount);
472489
if (shouldKeepValue) {
473490
return;
474491
}

0 commit comments

Comments
 (0)