"FormAdvancedForm/src/components/TableForm.tsx" did not exist on "8c74bc6cf62fc19a916338b380374aef1afb8914"
TableForm.tsx 6.58 KB
Newer Older
陈帅's avatar
陈帅 committed
1
import React, { PureComponent, Fragment } from 'react';
afc163's avatar
afc163 committed
2
import { Table, Button, Input, message, Popconfirm, Divider } from 'antd';
3 4
import { isEqual } from 'lodash';
import styles from '../style.less';
5

lijiehua's avatar
lijiehua committed
6
class TableForm extends PureComponent {
陈帅's avatar
陈帅 committed
7 8 9 10 11 12 13 14 15
  static getDerivedStateFromProps(nextProps, preState) {
    if (isEqual(nextProps.value, preState.value)) {
      return null;
    }
    return {
      data: nextProps.value,
      value: nextProps.value,
    };
  }
陈帅's avatar
陈帅 committed
16

17 18 19
  index = 0;

  cacheOriginData = {};
陈帅's avatar
陈帅 committed
20

陈帅's avatar
陈帅 committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
  columns = [
    {
      title: '成员姓名',
      dataIndex: 'name',
      key: 'name',
      width: '20%',
      render: (text, record) => {
        if (record.editable) {
          return (
            <Input
              value={text}
              autoFocus
              onChange={e => this.handleFieldChange(e, 'name', record.key)}
              onKeyPress={e => this.handleKeyPress(e, record.key)}
              placeholder="成员姓名"
            />
          );
        }
        return text;
      },
    },
    {
      title: '工号',
      dataIndex: 'workId',
      key: 'workId',
      width: '20%',
      render: (text, record) => {
        if (record.editable) {
          return (
            <Input
              value={text}
              onChange={e => this.handleFieldChange(e, 'workId', record.key)}
              onKeyPress={e => this.handleKeyPress(e, record.key)}
              placeholder="工号"
            />
          );
        }
        return text;
      },
    },
    {
      title: '所属部门',
      dataIndex: 'department',
      key: 'department',
      width: '40%',
      render: (text, record) => {
        if (record.editable) {
          return (
            <Input
              value={text}
              onChange={e => this.handleFieldChange(e, 'department', record.key)}
              onKeyPress={e => this.handleKeyPress(e, record.key)}
              placeholder="所属部门"
            />
          );
        }
        return text;
      },
    },
    {
      title: '操作',
      key: 'action',
      render: (text, record) => {
        const { loading } = this.state;
        if (!!record.editable && loading) {
          return null;
        }
        if (record.editable) {
          if (record.isNew) {
            return (
              <span>
                <a onClick={e => this.saveRow(e, record.key)}>添加</a>
                <Divider type="vertical" />
                <Popconfirm title="是否要删除此行?" onConfirm={() => this.remove(record.key)}>
                  <a>删除</a>
                </Popconfirm>
              </span>
            );
          }
          return (
            <span>
              <a onClick={e => this.saveRow(e, record.key)}>保存</a>
              <Divider type="vertical" />
              <a onClick={e => this.cancel(e, record.key)}>取消</a>
            </span>
          );
        }
        return (
          <span>
            <a onClick={e => this.toggleEditable(e, record.key)}>编辑</a>
            <Divider type="vertical" />
            <Popconfirm title="是否要删除此行?" onConfirm={() => this.remove(record.key)}>
              <a>删除</a>
            </Popconfirm>
          </span>
        );
      },
    },
  ];
陈帅's avatar
陈帅 committed
120

121 122 123 124 125
  constructor(props) {
    super(props);

    this.state = {
      data: props.value,
jim chen's avatar
jim chen committed
126
      loading: false,
127 128
      /* eslint-disable-next-line react/no-unused-state */
      value: props.value,
129 130
    };
  }
jim's avatar
jim committed
131

afc163's avatar
afc163 committed
132
  getRowByKey(key, newData) {
陈帅's avatar
陈帅 committed
133 134
    const { data } = this.state;
    return (newData || data).filter(item => item.key === key)[0];
135
  }
陈帅's avatar
陈帅 committed
136

jim's avatar
jim committed
137
  toggleEditable = (e, key) => {
138
    e.preventDefault();
陈帅's avatar
陈帅 committed
139 140
    const { data } = this.state;
    const newData = data.map(item => ({ ...item }));
afc163's avatar
afc163 committed
141
    const target = this.getRowByKey(key, newData);
142 143 144 145 146 147
    if (target) {
      // 进入编辑状态时保存原始数据
      if (!target.editable) {
        this.cacheOriginData[key] = { ...target };
      }
      target.editable = !target.editable;
afc163's avatar
afc163 committed
148
      this.setState({ data: newData });
149
    }
jim's avatar
jim committed
150
  };
陈帅's avatar
陈帅 committed
151 152

