2016-04-12 17:02:17 +08:00
|
|
|
---
|
2016-10-31 15:42:57 +08:00
|
|
|
order: 5
|
2016-09-01 11:48:38 +08:00
|
|
|
title:
|
2016-07-31 09:53:51 +08:00
|
|
|
zh-CN: 动态增减表单项
|
2016-10-31 15:42:57 +08:00
|
|
|
en-US: Dynamic Form Item
|
2016-04-12 17:02:17 +08:00
|
|
|
---
|
|
|
|
|
2016-07-31 09:53:51 +08:00
|
|
|
## zh-CN
|
|
|
|
|
2016-04-12 17:02:17 +08:00
|
|
|
动态增加、减少表单项。
|
|
|
|
|
2016-07-31 09:53:51 +08:00
|
|
|
## en-US
|
|
|
|
|
2016-07-31 10:01:58 +08:00
|
|
|
Add or remove form items dynamically.
|
2016-07-31 09:53:51 +08:00
|
|
|
|
2017-02-13 10:55:53 +08:00
|
|
|
````jsx
|
2018-11-28 15:00:03 +08:00
|
|
|
import {
|
|
|
|
Form, Input, Icon, Button,
|
|
|
|
} from 'antd';
|
2018-06-27 15:55:04 +08:00
|
|
|
|
2018-11-23 11:25:28 +08:00
|
|
|
let id = 0;
|
|
|
|
|
2016-11-10 16:11:22 +08:00
|
|
|
class DynamicFieldSet extends React.Component {
|
|
|
|
remove = (k) => {
|
2016-04-12 17:02:17 +08:00
|
|
|
const { form } = this.props;
|
|
|
|
// can use data-binding to get
|
2016-10-31 15:42:57 +08:00
|
|
|
const keys = form.getFieldValue('keys');
|
2016-11-10 16:11:22 +08:00
|
|
|
// We need at least one passenger
|
|
|
|
if (keys.length === 1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-12 17:02:17 +08:00
|
|
|
// can use data-binding to set
|
|
|
|
form.setFieldsValue({
|
2016-11-02 18:08:48 +08:00
|
|
|
keys: keys.filter(key => key !== k),
|
2016-04-12 17:02:17 +08:00
|
|
|
});
|
2016-11-10 16:11:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
add = () => {
|
2016-04-12 17:02:17 +08:00
|
|
|
const { form } = this.props;
|
|
|
|
// can use data-binding to get
|
2016-10-31 15:42:57 +08:00
|
|
|
const keys = form.getFieldValue('keys');
|
2019-01-29 11:50:43 +08:00
|
|
|
const nextKeys = keys.concat(id++);
|
2016-04-12 17:02:17 +08:00
|
|
|
// can use data-binding to set
|
|
|
|
// important! notify form to detect changes
|
|
|
|
form.setFieldsValue({
|
2016-10-31 15:42:57 +08:00
|
|
|
keys: nextKeys,
|
2016-04-12 17:02:17 +08:00
|
|
|
});
|
2016-11-10 16:11:22 +08:00
|
|
|
}
|
|
|
|
|
2016-12-31 23:47:07 +08:00
|
|
|
handleSubmit = (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
this.props.form.validateFields((err, values) => {
|
|
|
|
if (!err) {
|
2019-04-02 17:40:50 +08:00
|
|
|
const { keys, names } = values;
|
2016-12-31 23:47:07 +08:00
|
|
|
console.log('Received values of form: ', values);
|
2019-04-02 17:40:50 +08:00
|
|
|
console.log('Merged values:', keys.map(key => names[key]));
|
2016-12-31 23:47:07 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-04-12 17:02:17 +08:00
|
|
|
render() {
|
2016-09-01 11:48:38 +08:00
|
|
|
const { getFieldDecorator, getFieldValue } = this.props.form;
|
2016-04-12 17:02:17 +08:00
|
|
|
const formItemLayout = {
|
2017-03-15 11:25:58 +08:00
|
|
|
labelCol: {
|
|
|
|
xs: { span: 24 },
|
|
|
|
sm: { span: 4 },
|
|
|
|
},
|
|
|
|
wrapperCol: {
|
|
|
|
xs: { span: 24 },
|
|
|
|
sm: { span: 20 },
|
|
|
|
},
|
2016-11-10 16:11:22 +08:00
|
|
|
};
|
|
|
|
const formItemLayoutWithOutLabel = {
|
2017-03-15 11:25:58 +08:00
|
|
|
wrapperCol: {
|
|
|
|
xs: { span: 24, offset: 0 },
|
|
|
|
sm: { span: 20, offset: 4 },
|
|
|
|
},
|
2016-04-12 17:02:17 +08:00
|
|
|
};
|
2016-12-31 23:47:07 +08:00
|
|
|
getFieldDecorator('keys', { initialValue: [] });
|
2016-11-10 16:11:22 +08:00
|
|
|
const keys = getFieldValue('keys');
|
2018-11-28 15:00:03 +08:00
|
|
|
const formItems = keys.map((k, index) => (
|
2018-12-22 16:48:30 +08:00
|
|
|
<Form.Item
|
2018-11-28 15:00:03 +08:00
|
|
|
{...(index === 0 ? formItemLayout : formItemLayoutWithOutLabel)}
|
|
|
|
label={index === 0 ? 'Passengers' : ''}
|
|
|
|
required={false}
|
|
|
|
key={k}
|
|
|
|
>
|
|
|
|
{getFieldDecorator(`names[${k}]`, {
|
|
|
|
validateTrigger: ['onChange', 'onBlur'],
|
|
|
|
rules: [{
|
|
|
|
required: true,
|
|
|
|
whitespace: true,
|
|
|
|
message: "Please input passenger's name or delete this field.",
|
|
|
|
}],
|
|
|
|
})(
|
|
|
|
<Input placeholder="passenger name" style={{ width: '60%', marginRight: 8 }} />
|
|
|
|
)}
|
|
|
|
{keys.length > 1 ? (
|
|
|
|
<Icon
|
|
|
|
className="dynamic-delete-button"
|
|
|
|
type="minus-circle-o"
|
|
|
|
onClick={() => this.remove(k)}
|
|
|
|
/>
|
|
|
|
) : null}
|
2018-12-22 16:48:30 +08:00
|
|
|
</Form.Item>
|
2018-11-28 15:00:03 +08:00
|
|
|
));
|
2016-04-12 17:02:17 +08:00
|
|
|
return (
|
2017-01-05 16:57:41 +08:00
|
|
|
<Form onSubmit={this.handleSubmit}>
|
2016-04-29 12:13:27 +08:00
|
|
|
{formItems}
|
2018-12-22 16:48:30 +08:00
|
|
|
<Form.Item {...formItemLayoutWithOutLabel}>
|
2016-11-10 16:11:22 +08:00
|
|
|
<Button type="dashed" onClick={this.add} style={{ width: '60%' }}>
|
2016-12-31 23:47:07 +08:00
|
|
|
<Icon type="plus" /> Add field
|
2016-11-10 16:11:22 +08:00
|
|
|
</Button>
|
2018-12-22 16:48:30 +08:00
|
|
|
</Form.Item>
|
|
|
|
<Form.Item {...formItemLayoutWithOutLabel}>
|
2017-07-16 15:41:51 +08:00
|
|
|
<Button type="primary" htmlType="submit">Submit</Button>
|
2018-12-22 16:48:30 +08:00
|
|
|
</Form.Item>
|
2016-04-12 17:02:17 +08:00
|
|
|
</Form>
|
|
|
|
);
|
2016-11-10 16:11:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-17 10:02:08 +08:00
|
|
|
const WrappedDynamicFieldSet = Form.create({ name: 'dynamic_form_item' })(DynamicFieldSet);
|
2016-11-10 16:11:22 +08:00
|
|
|
ReactDOM.render(<WrappedDynamicFieldSet />, mountNode);
|
|
|
|
````
|
2016-04-12 17:02:17 +08:00
|
|
|
|
2016-11-10 16:11:22 +08:00
|
|
|
````css
|
2016-11-23 20:17:44 +08:00
|
|
|
.dynamic-delete-button {
|
2016-11-10 16:11:22 +08:00
|
|
|
cursor: pointer;
|
|
|
|
position: relative;
|
|
|
|
top: 4px;
|
|
|
|
font-size: 24px;
|
|
|
|
color: #999;
|
2016-11-23 20:17:44 +08:00
|
|
|
transition: all .3s;
|
2016-11-10 16:11:22 +08:00
|
|
|
}
|
2016-11-23 20:17:44 +08:00
|
|
|
.dynamic-delete-button:hover {
|
|
|
|
color: #777;
|
|
|
|
}
|
|
|
|
.dynamic-delete-button[disabled] {
|
2016-11-10 16:11:22 +08:00
|
|
|
cursor: not-allowed;
|
2016-11-23 20:17:44 +08:00
|
|
|
opacity: 0.5;
|
2016-11-10 16:11:22 +08:00
|
|
|
}
|
2016-04-12 17:02:17 +08:00
|
|
|
````
|