Form.list + Table实现可编辑表格,添加,删除,上移下移

155 阅读1分钟
import React from 'react';
import { MinusCircleOutlined, PlusOutlined, EllipsisOutlined } from '@ant-design/icons';
import { Button, Dropdown, Form, Input, InputNumber, Menu, Select, Space, Table } from 'antd';
import { uniqueId } from 'lodash'

const mockData = [
    {
        key: '1',
        name: '小红',
        value: 12,
        type: 'Input'
    },
    {
        key: '2',
        name: '小明',
        value: 36,
        type: 'Input'
    }
]
const App: React.FC = () => {
    const [form] = Form.useForm();

    const onFinish = (values: any) => {
        console.log('Received values of form:', values);
    };

    const getInput = (record: { type: string }) => {
        if (record?.type === 'InputNumber') {
            return (
                <InputNumber />
            )
        }
        if (record?.type === 'Select') {
            return (
                <Select allowClear>
                    <Select value={true}></Select>
                    <Select value={false}></Select>
                </Select>
            )
        }
        return (
            <Input placeholder='请输入' allowClear />
        )
    }

    const getColumns = (remove, move) => {
        return [
            {
                title: "名称",
                dataIndex: 'name',
                render(text, field, index) {
                    const record = form.getFieldValue('users')?.[index];
                    const isEdit = record?.isEdit || false;
                    return (
                        <Form.Item required name={[field?.name, 'name']} shouldUpdate={true}>
                            {
                                isEdit ? <Input allowClear placeholder='请输入' /> : record.name
                            }
                        </Form.Item>
                    )
                }
            },
            {
                title: "数值",
                dataIndex: 'value',
                render(text, field, index) {
                    const record = form.getFieldValue('users')?.[index];
                    const isEdit = record?.isEdit || false;
                    return (
                        <Form.Item required name={[field?.name, 'value']} shouldUpdate={true}>
                            {
                                isEdit ? getInput(record) : record?.value
                            }
                        </Form.Item>
                    )
                }
            },
            {
                title: "操作",
                render(text, field, index) {
                    const record = form.getFieldValue('users')?.[index];
                    const isEdit = record?.isEdit || false;
                    const recordList = form.getFieldValue('users')
                    return (
                        <Space>
                            <a onClick={() => remove(field.name)}>删除</a>
                            {
                                !isEdit &&
                                <a onClick={() => {
                                    const newList = recordList?.map((item) => {
                                        if (item?.key === record?.key) {
                                            return { ...item, isEdit: true }
                                        }
                                        return item
                                    })
                                    // const itemIndex = newList?.findIndex((item) => item?.key === record?.key)
                                    // newList[itemIndex] = { ...newList[itemIndex], isEdit: true }
                                    form.setFieldsValue({ ['users']: newList })
                                }}>
                                    编辑
                                </a>
                            }
                            {
                                isEdit &&
                                <a onClick={() => {
                                    const list = [...form.getFieldValue(['users'])];
                                    const itemIndex = list?.findIndex((item) => item?.key === record?.key)
                                    list[itemIndex] = { ...list[itemIndex], isEdit: false }
                                    form.setFieldsValue({ ['users']: list })
                                }}>
                                    保存
                                </a>
                            }
                            {
                                isEdit &&
                                <a onClick={() => {
                                    const list = [...form.getFieldValue(['users'])];
                                    const itemIndex = list?.findIndex((item) => item?.key === record?.key)
                                    list[itemIndex] = { ...list[itemIndex], isEdit: false }
                                    form.setFieldsValue({ ['users']: list })
                                }}>
                                    取消
                                </a>
                            }
                            {/* 上移下移 */}
                            <Dropdown
                                getPopupContainer={(triggerNode) => triggerNode.parentElement}
                                overlay={
                                    <Menu>
                                        <Menu.Item>
                                            <a onClick={() => { if (index > 0) { move(index, index - 1) } }}>上移</a>
                                        </Menu.Item>
                                        <Menu.Item>
                                            <a onClick={() => { move(index, index + 1) }}>下移</a>
                                        </Menu.Item>
                                    </Menu>
                                }
                                trigger={['click']}
                            >
                                <EllipsisOutlined />
                            </Dropdown>
                        </Space>
                    )
                }
            }
        ]
    }
    return (
        <Form
            form={form}
            initialValues={{ users: mockData }}
            onFinish={onFinish}
            style={{ maxWidth: 800 }}
        >
            <Form.List name="users">
                {(fields, { add, remove, move }, { errors }) => (
                    <>
                        <Table
                            dataSource={fields}
                            columns={getColumns(remove, move)}
                            rowKey='key'
                            pagination={false}
                        />

                        <Form.Item>
                            <Button
                                type="dashed"
                                style={{ width: '100%', marginTop: '8px' }}
                                icon={<PlusOutlined />}
                                onClick={() => {
                                    // add('The head item', 0); //加个0 会从顶部添加
                                    // const newKey = uniqueId('tableForm') //添加一个唯一的key
                                    // add({key:newKey,});
                                    add({ isEdit: true })
                                }}
                            >
                                添加一行
                            </Button>
                        </Form.Item>
                    </>
                )}
            </Form.List>
            <Form.Item>
                <Button type="primary" htmlType="submit">
                    提交
                </Button>
            </Form.Item>
        </Form>
    );
};

export default App;

image.png