Skip to content
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

feat(form): resetFields 增加 namepath 参数,用于重置指定的字段 #2953

Merged
merged 4 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions src/packages/form/__tests__/form.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,59 @@ test('no-style and render function', async () => {
})
})

test('reset usename filed', async () => {
const Demo1 = () => {
const [form] = Form.useForm()
return (
<>
<Form
form={form}
labelPosition="right"
footer={
<>
<div
id="reset"
onClick={() => {
form.resetFields(['username'])
}}
>
Reset
</div>
</>
}
>
<Form.Item
align="center"
required
label="字段A"
name="username"
rules={[{ max: 5, message: '字段A不能超过5个字' }]}
>
<Input placeholder="请输入字段A" type="text" />
</Form.Item>
</Form>
</>
)
}
const { container } = render(<Demo1 />)
const input = container.querySelector('input')
const reset = container.querySelector('#reset')
if (input) {
fireEvent.change(input, { target: { value: 'NutUI React Taro' } })
await waitFor(() => {
expect(
container.querySelector('.nut-form-item-body-tips')
).toHaveTextContent('字段A不能超过5个字')
})
}
if (reset) {
fireEvent.click(reset)
await waitFor(() => {
expect(container.querySelector('.nut-form-item-body-tips')).toBeNull()
})
}
})

