Antd 可编辑表格暂存

//组件部分
import React, { useContext, useState, useEffect, useRef } from 'react';
import { Table, Input, Form, DatePicker, Select } from 'antd';
import styles from './index.less';
import moment from 'moment';
const EditableContext = React.createContext(null);

const { Option } = Select;

const EditableRow = ({ index, ...props }) => {
    const [form] = Form.useForm();
    return (
        <Form form={form} component={false}>
            <EditableContext.Provider value={form}>
                <tr {...props} />
            </EditableContext.Provider>
        </Form>
    );
};

const renderFormItem = (type, props, otherParam) => {
    const { optionList } = otherParam;
    console.log('optionList: ', optionList);
    switch (type) {
        case 'date':
            return <DatePicker {...props} />;
        case 'select':
            return (
                <Select placeholder="请选择" {...props}>
                    {optionList.map((item) => {
                        return (
                            <Option value={item.id} key={item.id}>
                                {item.name}
                            </Option>
                        );
                    })}
                </Select>
            );
        default:
            return <Input {...props} placeholder="请输入" />;
    }
};

const EditableCell = ({
    title,
    editable,
    children,
    dataIndex,
    record,
    handleSave,
    editType,
    rules,
    optionList,
    ...restProps
}) => {
    console.log(editType, 'editType');
    const [editing, setEditing] = useState(false);
    const editRef = useRef(null);
    const form = useContext(EditableContext);
    useEffect(() => {
        if (editing) {
            editRef.current.focus();
        }
    }, [editing]);

    const toggleEdit = () => {
        setEditing(!editing);
        // form.setFieldsValue({
        //     [dataIndex]: record[dataIndex],
        // });
    };

    const save = async () => {
        try {
            const values = await form.validateFields();
            console.log('values: ', values);
            toggleEdit();
            handleSave({ ...record, ...values });
        } catch (errInfo) {
            console.log('Save failed:', errInfo);
        }
    };

    let childNode = children;

    if (editable) {
        childNode = editing ? (
            <Form.Item
                style={{
                    margin: 0,
                }}
                name={dataIndex}
                rules={rules}
                initialValue={record[dataIndex]}
            >
                {renderFormItem(
                    editType,
                    {
                        ref: editRef,
                        onPressEnter: save,
                        onBlur: save,
                        style: { width: '100%' },
                    },
                    {
                        optionList,
                    },
                )}
            </Form.Item>
        ) : (
            <div
                className="editable-cell-value-wrap"
                style={{
                    width: '100%',
                    minHeight: 32,
                }}
                onClick={toggleEdit}
            >
                {children}
            </div>
        );
    }

    return <td {...restProps}>{childNode}</td>;
};

export default class EditableTable extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            dataSource: props.dataSource || [],
            columns: props.columns || [],
        };
    }

    handleDelete = (key) => {
        const dataSource = [...this.state.dataSource];
        this.setState({
            dataSource: dataSource.filter((item) => item.key !== key),
        });
    };

    handleSave = (row) => {
        const newData = [...this.state.dataSource];
        const index = newData.findIndex((item) => row.key === item.key);
        const item = newData[index];
        newData.splice(index, 1, { ...item, ...row });
        this.setState({
            dataSource: newData,
        });
    };

    render() {
        const { dataSource } = this.state;
        const { className, loading } = this.props;
        const components = {
            body: {
                row: EditableRow,
                cell: EditableCell,
            },
        };
        const columns = this.state.columns.map((col) => {
            console.log('col: ', col);
            if (!col.editable) {
                return col;
            }

            return {
                ...col,
                ellipsis: { showTitle: 'false' },

                onCell: (record) => ({
                    record,
                    editable: col.editable,
                    dataIndex: col.dataIndex,
                    title: col.title,
                    handleSave: this.handleSave,
                    editType: col.type,
                    rules: col.rules,
                    optionList: col.optionList || [],
                }),
            };
        });
        return (
            <Table
                rowKey={'id'}
                className={`${styles.editableTable} ${className}`}
                components={components}
                rowClassName={() => 'editable-row'}
                bordered={false}
                dataSource={dataSource}
                columns={columns}
                loading={loading}
            />
        );
    }
}

//样式部分
.editableTable {
    :global {
        .editable-cell {
            position: relative;
        }

        .editable-cell-value-wrap {
            cursor: pointer;
            display: flex;
            align-items: center;
            &:hover {
                border: 1px solid #d9d9d9;
                border-radius: 2px;
            }
        }
    }
}

//页面引用部分


const dataList = [
    { id: '1', name: '张三', date: moment() },
    { id: '2', name: '里斯' },
];

const testColumns: any = [
    {
        key: 'id',
        dataIndex: 'id',
        title: 'ID',
        readonly: true,
        editable: true,
        type: 'number',
    },
    { key: 'name', dataIndex: 'name', title: '姓名', editable: true },
    {
        key: 'date',
        dataIndex: 'date',
        title: '日期',
        editable: true,
        type: 'date',
        render: (text: any, record: any) => {
            return text ? moment(text).format('YYYY-MM-DD') : '';
        },
    },
    {
        key: 'position',
        dataIndex: 'position',
        title: '选择',
        editable: true,
        type: 'select',
        optionList: [
            { id: '1', name: '选择1' },
            { id: '2', name: '选择2' },
        ],
        render: (text: any, record: any) => {
            return text ? (text === '1' ? '选择1' : '选择2') : '';
        },
    },
    {
        key: 'action',
        title: '操作',
        align: 'center',
        render: (text: any, record: any) => {
            return (
                <Button
                    color="primary"
                    onClick={() => {
                        console.log(record, 'record');
                    }}
                >
                    保存
                </Button>
            );
        },
    },
];

import AntdTable from './AntdAllowEditTable';


 <AntdTable
                dataSource={dataList}
                columns={testColumns}
                loading={loading}
            />

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值