AdvancedForm.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. import React, { PureComponent } from 'react';
  2. import {
  3. Card,
  4. Button,
  5. Form,
  6. Icon,
  7. Col,
  8. Row,
  9. DatePicker,
  10. TimePicker,
  11. Input,
  12. Select,
  13. Popover,
  14. } from 'antd';
  15. import { connect } from 'dva';
  16. import FooterToolbar from 'components/FooterToolbar';
  17. import PageHeaderLayout from '../../layouts/PageHeaderLayout';
  18. import TableForm from './TableForm';
  19. import styles from './style.less';
  20. const { Option } = Select;
  21. const { RangePicker } = DatePicker;
  22. const fieldLabels = {
  23. name: '仓库名',
  24. url: '仓库域名',
  25. owner: '仓库管理员',
  26. approver: '审批人',
  27. dateRange: '生效日期',
  28. type: '仓库类型',
  29. name2: '任务名',
  30. url2: '任务描述',
  31. owner2: '执行人',
  32. approver2: '责任人',
  33. dateRange2: '生效日期',
  34. type2: '任务类型',
  35. };
  36. const tableData = [
  37. {
  38. key: '1',
  39. workId: '00001',
  40. name: 'John Brown',
  41. department: 'New York No. 1 Lake Park',
  42. },
  43. {
  44. key: '2',
  45. workId: '00002',
  46. name: 'Jim Green',
  47. department: 'London No. 1 Lake Park',
  48. },
  49. {
  50. key: '3',
  51. workId: '00003',
  52. name: 'Joe Black',
  53. department: 'Sidney No. 1 Lake Park',
  54. },
  55. ];
  56. @connect(({ global, loading }) => ({
  57. collapsed: global.collapsed,
  58. submitting: loading.effects['form/submitAdvancedForm'],
  59. }))
  60. @Form.create()
  61. export default class AdvancedForm extends PureComponent {
  62. render() {
  63. const { form, dispatch, submitting } = this.props;
  64. const { getFieldDecorator, validateFieldsAndScroll, getFieldsError } = form;
  65. const validate = () => {
  66. validateFieldsAndScroll((error, values) => {
  67. if (!error) {
  68. // submit the values
  69. dispatch({
  70. type: 'form/submitAdvancedForm',
  71. payload: values,
  72. });
  73. }
  74. });
  75. };
  76. const errors = getFieldsError();
  77. const getErrorInfo = () => {
  78. const errorCount = Object.keys(errors).filter(key => errors[key]).length;
  79. if (!errors || errorCount === 0) {
  80. return null;
  81. }
  82. const scrollToField = fieldKey => {
  83. const labelNode = document.querySelector(`label[for="${fieldKey}"]`);
  84. if (labelNode) {
  85. labelNode.scrollIntoView(true);
  86. }
  87. };
  88. const errorList = Object.keys(errors).map(key => {
  89. if (!errors[key]) {
  90. return null;
  91. }
  92. return (
  93. <li key={key} className={styles.errorListItem} onClick={() => scrollToField(key)}>
  94. <Icon type="cross-circle-o" className={styles.errorIcon} />
  95. <div className={styles.errorMessage}>{errors[key][0]}</div>
  96. <div className={styles.errorField}>{fieldLabels[key]}</div>
  97. </li>
  98. );
  99. });
  100. return (
  101. <span className={styles.errorIcon}>
  102. <Popover
  103. title="表单校验信息"
  104. content={errorList}
  105. overlayClassName={styles.errorPopover}
  106. trigger="click"
  107. getPopupContainer={trigger => trigger.parentNode}
  108. >
  109. <Icon type="exclamation-circle" />
  110. </Popover>
  111. {errorCount}
  112. </span>
  113. );
  114. };
  115. return (
  116. <PageHeaderLayout
  117. title="高级表单"
  118. content="高级表单常见于一次性输入和提交大批量数据的场景。"
  119. wrapperClassName={styles.advancedForm}
  120. >
  121. <Card title="仓库管理" className={styles.card} bordered={false}>
  122. <Form layout="vertical" hideRequiredMark>
  123. <Row gutter={16}>
  124. <Col lg={6} md={12} sm={24}>
  125. <Form.Item label={fieldLabels.name}>
  126. {getFieldDecorator('name', {
  127. rules: [{ required: true, message: '请输入仓库名称' }],
  128. })(<Input placeholder="请输入仓库名称" />)}
  129. </Form.Item>
  130. </Col>
  131. <Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}>
  132. <Form.Item label={fieldLabels.url}>
  133. {getFieldDecorator('url', {
  134. rules: [{ required: true, message: '请选择' }],
  135. })(
  136. <Input
  137. style={{ width: '100%' }}
  138. addonBefore="http://"
  139. addonAfter=".com"
  140. placeholder="请输入"
  141. />
  142. )}
  143. </Form.Item>
  144. </Col>
  145. <Col xl={{ span: 8, offset: 2 }} lg={{ span: 10 }} md={{ span: 24 }} sm={24}>
  146. <Form.Item label={fieldLabels.owner}>
  147. {getFieldDecorator('owner', {
  148. rules: [{ required: true, message: '请选择管理员' }],
  149. })(
  150. <Select placeholder="请选择管理员">
  151. <Option value="xiao">付晓晓</Option>
  152. <Option value="mao">周毛毛</Option>
  153. </Select>
  154. )}
  155. </Form.Item>
  156. </Col>
  157. </Row>
  158. <Row gutter={16}>
  159. <Col lg={6} md={12} sm={24}>
  160. <Form.Item label={fieldLabels.approver}>
  161. {getFieldDecorator('approver', {
  162. rules: [{ required: true, message: '请选择审批员' }],
  163. })(
  164. <Select placeholder="请选择审批员">
  165. <Option value="xiao">付晓晓</Option>
  166. <Option value="mao">周毛毛</Option>
  167. </Select>
  168. )}
  169. </Form.Item>
  170. </Col>
  171. <Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}>
  172. <Form.Item label={fieldLabels.dateRange}>
  173. {getFieldDecorator('dateRange', {
  174. rules: [{ required: true, message: '请选择生效日期' }],
  175. })(
  176. <RangePicker placeholder={['开始日期', '结束日期']} style={{ width: '100%' }} />
  177. )}
  178. </Form.Item>
  179. </Col>
  180. <Col xl={{ span: 8, offset: 2 }} lg={{ span: 10 }} md={{ span: 24 }} sm={24}>
  181. <Form.Item label={fieldLabels.type}>
  182. {getFieldDecorator('type', {
  183. rules: [{ required: true, message: '请选择仓库类型' }],
  184. })(
  185. <Select placeholder="请选择仓库类型">
  186. <Option value="private">私密</Option>
  187. <Option value="public">公开</Option>
  188. </Select>
  189. )}
  190. </Form.Item>
  191. </Col>
  192. </Row>
  193. </Form>
  194. </Card>
  195. <Card title="任务管理" className={styles.card} bordered={false}>
  196. <Form layout="vertical" hideRequiredMark>
  197. <Row gutter={16}>
  198. <Col lg={6} md={12} sm={24}>
  199. <Form.Item label={fieldLabels.name2}>
  200. {getFieldDecorator('name2', {
  201. rules: [{ required: true, message: '请输入' }],
  202. })(<Input placeholder="请输入" />)}
  203. </Form.Item>
  204. </Col>
  205. <Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}>
  206. <Form.Item label={fieldLabels.url2}>
  207. {getFieldDecorator('url2', {
  208. rules: [{ required: true, message: '请选择' }],
  209. })(<Input placeholder="请输入" />)}
  210. </Form.Item>
  211. </Col>
  212. <Col xl={{ span: 8, offset: 2 }} lg={{ span: 10 }} md={{ span: 24 }} sm={24}>
  213. <Form.Item label={fieldLabels.owner2}>
  214. {getFieldDecorator('owner2', {
  215. rules: [{ required: true, message: '请选择管理员' }],
  216. })(
  217. <Select placeholder="请选择管理员">
  218. <Option value="xiao">付晓晓</Option>
  219. <Option value="mao">周毛毛</Option>
  220. </Select>
  221. )}
  222. </Form.Item>
  223. </Col>
  224. </Row>
  225. <Row gutter={16}>
  226. <Col lg={6} md={12} sm={24}>
  227. <Form.Item label={fieldLabels.approver2}>
  228. {getFieldDecorator('approver2', {
  229. rules: [{ required: true, message: '请选择审批员' }],
  230. })(
  231. <Select placeholder="请选择审批员">
  232. <Option value="xiao">付晓晓</Option>
  233. <Option value="mao">周毛毛</Option>
  234. </Select>
  235. )}
  236. </Form.Item>
  237. </Col>
  238. <Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}>
  239. <Form.Item label={fieldLabels.dateRange2}>
  240. {getFieldDecorator('dateRange2', {
  241. rules: [{ required: true, message: '请输入' }],
  242. })(
  243. <TimePicker
  244. placeholder="提醒时间"
  245. style={{ width: '100%' }}
  246. getPopupContainer={trigger => trigger.parentNode}
  247. />
  248. )}
  249. </Form.Item>
  250. </Col>
  251. <Col xl={{ span: 8, offset: 2 }} lg={{ span: 10 }} md={{ span: 24 }} sm={24}>
  252. <Form.Item label={fieldLabels.type2}>
  253. {getFieldDecorator('type2', {
  254. rules: [{ required: true, message: '请选择仓库类型' }],
  255. })(
  256. <Select placeholder="请选择仓库类型">
  257. <Option value="private">私密</Option>
  258. <Option value="public">公开</Option>
  259. </Select>
  260. )}
  261. </Form.Item>
  262. </Col>
  263. </Row>
  264. </Form>
  265. </Card>
  266. <Card title="成员管理" bordered={false}>
  267. {getFieldDecorator('members', {
  268. initialValue: tableData,
  269. })(<TableForm />)}
  270. </Card>
  271. <FooterToolbar>
  272. {getErrorInfo()}
  273. <Button type="primary" onClick={validate} loading={submitting}>
  274. 提交
  275. </Button>
  276. </FooterToolbar>
  277. </PageHeaderLayout>
  278. );
  279. }
  280. }