Skip to content

Commit

Permalink
Merge pull request #11 from gutentag2012/fix/form-update-options
Browse files Browse the repository at this point in the history
Fix/form update options
  • Loading branch information
gutentag2012 authored Apr 7, 2024
2 parents e3a8d67 + d75870e commit 1ba34f0
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 6 deletions.
2 changes: 1 addition & 1 deletion docs/reference/react/useForm.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ declare function useForm<
TData,
TAdapter extends ValidatorAdapter | undefined = undefined,
>(
options: FormLogicOptions<TData, TAdapter>,
options?: FormLogicOptions<TData, TAdapter>,
): FormContextType<TData, TAdapter>;
```

Expand Down
73 changes: 72 additions & 1 deletion packages/form-core/src/FormLogic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ const adapter: ValidatorAdapter = {
describe('FormLogic', () => {
it('should have the correct initial state', () => {
const form = new FormLogic()

expect(form.isMounted.value).toBeFalsy()
form.mount()
expect(form.isMounted.value).toBeTruthy()

expect(form.fields.peek().length).toBe(0)
expect(form.fields.value.length).toBe(0)

expect(form.data.value).toStrictEqual({})
expect(form.json.value).toStrictEqual({})
Expand Down Expand Up @@ -470,6 +473,42 @@ describe('FormLogic', () => {
form.updateOptions({ defaultValues: { name: 'another' } })
expect(form.data.value.name.value).toBe('another')
})
it('should be able to remove fields of dynamic objects or items from an array when updating the options', () => {
const form = new FormLogic<{
obj: { [key: string]: string }
array: number[]
}>({
defaultValues: {
obj: {
stay: 'stay',
go: 'go',
},
array: [1, 2, 3],
},
})
form.mount()

expect(form.json.value).toEqual({
obj: {
stay: 'stay',
go: 'go',
},
array: [1, 2, 3],
})
form.updateOptions({
defaultValues: {
obj: { stay: 'stay(changed)', new: 'new' },
array: [2],
},
})
expect(form.json.value).toEqual({
obj: {
stay: 'stay(changed)',
new: 'new',
},
array: [2],
})
})

it('should update the data when using the handleChange method', () => {
const form = new FormLogic<{ name: string }>()
Expand Down Expand Up @@ -1804,6 +1843,22 @@ describe('FormLogic', () => {
expect(form.data.value.deep.value.new.value).toBe(2)
expect(fn).toHaveBeenCalledTimes(1)
})
it('should touch a field when adding a new key to an object if configured', () => {
const form = new FormLogic<{ deep: { [key: string]: number } }>({
defaultValues: {
deep: {
value: 1,
},
},
})
form.mount()
const field = new FieldLogic(form, 'deep')
field.mount()

expect(field.isTouched.value).toBe(false)
form.setValueInObject('deep', 'new', 2, { shouldTouch: true })
expect(field.isTouched.value).toBe(true)
})
it('should update a value in an object that already has the key', () => {
const form = new FormLogic<{ deep: { [key: string]: number } }>({
defaultValues: {
Expand Down Expand Up @@ -1881,6 +1936,22 @@ describe('FormLogic', () => {
expect(form.data.value.deep.value.value).toBeUndefined()
expect(fn).toHaveBeenCalledTimes(1)
})
it('should touch a field when removing a key from an object if configured', () => {
const form = new FormLogic<{ deep: { value?: number } }>({
defaultValues: {
deep: {
value: 1,
},
},
})
form.mount()
const field = new FieldLogic(form, 'deep')
field.mount()

expect(field.isTouched.value).toBe(false)
form.removeValueInObject('deep', 'value', { shouldTouch: true })
expect(field.isTouched.value).toBe(true)
})
it('should do nothing when trying to remove a key to a value that is not an object or a date', () => {
const form = new FormLogic({
defaultValues: {
Expand Down
5 changes: 2 additions & 3 deletions packages/form-core/src/FormLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
isEqualDeep,
makeArrayEntry,
removeSignalValueAtPath,
removeValueAtPath,
setSignalValueAtPath,
setSignalValuesFromObject,
setValueAtPath,
Expand Down Expand Up @@ -394,9 +393,9 @@ export class FormLogic<
// We do not want to update dirty field values, since we do not want to reset the form, but just override the default values
const newDefaultValues = { ...options.defaultValues }
for (const dirtyField of dirtyFields) {
removeValueAtPath(newDefaultValues, dirtyField as never)
setValueAtPath(newDefaultValues, dirtyField as never, undefined)
}
setSignalValuesFromObject(this._data, newDefaultValues, true)
setSignalValuesFromObject(this._data, newDefaultValues)
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/form-react/src/form/form.hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function useForm<
TData,
TAdapter extends ValidatorAdapter | undefined = undefined,
>(
options: FormLogicOptions<TData, TAdapter>,
options?: FormLogicOptions<TData, TAdapter>,
): FormContextType<TData, TAdapter> {
// biome-ignore lint/correctness/useExhaustiveDependencies: We only ever want to create a form once
const finalForm = React.useMemo(() => {
Expand Down

0 comments on commit 1ba34f0

Please sign in to comment.