Skip to content

Commit

Permalink
fix: avoid toggling field array checkboxes values closes #3844
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Jul 16, 2022
1 parent 7437612 commit fffad4b
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 16 deletions.
8 changes: 0 additions & 8 deletions packages/vee-validate/src/useField.ts
Expand Up @@ -453,14 +453,6 @@ function useCheckboxField<TValue = unknown>(
handleChange(newValue, shouldValidate);
}

onBeforeUnmount(() => {
const shouldKeepValue = unref(field.keepValueOnUnmount) ?? unref(form?.keepValuesOnUnmount) ?? false;
// toggles the checkbox value if it was checked and the unset behavior is set
if (checked.value && !shouldKeepValue) {
handleCheckboxChange(unref(checkedValue), false);
}
});

return {
...field,
checked,
Expand Down
33 changes: 25 additions & 8 deletions packages/vee-validate/src/useForm.ts
Expand Up @@ -400,11 +400,6 @@ export function useForm<TValues extends Record<string, any> = Record<string, any

fieldAtPath.splice(idx, 1);

if (fieldAtPath.length === 1) {
fieldsByPath.value[fieldPath] = fieldAtPath[0];
return;
}

if (!fieldAtPath.length) {
delete fieldsByPath.value[fieldPath];
}
Expand Down Expand Up @@ -458,17 +453,39 @@ export function useForm<TValues extends Record<string, any> = Record<string, any
const isGroup = !!fieldInstance && isFieldGroup(fieldInstance);
removeFieldFromPath(field, fieldName);

// clears a field error on unmounted
// we wait till next tick to make sure if the field is completely removed and doesn't have any siblings like checkboxes
nextTick(() => {
// clears a field error on unmounted
// we wait till next tick to make sure if the field is completely removed and doesn't have any siblings like checkboxes
const shouldKeepValue = unref(field.keepValueOnUnmount) ?? unref(keepValuesOnUnmount);
const currentGroupValue = getFromPath(formValues, fieldName);
// The boolean here is we check if the field still belongs to the same control group with that name
// if another group claimed the name, we should avoid handling it since it is no longer the same group
// this happens with `v-for` over some checkboxes and field arrays.
// also if the group no longer exist we can assume this group was the last one that controlled it
const isSameGroup =
isGroup && (fieldInstance === fieldsByPath.value[fieldName] || !fieldsByPath.value[fieldName]);

// group field that still has a dangling value, the field may exist or not after it was removed.
// This used to be handled in the useField composable but the form has better context on when it should/not happen.
// if it does belong to it that means the group still exists
// #3844
if (isSameGroup && Array.isArray(currentGroupValue) && !shouldKeepValue) {
const valueIdx = currentGroupValue.findIndex(i => isEqual(i, unref(field.checkedValue)));
if (valueIdx > -1) {
const newVal = [...currentGroupValue];
newVal.splice(valueIdx, 1);
setFieldValue(fieldName, newVal as any, { force: true });
}
}

// Field was removed entirely, we should unset its path
// #3384
if (!fieldExists(fieldName)) {
setFieldError(fieldName, undefined);

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

0 comments on commit fffad4b

Please sign in to comment.