Skip to content

Commit f10f43e

Browse files
feat(form-core): add array method field.clearValues and form.clearFieldValues (#1404)
* feat(form-core): add array method `field.clearValues` and `form.clearFieldValues` Co-authored-by: LeCarbonator <[email protected]> * test(form-core): add test for more coverage * chore: use DeepKeysOfType for clearFieldValues --------- Co-authored-by: LeCarbonator <[email protected]>
1 parent 9011802 commit f10f43e

File tree

4 files changed

+79
-0
lines changed

4 files changed

+79
-0
lines changed

packages/form-core/src/FieldApi.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,15 @@ export class FieldApi<
13131313
this.triggerOnChangeListener()
13141314
}
13151315

1316+
/**
1317+
* Clear all values from the array.
1318+
*/
1319+
clearValues = (opts?: UpdateMetaOptions) => {
1320+
this.form.clearFieldValues(this.name, opts)
1321+
1322+
this.triggerOnChangeListener()
1323+
}
1324+
13161325
/**
13171326
* @private
13181327
*/

packages/form-core/src/FormApi.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2125,6 +2125,32 @@ export class FormApi<
21252125
this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')
21262126
}
21272127

2128+
/**
2129+
* Clear all values within an array field.
2130+
*/
2131+
clearFieldValues = <TField extends DeepKeysOfType<TFormData, any[]>>(
2132+
field: TField,
2133+
opts?: UpdateMetaOptions,
2134+
) => {
2135+
const fieldValue = this.getFieldValue(field)
2136+
2137+
const lastIndex = Array.isArray(fieldValue)
2138+
? Math.max((fieldValue as unknown[]).length - 1, 0)
2139+
: null
2140+
2141+
this.setFieldValue(field, [] as any, opts)
2142+
2143+
if (lastIndex !== null) {
2144+
for (let i = 0; i <= lastIndex; i++) {
2145+
const fieldKey = `${field}[${i}]`
2146+
this.deleteField(fieldKey as never)
2147+
}
2148+
}
2149+
2150+
// validate array change
2151+
this.validateField(field, 'change')
2152+
}
2153+
21282154
/**
21292155
* Resets the field value and meta to default state
21302156
*/

packages/form-core/tests/FieldApi.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,28 @@ describe('field api', () => {
13461346

13471347
field.moveValue(0, 1)
13481348
expect(arr).toStrictEqual(['middle', 'end', 'start'])
1349+
1350+
field.clearValues()
1351+
expect(arr).toStrictEqual([])
1352+
})
1353+
1354+
it('should not break when clearValues is called on a non-array field', () => {
1355+
const form = new FormApi({
1356+
defaultValues: {
1357+
name: 'foo',
1358+
},
1359+
})
1360+
1361+
form.mount()
1362+
1363+
const field = new FieldApi({
1364+
form,
1365+
name: 'name',
1366+
})
1367+
1368+
field.mount()
1369+
1370+
expect(() => field.clearValues()).not.toThrow()
13491371
})
13501372

13511373
it('should reset the form on a listener', () => {

packages/form-core/tests/FormApi.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3267,6 +3267,28 @@ describe('form api', () => {
32673267
form.parseValuesWithSchemaAsync(z.any())
32683268
}).not.toThrowError()
32693269
})
3270+
3271+
it('should delete fields when resetting an array field to an empty array', () => {
3272+
const employees = [
3273+
{
3274+
firstName: 'Darcy',
3275+
},
3276+
]
3277+
3278+
const form = new FormApi({
3279+
defaultValues: {
3280+
employees,
3281+
},
3282+
})
3283+
form.mount()
3284+
3285+
form.clearFieldValues('employees')
3286+
3287+
expect(form.getFieldValue('employees')).toEqual([])
3288+
expect(form.getFieldValue(`employees[0]`)).toBeUndefined()
3289+
expect(form.getFieldMeta(`employees[0]`)).toBeUndefined()
3290+
expect(form.state.values.employees).toStrictEqual([])
3291+
})
32703292
})
32713293

32723294
it('should reset the errorSourceMap for the field when the form is reset', () => {

0 commit comments

Comments
 (0)