| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- import React, { PureComponent, Fragment } from 'react';
- import { Table, Button, Input, message, Popconfirm, Divider } from 'antd';
- import isEqual from 'lodash/isEqual';
- import styles from './style.less';
- class TableForm extends PureComponent {
- index = 0;
- cacheOriginData = {};
- constructor(props) {
- super(props);
- this.state = {
- data: props.value,
- loading: false,
- /* eslint-disable-next-line react/no-unused-state */
- value: props.value,
- };
- }
- static getDerivedStateFromProps(nextProps, preState) {
- if (isEqual(nextProps.value, preState.value)) {
- return null;
- }
- return {
- data: nextProps.value,
- value: nextProps.value,
- };
- }
- getRowByKey(key, newData) {
- const { data } = this.state;
- return (newData || data).filter(item => item.key === key)[0];
- }
- toggleEditable = (e, key) => {
- e.preventDefault();
- const { data } = this.state;
- const newData = data.map(item => ({ ...item }));
- const target = this.getRowByKey(key, newData);
- if (target) {
- // 进入编辑状态时保存原始数据
- if (!target.editable) {
- this.cacheOriginData[key] = { ...target };
- }
- target.editable = !target.editable;
- this.setState({ data: newData });
- }
- };
- newMember = () => {
- 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,
- });
- this.index += 1;
- this.setState({ data: newData });
- };
- remove(key) {
- const { data } = this.state;
- const { onChange } = this.props;
- const newData = data.filter(item => item.key !== key);
- this.setState({ data: newData });
- onChange(newData);
- }
- handleKeyPress(e, key) {
- if (e.key === 'Enter') {
- this.saveRow(e, key);
- }
- }
- handleFieldChange(e, fieldName, key) {
- const { data } = this.state;
- const newData = data.map(item => ({ ...item }));
- const target = this.getRowByKey(key, newData);
- if (target) {
- target[fieldName] = e.target.value;
- this.setState({ data: newData });
- }
- }
- saveRow(e, key) {
- e.persist();
- this.setState({
- loading: true,
- });
- setTimeout(() => {
- if (this.clickedCancel) {
- this.clickedCancel = false;
- return;
- }
- const target = this.getRowByKey(key) || {};
- if (!target.workId || !target.name || !target.department) {
- message.error('请填写完整成员信息。');
- e.target.focus();
- this.setState({
- loading: false,
- });
- return;
- }
- delete target.isNew;
- this.toggleEditable(e, key);
- const { data } = this.state;
- const { onChange } = this.props;
- onChange(data);
- this.setState({
- loading: false,
- });
- }, 500);
- }
- cancel(e, key) {
- this.clickedCancel = true;
- e.preventDefault();
- const { data } = this.state;
- const newData = data.map(item => ({ ...item }));
- const target = this.getRowByKey(key, newData);
- if (this.cacheOriginData[key]) {
- Object.assign(target, this.cacheOriginData[key]);
- delete this.cacheOriginData[key];
- }
- target.editable = false;
- this.setState({ data: newData });
- this.clickedCancel = false;
- }
- render() {
- const 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>
- );
- },
- },
- ];
- const { loading, data } = this.state;
- return (
- <Fragment>
- <Table
- loading={loading}
- columns={columns}
- dataSource={data}
- pagination={false}
- rowClassName={record => (record.editable ? styles.editable : '')}
- />
- <Button
- style={{ width: '100%', marginTop: 16, marginBottom: 8 }}
- type="dashed"
- onClick={this.newMember}
- icon="plus"
- >
- 新增成员
- </Button>
- </Fragment>
- );
- }
- }
- export default TableForm;
|