  newMember = () => {
153 154 155 156 157 158 159 160 161
    const { data } = this.state;
    const newData = data.map(item => ({ ...item }));
    newData.push({
      key: `NEW_TEMP_ID_${this.index}`,
      workId: '',
      name: '',
      department: '',
      editable: true,
      isNew: true,
陈帅's avatar
陈帅 committed
162
    });
163 164
    this.index += 1;
    this.setState({ data: newData });
陈帅's avatar
陈帅 committed
165 166
  };

afc163's avatar
afc163 committed
167
  remove(key) {
168
    const { data } = this.state;
陈帅's avatar
陈帅 committed
169 170
    const { onChange } = this.props;
    const newData = data.filter(item => item.key !== key);
171
    this.setState({ data: newData });
陈帅's avatar
陈帅 committed
172
    onChange(newData);
afc163's avatar
afc163 committed
173
  }
陈帅's avatar
陈帅 committed
174

175 176 177 178 179 180
  handleKeyPress(e, key) {
    if (e.key === 'Enter') {
      this.saveRow(e, key);
    }
  }

181
  handleFieldChange(e, fieldName, key) {
陈帅's avatar
陈帅 committed
182 183
    const { data } = this.state;
    const newData = data.map(item => ({ ...item }));
afc163's avatar
afc163 committed
184
    const target = this.getRowByKey(key, newData);
185 186 187 188 189
    if (target) {
      target[fieldName] = e.target.value;
      this.setState({ data: newData });
    }
  }
陈帅's avatar
陈帅 committed
190

191
  saveRow(e, key) {
afc163's avatar
afc163 committed
192
    e.persist();
jim chen's avatar
jim chen committed
193 194 195
    this.setState({
      loading: true,
    });
afc163's avatar
afc163 committed
196 197 198 199 200
    setTimeout(() => {
      if (this.clickedCancel) {
        this.clickedCancel = false;
        return;
      }
afc163's avatar
afc163 committed
201
      const target = this.getRowByKey(key) || {};
afc163's avatar
afc163 committed
202 203
      if (!target.workId || !target.name || !target.department) {
        message.error('请填写完整成员信息。');
afc163's avatar
afc163 committed
204
        e.target.focus();
205 206 207
        this.setState({
          loading: false,
        });
afc163's avatar
afc163 committed
208 209
        return;
      }
afc163's avatar
afc163 committed
210
      delete target.isNew;
afc163's avatar
afc163 committed
211
      this.toggleEditable(e, key);
WeiYang Qiu's avatar
WeiYang Qiu committed
212 213
      const { data } = this.state;
      const { onChange } = this.props;
陈帅's avatar
陈帅 committed
214
      onChange(data);
jim chen's avatar
jim chen committed
215 216 217 218
      this.setState({
        loading: false,
      });
    }, 500);
219
  }
陈帅's avatar
陈帅 committed
220

221
  cancel(e, key) {
afc163's avatar
afc163 committed
222
    this.clickedCancel = true;
223
    e.preventDefault();
224
    const { data } = this.state;
陈帅's avatar
陈帅 committed
225
    const newData = data.map(item => ({ ...item }));
afc163's avatar
afc163 committed
226
    const target = this.getRowByKey(key, newData);
227 228 229 230
    if (this.cacheOriginData[key]) {
      Object.assign(target, this.cacheOriginData[key]);
      delete this.cacheOriginData[key];
    }
WeiYang Qiu's avatar
WeiYang Qiu committed
231
    target.editable = false;
afc163's avatar
afc163 committed
232
    this.setState({ data: newData });
233
    this.clickedCancel = false;
234
  }
陈帅's avatar
陈帅 committed
235

236
  render() {
237 238
    const { loading, data } = this.state;

239
    return (
陈帅's avatar
陈帅 committed
240
      <Fragment>
241
        <Table
陈帅's avatar
陈帅 committed
242
          loading={loading}
陈帅's avatar
陈帅 committed
243
          columns={this.columns}
244
          dataSource={data}
245
          pagination={false}
246
          rowClassName={record => (record.editable ? styles.editable : '')}
247 248
        />
        <Button
249
          style={{ width: '100%', marginTop: 16, marginBottom: 8 }}
250 251 252 253 254 255
          type="dashed"
          onClick={this.newMember}
          icon="plus"
        >
          新增成员
        </Button>
陈帅's avatar
陈帅 committed
256
      </Fragment>
257 258 259
    );
  }
}
lijiehua's avatar
lijiehua committed
260 261

export default TableForm;