@modular-forms/react
Version:
The modular and type-safe form library for React
55 lines (54 loc) • 2.87 kB
JavaScript
import { batch } from '@preact/signals-react';
import { getFieldArrayNames, getFieldArrayState, getFieldArrayStore, getFieldNames, getFieldState, getPathIndex, setFieldArrayState, setFieldState, sortArrayPathIndex, updateFieldArrayDirty, validateIfRequired, } from '../utils';
/**
* Removes a item of the field array.
*
* @param form The form of the field array.
* @param name The name of field array.
* @param options The remove options.
*/
export function remove(form, name, { at: index }) {
// Get store of specified field array
const fieldArray = getFieldArrayStore(form, name);
// Continue if specified field array exists
if (fieldArray) {
// Get last index of field array
const lastIndex = fieldArray.items.peek().length - 1;
// Continue if specified index is valid
if (index >= 0 && index <= lastIndex) {
// Create function to filter a name
const filterName = (value) => value.startsWith(`${name}.`) && getPathIndex(name, value) > index;
// Create function to get previous index name
const getPrevIndexName = (fieldOrFieldArrayName, fieldOrFieldArrayIndex) => fieldOrFieldArrayName.replace(`${name}.${fieldOrFieldArrayIndex}`, `${name}.${fieldOrFieldArrayIndex - 1}`);
batch(() => {
// Move state of each field after the removed index back by one index
getFieldNames(form)
.filter(filterName)
.sort(sortArrayPathIndex(name))
.forEach((fieldName) => {
setFieldState(form, getPrevIndexName(fieldName, getPathIndex(name, fieldName)), getFieldState(form, fieldName));
});
// Move state of each field array after the removed index back by one index
getFieldArrayNames(form)
.filter(filterName)
.sort(sortArrayPathIndex(name))
.forEach((fieldArrayName) => {
setFieldArrayState(form, getPrevIndexName(fieldArrayName, getPathIndex(name, fieldArrayName)), getFieldArrayState(form, fieldArrayName));
});
// Delete item from field array
const nextItems = [...fieldArray.items.peek()];
nextItems.splice(index, 1);
fieldArray.items.value = nextItems;
// Set touched at field array and form to true
fieldArray.touched.value = true;
form.touched.value = true;
// Update dirty state at field array and form
updateFieldArrayDirty(form, fieldArray);
// Validate field array if necessary
validateIfRequired(form, fieldArray, name, {
on: ['touched', 'change'],
});
});
}
}
}