-
-
Notifications
You must be signed in to change notification settings - Fork 629
feat(form-core): Add options to reset/replace/delete all fields [FieldGroupApi] #1962
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@tanstack/form-core': patch | ||
| --- | ||
|
|
||
| Added options to reset/replace/delete fields for FieldGroup |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,6 +110,14 @@ export interface FieldGroupOptions< | |
| onSubmitMeta?: TSubmitMeta | ||
| } | ||
|
|
||
| function isFieldInStringGroup(fieldName: string, groupPath: string) { | ||
| return ( | ||
| fieldName !== groupPath && | ||
| fieldName.startsWith(groupPath) && | ||
| (fieldName[groupPath.length] === '.' || fieldName[groupPath.length] === '[') | ||
| ) | ||
| } | ||
|
|
||
| export class FieldGroupApi< | ||
| in out TFormData, | ||
| in out TFieldGroupData, | ||
|
|
@@ -395,6 +403,36 @@ export class FieldGroupApi< | |
| return this.form.deleteField(this.getFormFieldName(field)) | ||
| } | ||
|
|
||
| /** | ||
| * Delete all fields that belong to this field group. | ||
| */ | ||
| deleteAllFields = () => { | ||
| if (typeof this.fieldsMap === 'string') { | ||
| const groupPath = this.fieldsMap.toString() | ||
| const currentValue = this.form.getFieldValue(groupPath) | ||
|
|
||
| const fieldsToDelete = Object.keys(this.form.fieldInfo).filter( | ||
| (fieldName) => isFieldInStringGroup(fieldName, groupPath), | ||
| ) | ||
|
|
||
| fieldsToDelete.forEach((field) => { | ||
| this.form.deleteField(field) | ||
| }) | ||
|
|
||
| const emptyValue = Array.isArray(currentValue) ? [] : {} | ||
| this.form.setFieldValue(groupPath, emptyValue as never, { | ||
| dontUpdateMeta: true, | ||
| }) | ||
|
|
||
| return | ||
| } | ||
|
|
||
| const fieldsMap = this.fieldsMap as FieldsMap<TFormData, TFieldGroupData> | ||
| for (const key in fieldsMap) { | ||
| this.deleteField(key) | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Pushes a value into an array field. | ||
| */ | ||
|
|
@@ -457,6 +495,20 @@ export class FieldGroupApi< | |
| ) | ||
| } | ||
|
|
||
| /** | ||
| * Replaces all field values in this field group with the provided values. | ||
| */ | ||
| replaceAllFields = (fields: TFieldGroupData) => { | ||
| for (const fieldName of Object.keys( | ||
| fields as object, | ||
| ) as (keyof TFieldGroupData)[]) { | ||
| this.setFieldValue( | ||
| fieldName as unknown as DeepKeys<TFieldGroupData>, | ||
| fields[fieldName] as never, | ||
| ) | ||
| } | ||
| } | ||
|
Comment on lines
+501
to
+510
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Because each provided key is written via At minimum, please clarify the intended semantics in the JSDoc (partial overwrite vs. full replace) so callers don't get surprised. If full replace is intended, switch the string-group path to a single 🤖 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one sounds like a miss. At least I can't make much sense of it. Focus on the other errors for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| /** | ||
| * Removes a value from an array field at the specified index. | ||
| */ | ||
|
|
@@ -512,12 +564,41 @@ export class FieldGroupApi< | |
| } | ||
|
|
||
| /** | ||
| * Resets the field value and meta to default state | ||
| * Resets the field value and meta to default state. | ||
| */ | ||
| resetField = <TField extends DeepKeys<TFieldGroupData>>(field: TField) => { | ||
| return this.form.resetField(this.getFormFieldName(field)) | ||
| } | ||
|
|
||
| /** | ||
| * Resets all field values and meta within this field group. | ||
| */ | ||
| resetAllFields = () => { | ||
| if (typeof this.fieldsMap === 'string') { | ||
| const groupPath = this.fieldsMap.toString() | ||
|
|
||
| const fieldsToReset = Object.keys(this.form.fieldInfo).filter( | ||
| (fieldName) => isFieldInStringGroup(fieldName, groupPath), | ||
| ) | ||
|
|
||
| fieldsToReset.forEach((field) => this.form.resetField(field)) | ||
|
|
||
| if (this.form.options.defaultValues !== undefined) { | ||
| const resetValue = getBy(this.form.options.defaultValues, groupPath) | ||
| this.form.setFieldValue(groupPath, resetValue as never, { | ||
| dontUpdateMeta: true, | ||
| }) | ||
| } | ||
| return | ||
| } | ||
|
|
||
| const fieldsMap = this.fieldsMap as FieldsMap<TFormData, TFieldGroupData> | ||
|
|
||
| for (const key in fieldsMap) { | ||
| this.resetField(key) | ||
| } | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| validateAllFields = (cause: ValidationCause) => | ||
| this.form.validateAllFields(cause) | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.