123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- import React, { Component } from 'react';
- import moment from 'moment';
- import { Form, Button, Switch, DatePicker, Input, InputNumber, Modal, Alert, Cascader } from 'antd';
- import Select from '../../components/Select';
- import Multiple from '../../components/Multiple';
- import Radio from '../../components/Radio';
- import TreeSelect from '../../components/TreeSelect';
- import FileUpload from '../../components/FileUpload';
- import './index.less';
- const { TextArea } = Input;
- class FormLayout extends Component {
- constructor(props) {
- super(props);
- this.state = { show: !!props.modal, loading: false, err: '' };
- }
- onConfirm() {
- this.props.form.validateFields((err, fieldsValue) => {
- if (err) {
- return;
- }
- if (this.props.onConfirm && this.props.modal) {
- this.setState({ loading: true });
- this.props
- .onConfirm(fieldsValue)
- .then(() => {
- this.setState({ loading: false });
- this.onCancel();
- })
- .catch(e => {
- this.setState({ loading: false, err: e.message });
- });
- } else {
- this.onCancel();
- }
- });
- }
- onCancel() {
- if (this.props.modal) this.setState({ show: false });
- if (this.props.onCancel) this.props.onCancel();
- }
- getItem(item) {
- switch (item.type) {
- case 'tree':
- return (
- <TreeSelect
- {...item}
- className={item.class}
- disabled={!!item.disabled}
- placeholder={item.placeholder}
- isNode={item.isNode}
- treeDefaultExpandAll
- treeData={item.tree}
- loadData={item.loadData}
- initData={item.initData}
- ignore={item.ignore}
- />
- );
- case 'radio':
- return <Radio {...item} className={item.class} select={item.select} disabled={!!item.disabled} />;
- case 'select':
- return (
- <Select
- {...item}
- className={item.class}
- select={item.select}
- placeholder={item.placeholder}
- disabled={!!item.disabled}
- />
- );
- case 'multiple':
- return (
- <Multiple
- {...item}
- className={item.class}
- select={item.select}
- placeholder={item.placeholder}
- disabled={!!item.disabled}
- />
- );
- case 'cascader':
- return <Cascader {...item} className={item.class} options={item.select} placeholder={item.placeholder} />;
- case 'render':
- return item.render(item, this.props.data, this.props.form);
- case 'textarea':
- return <TextArea {...item} autosize className={item.class} placeholder={item.placeholder} disabled={!!item.disabled} />;
- case 'password':
- case 'input':
- return (
- <Input
- {...item}
- className={item.class}
- placeholder={item.placeholder}
- readOnly={!!item.readOnly}
- disabled={!!item.disabled}
- />
- );
- case 'number':
- return (
- <InputNumber
- {...item}
- className={item.class}
- placeholder={item.placeholder}
- readOnly={!!item.readOnly}
- disabled={!!item.disabled}
- />
- );
- case 'switch':
- return <Switch {...item} className={item.class} disabled={!!item.disabled} />;
- case 'date':
- return <DatePicker {...item} className={item.class} placeholder={item.placeholder} disabled={!!item.disabled} />;
- case 'daterange':
- return <DatePicker.RangePicker {...item} className={item.class} />;
- case 'hidden':
- return <Input type="hidden" />;
- case 'image':
- case 'logo':
- case 'file':
- return (
- <FileUpload
- {...item}
- title={item.name}
- onEnd={url => {
- this.props.form.setFieldsValue({ [item.key]: url });
- }}
- onError={err => {
- this.props.form.setFields({ [item.key]: { value: '', errors: [err] } });
- }}
- />
- );
- default:
- return <div />;
- }
- }
- formatData(data, item) {
- switch (item.type) {
- case 'date':
- return moment(data[item.key]);
- default:
- return data[item.key];
- }
- }
- getForm() {
- const {
- modal,
- itemList = [],
- confirmText = '确定',
- cancelText = '取消',
- data = {},
- layoutCol = { labelCol: { span: 4 }, wrapperCol: { span: 20 } },
- } = this.props;
- const { getFieldDecorator } = this.props.form;
- return (
- <Form>
- {itemList.map((item, index) => {
- if (item.hidden) return '';
- const defaultOption = { rules: [] };
- const option = item.option ? Object.assign(defaultOption, item.option) : defaultOption;
- if (data && data[item.key]) {
- option.initialValue = this.formatData(data, item);
- }
- if (item.required) {
- option.rules.push({ required: true, message: item.placeholder });
- }
- if (item.type === 'hidden') {
- return <div>{getFieldDecorator(item.key, option)(this.getItem(item, option))}</div>;
- }
- return (
- <Form.Item {...layoutCol} key={index} label={item.name}>
- {getFieldDecorator(item.key, option)(this.getItem(item, option))}
- </Form.Item>
- );
- })}
- {!modal && (
- <Form.Item wrapperCol={{ offset: 6 }}>
- <Button type="primary" onClick={() => this.onConfirm()} style={{ marginRight: 20 }}>
- {confirmText}
- </Button>
- <Button onClick={() => this.onCancel()}>{cancelText}</Button>
- </Form.Item>
- )}
- </Form>
- );
- }
- render() {
- const { modal, title, confirmText = '确定', cancelText = '取消' } = this.props;
- const { show, loading, err } = this.state;
- return modal ? (
- <Modal
- title={title}
- visible={show}
- className="form-layout"
- okText={confirmText}
- cancelText={cancelText}
- confirmLoading={loading}
- onOk={() => this.onConfirm()}
- onCancel={() => this.onCancel()}
- >
- {err && <Alert type="error" showIcon message={err} closable onClose={() => this.setState({ err: '' })} />}
- {this.getForm()}
- </Modal>
- ) : (<div className="form-layout">{this.getForm()}</div>);
- }
- }
- export default Form.create()(FormLayout);
|