test('useWatch', async () => {
const Demo = () => {
const [form] = Form.useForm()
Expand Down
2 changes: 1 addition & 1 deletion src/packages/form/doc.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ The rule validation process is based on [async-validator](https://github.com/yim
| getFieldsValue | Get values by a set of field names. Return according to the corresponding structure. Default return mounted field value, but you can use getFieldsValue(true) to get all values | `(name: NamePath \| boolean) => any` |
| setFieldsValue | Set the value of the form (the value will be passed directly to the form store. If you do not want the object passed in to be modified, please copy it and pass it in) | `(values) => void` |
| setFieldValue | Set the value of the corresponding field name | `<T>(name: NamePath, value: T) => void` |
| resetFields | Reset form prompt state | `() => void` |
| resetFields | Reset form prompt state | `(namePaths?: NamePath[]) => void` |
| submit | method to submit a form for validation | `Promise` |

`Form.useWatch()`, this method will watch specified inputs and return their values. It is useful to render input value and for determining what to render by condition.
Expand Down
2 changes: 1 addition & 1 deletion src/packages/form/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ import { Form } from '@nutui/nutui-react'
| getFieldsValue | 获取一组字段名对应的值,会按照对应结构返回。默认返回现存字段值,当调用 getFieldsValue(true) 时返回所有值 | `(name: NamePath \| boolean) => any` |
| setFieldsValue | 设置表单的值(该值将直接传入 form store 中。如果你不希望传入对象被修改,请克隆后传入) | `(values) => void` |
| setFieldValue | 设置对应字段名的值 | `<T>(name: NamePath, value: T) => void` |
| resetFields | 重置表单提示状态 | `() => void` |
| resetFields | 重置表单提示状态 | `(namePaths?: NamePath[]) => void` |
| submit | 提交表单进行校验的方法 | `Promise` |

`Form.useWatch()`此方法将监视指定的输入并返回其值。它对于呈现输入值和确定根据条件呈现的内容很有用。
Expand Down
2 changes: 1 addition & 1 deletion src/packages/form/doc.taro.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ import { Form } from '@nutui/nutui-react-taro'
| getFieldsValue | 获取一组字段名对应的值,会按照对应结构返回。默认返回现存字段值,当调用 getFieldsValue(true) 时返回所有值 | `(name: NamePath \| boolean) => any` |
| setFieldsValue | 设置表单的值(该值将直接传入 form store 中。如果你不希望传入对象被修改,请克隆后传入) | `(values) => void` |
| setFieldValue | 设置对应字段名的值 | `<T>(name: NamePath, value: T) => void` |
| resetFields | 重置表单提示状态 | `() => void` |
| resetFields | 重置表单提示状态 | `(namePaths?: NamePath[]) => void` |
| submit | 提交表单进行校验的方法 | `Promise` |

`Form.useWatch()`此方法将监视指定的输入并返回其值。它对于呈现输入值和确定根据条件呈现的内容很有用。
Expand Down
2 changes: 1 addition & 1 deletion src/packages/form/doc.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ import { Form } from '@nutui/nutui-react'
| getFieldsValue | 获取一组字段名对应的值,会按照对应结构返回。默认返回现存字段值,当调用 getFieldsValue(true) 时返回所有值 | `(name: NamePath \| boolean) => any` |
| setFieldsValue | 設定表單的值(該值將直接傳入 form store 中。如果你不希望傳入物件被修改,請複製後傳入) | `(values) => void` |
| setFieldValue | 設定對應欄位名的值 | `<T>(name: NamePath, value: T) => void` |
| resetFields | 重置錶單提示狀態 | `() => void` |
| resetFields | 重置錶單提示狀態 | `(namePaths?: NamePath[]) => void` |
| submit | 提交錶單進行校驗的方法 | `Promise` |

`Form.useWatch()`此方法將監視指定的輸入並傳回其值。它對於呈現輸入值和確定根據條件呈現的內容很有用。
Expand Down
32 changes: 24 additions & 8 deletions src/packages/form/useform.taro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class FormStore {

validateFields = async (nameList?: NamePath[]) => {
let filterEntities = []
this.errors.length = 0
// this.errors.length = 0
if (!nameList || nameList.length === 0) {
filterEntities = this.fieldEntities
} else {
Expand All @@ -202,13 +202,29 @@ class FormStore {
}
}

resetFields = () => {
this.errors.length = 0
const nextStore = merge({}, this.initialValues)
this.updateStore(nextStore)
this.fieldEntities.forEach((entity: FormFieldEntity) => {
entity.onStoreChange('reset')
})
resetFields = (namePaths?: NamePath[]) => {
if (namePaths && namePaths.length) {
namePaths.forEach((path) => {
this.errors[path] = null
this.fieldEntities.forEach((entity: FormFieldEntity) => {
const name = entity.props.name
if (name === path) {
if (path in this.initialValues) {
this.updateStore({ [path]: this.initialValues[path] })
} else {
delete this.store[path]
}
entity.onStoreChange('reset')
}
})
})
} else {
const nextStore = merge({}, this.initialValues)
this.updateStore(nextStore)
this.fieldEntities.forEach((entity: FormFieldEntity) => {
entity.onStoreChange('reset')
})
}
}

// 监听事件
Expand Down
32 changes: 24 additions & 8 deletions src/packages/form/useform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@

validateFields = async (nameList?: NamePath[]) => {
let filterEntities = []
this.errors.length = 0
// this.errors.length = 0
if (!nameList || nameList.length === 0) {
filterEntities = this.fieldEntities
} else {
Expand All @@ -202,13 +202,29 @@
}
}

resetFields = () => {
this.errors.length = 0
const nextStore = merge({}, this.initialValues)
this.updateStore(nextStore)
this.fieldEntities.forEach((entity: FormFieldEntity) => {
entity.onStoreChange('reset')
})
resetFields = (namePaths?: NamePath[]) => {
if (namePaths && namePaths.length) {
namePaths.forEach((path) => {
this.errors[path] = null
this.fieldEntities.forEach((entity: FormFieldEntity) => {
const name = entity.props.name
if (name === path) {
if (path in this.initialValues) {
this.updateStore({ [path]: this.initialValues[path] })

Check warning on line 213 in src/packages/form/useform.ts

View check run for this annotation

Codecov / codecov/patch

src/packages/form/useform.ts#L213

Added line #L213 was not covered by tests
} else {
delete this.store[path]
}
entity.onStoreChange('reset')
}
})
})
} else {
const nextStore = merge({}, this.initialValues)
this.updateStore(nextStore)
this.fieldEntities.forEach((entity: FormFieldEntity) => {
entity.onStoreChange('reset')
})
}
}

// 监听事件
Expand Down
Loading