Skip to content

Commit

Permalink
feat(Form): add support for nestedField prop on Form (#3568)
Browse files Browse the repository at this point in the history
* feat(Form): add support for `nestedField` prop on Form

* test: fix tests

* test: add tests for getFieldError and getFieldValue

* test(Form): add test for onSubmit

* fix: some of your tests did a full page reload!

* docs(Form): form accessibility

* fix: some of your tests did a full page reload!
  • Loading branch information
simonguo committed Jan 19, 2024
1 parent f874edf commit 47fce55
Show file tree
Hide file tree
Showing 16 changed files with 458 additions and 225 deletions.
70 changes: 33 additions & 37 deletions docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"react-device-detect": "^2.2.2",
"react-dom": "^17.0.2",
"react-icons": "^4.2.0",
"react-json-tree": "^0.17.0",
"react-json-tree": "^0.18.0",
"react-select": "^5.5.9",
"rsuite": "^5.50.0",
"svg-sprite-loader": "^6.0.11",
Expand Down
4 changes: 4 additions & 0 deletions docs/pages/components/form-validation/en-US/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ There are `checkTrigger` properties on the `<Form>` and `<Form.Control>` compone

<!--{include:`dynamic-form.md`}-->

### Nested fields

<!--{include:`form-nested-fields.md`}-->

## Props & Methods

- [Form props](/components/form)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const model = Schema.Model({
const TextField = React.forwardRef((props, ref) => {
const { name, label, accepter, ...rest } = props;
return (
<Form.Group controlId={`${name}-4`} ref={ref}>
<Form.Group ref={ref}>
<Form.ControlLabel>{label} </Form.ControlLabel>
<Form.Control name={name} accepter={accepter} {...rest} />
</Form.Group>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<!--start-code-->

```js
import { Form, Button, ButtonToolbar, Schema, Panel, FlexboxGrid } from 'rsuite';
import JSONTree from 'react-json-tree';

const JSONView = ({ formValue, formError }) => (
<div style={{ marginBottom: 10 }}>
<Panel className="json-tree-wrapper" header={<p>formValue</p>}>
<JSONTree data={formValue} />
</Panel>

<Panel className="json-tree-wrapper" header={<p>formError</p>}>
<JSONTree data={formError} />
</Panel>
</div>
);

const { StringType, ObjectType, NumberType } = Schema.Types;

const model = Schema.Model({
name: StringType().isRequired('This field is required.'),
address: ObjectType().shape({
city: StringType().isRequired('This field is required.'),
postCode: NumberType('Post Code must be a number').isRequired('This field is required.')
})
});

const TextField = React.forwardRef((props, ref) => {
const { name, label, accepter, ...rest } = props;
return (
<Form.Group ref={ref}>
<Form.ControlLabel>{label} </Form.ControlLabel>
<Form.Control name={name} accepter={accepter} {...rest} />
</Form.Group>
);
});

const App = () => {
const form = React.useRef();
const [formError, setFormError] = React.useState({});
const [formValue, setFormValue] = React.useState({
name: 'Tom',
address: { city: 'ShangHai', postCode: '200000' }
});

const handleSubmit = () => {
if (!form.current.check()) {
console.error('Form Error');
return;
}
console.log(formValue, 'Form Value');
};

return (
<FlexboxGrid>
<FlexboxGrid.Item colspan={12}>
<Form
nestedField
ref={form}
onChange={setFormValue}
onCheck={setFormError}
formValue={formValue}
model={model}
>
<TextField name="name" label="Name" />
<TextField name="address.city" label="City" />
<TextField name="address.postCode" label="Post Code" />

<ButtonToolbar>
<Button appearance="primary" onClick={handleSubmit}>
Submit
</Button>
</ButtonToolbar>
</Form>
</FlexboxGrid.Item>
<FlexboxGrid.Item colspan={12}>
<JSONView formValue={formValue} formError={formError} />
</FlexboxGrid.Item>
</FlexboxGrid>
);
};

ReactDOM.render(<App />, document.getElementById('root'));
```

<!--end-code-->
4 changes: 4 additions & 0 deletions docs/pages/components/form-validation/zh-CN/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ return (

<!--{include:`dynamic-form.md`}-->

### 表单数据嵌套

<!--{include:`form-nested-fields.md`}-->

## Props & Methods

- [Form props](/zh/components/form)
Expand Down
11 changes: 10 additions & 1 deletion docs/pages/components/form/en-US/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ Error message can be set in 2 ways:

## Accessibility

### ARIA properties

- You should set the `aria-label` or `aria-labelledby` property for each form so that the screen reader can read the purpose of the form correctly.

- Through the `controlId` prop of `<Form.Group>`, you can set `id` on `<Form.Control>` and set `htmlFor` on `<Form.ControlLabel>`. In addition, `aria-labelledby` and `aria-describeby` will be generated for `<Form.Control>`, corresponding to the `id` of `<Form.ControlLabel>` and `<Form.HelpText>`.

```html
Expand Down Expand Up @@ -93,12 +97,16 @@ HTML:
</div>
```

### Required JavaScript features

- Click the button of `type='submit'` in the Form, and the submit event of the form will be triggered automatically.

## Props

### `<Form>`

<!-- prettier-sort-markdown-table -->

| Property | Type `(default)` | Description |
| ---------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| checkTrigger | 'change' &#124; 'blur' &#124; 'none' `('change')` | Trigger the type of form validation |
Expand All @@ -111,13 +119,14 @@ HTML:
| formValue | object | Value of form (Controlled) |
| layout | 'horizontal' &#124; 'vertical' &#124; 'inline' `('vertical')` | Set the left and right columns of the layout of the elements within the form |
| model | Schema | SchemaModel object |
| nestedField | boolean `(false)` | Whether to support nested fields |
| onChange | (formValue: object, event) => void | Callback fired when data changing |
| onCheck | (formError: object) => void | Callback fired when data cheking |
| onError | (formError: object) => void | Callback fired when error checking |
| plaintext | boolean `(false)` | Render the form as plain text |
| readOnly | boolean `(false)` | Make the form readonly |

### Form methods
### Form ref

- check

Expand Down
1 change: 0 additions & 1 deletion docs/pages/components/form/fragments/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ const App = () => {

return (
<Panel>
dsdfsdf
<Form
disabled={disabled}
readOnly={readOnly}
Expand Down
12 changes: 10 additions & 2 deletions docs/pages/components/form/zh-CN/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@

<!--{include:`status.md`}-->

## 无障碍设计
## 可访问性

### ARIA 属性

- 您应该为每个表单设置 `aria-label``aria-labelledby` 属性,以便屏幕阅读器可以正确地读取表单的目的。
- 通过 `<Form.Group>``controlId` 属性,可以在 `<Form.Control>` 上设置 `id` 同时在 `<Form.ControlLabel>` 上设置 `htmlFor`。另外会为 `<Form.Control>` 生成`aria-labelledby``aria- describeby`, 对应到 `<Form.ControlLabel>``<Form.HelpText>``id`

```html
Expand Down Expand Up @@ -93,12 +96,16 @@
</div>
```

### 必需的 JavaScript 功能

- 在 Form 内点击 `type='submit'` 的按钮,会自动触发表单的 submit 事件。

## Props

### `<Form>`

<!-- prettier-sort-markdown-table -->

| 名称 | 类型 `(默认值)` | 描述 |
| ---------------- | ------------------------------------------------------------- | -------------------------------------------------- |
| checkTrigger | 'change' &#124; 'blur' &#124; 'none' `('change')` | 触发表单校验的类型 |
Expand All @@ -111,13 +118,14 @@
| formValue | object | 表单的值 `受控组件` |
| layout | 'horizontal' &#124; 'vertical' &#124; 'inline' `('vertical')` | 设置表单内的元素左右两栏布局 |
| model | Schema | SchemaModel 对象 |
| nestedField | boolean `(false)` | 是否支持表单数据嵌套 |
| onChange | (formValue: object, event) => void | 数据改变后的回调函数 |
| onCheck | (formError: object) => void | 数据校验的回调函数 |
| onError | (formError: object) => void | 校验出错的回调函数 |
| plaintext | boolean `(false)` | 表单显示为纯文本 |
| readOnly | boolean `(false)` | 只读表单 |

### Form methods
### Form ref

- check 检验表单数据

Expand Down

1 comment on commit 47fce55

@vercel
Copy link

@vercel vercel bot commented on 47fce55 Jan 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

rsuite-nextjs – ./docs

rsuite.vercel.app
rsuite-nextjs-git-main-rsuite.vercel.app
rsuite-nextjs-rsuite.vercel.app
rsuitejs.com

Please sign in to comment.