import React, { useState } from 'react';
import 'antd/dist/antd.css';
// import './index.css';
import { MenuOutlined } from '@ant-design/icons';
import { Table } from 'antd';
import { arrayMoveImmutable } from 'array-move';
import { Form, Input, InputNumber, Popconfirm, Table, Typography } from 'antd';
import {
SortableContainer,
SortableElement,
SortableHandle,
} from 'react-sortable-hoc';
const originData = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
index: 0,
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
index: 1,
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
index: 2,
},
];
const EditableCell = ({
editing,
dataIndex,
title,
inputType,
record,
index,
children,
...restProps
}) => {
const inputNode = inputType === 'number' ? <InputNumber /> : <Input />;
return (
<td {...restProps}>
{editing ? (
<Form.Item
name={dataIndex}
style={{
margin: 0,
}}
rules={[
{
required: true,
message: `Please Input ${title}!`,
},
]}
>
{inputNode}
</Form.Item>
) : (
children
)}
</td>
);
};
const DragHandle = SortableHandle(() => (
<MenuOutlined
style={{
cursor: 'grab',
color: '#999',
}}
/>
));
const SortableItem = SortableElement((props) => <tr {...props} />);
const SortableBody = SortableContainer((props) => <tbody {...props} />);
const App = () => {
// const [dataSource, setDataSource] = useState(data);
const [form] = Form.useForm();
const [data, setData] = useState(originData);
const [editingKey, setEditingKey] = useState('');
const isEditing = (record) => record.key === editingKey;
const edit = (record) => {
form.setFieldsValue({
...record,
});
setEditingKey(record.key);
};
const cancel = () => {
setEditingKey('');
};
const save = async (key) => {
try {
const row = await form.validateFields();
const newData = [...data];
const index = newData.findIndex((item) => key === item.key);
if (index > -1) {
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
});
setData(newData);
setEditingKey('');
} else {
newData.push(row);
setData(newData);
setEditingKey('');
}
} catch (errInfo) {
console.log('Validate Failed:', errInfo);
}
};
const columns = [
{
title: 'Name',
dataIndex: 'name',
className: 'drag-visible',
editable: true,
},
{
title: 'Age',
dataIndex: 'age',
editable: true,
},
{
title: 'Address',
dataIndex: 'address',
editable: true,
},
{
title: 'operation',
dataIndex: 'operation',
render: (_, record) => {
const editable = isEditing(record);
return editable ? (
<span>
<Typography.Link
onClick={() => save(record.key)}
style={{
marginRight: 8,
}}
>
保存
</Typography.Link>
<Popconfirm title="Sure to cancel?" onConfirm={cancel}>
<a>删除</a>
</Popconfirm>
</span>
) : (
<div style={{ display: 'flex' }}>
<Typography.Link
disabled={editingKey !== ''}
onClick={() => edit(record)}
>
编辑
</Typography.Link>
<div style={{ marginLeft: '16px' }}>
<DragHandle />
</div>
</div>
);
},
},
];
const onSortEnd = ({ oldIndex, newIndex }) => {
if (oldIndex !== newIndex) {
const newData = arrayMoveImmutable(
data.slice(),
oldIndex,
newIndex
).filter((el) => !!el);
console.log('Sorted items: ', newData);
setData(newData);
}
};
const DraggableContainer = (props) => (
<SortableBody
useDragHandle
disableAutoscroll
helperClass="row-dragging"
onSortEnd={onSortEnd}
{...props}
/>
);
const DraggableBodyRow = ({ className, style, ...restProps }) => {
// function findIndex base on Table rowKey props and should always be a right array index
const index = data.findIndex((x) => x.index === restProps['data-row-key']);
return <SortableItem index={index} {...restProps} />;
};
const mergedColumns = columns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record) => ({
record,
inputType: col.dataIndex === 'age' ? 'number' : 'text',
dataIndex: col.dataIndex,
title: col.title,
editing: isEditing(record),
}),
};
});
return (
<Form form={form} component={false}>
<Table
pagination={false}
// dataSource={dataSource}
// columns={columns}
rowKey="index"
dataSource={data}
columns={mergedColumns}
components={{
body: {
cell: EditableCell,
wrapper: DraggableContainer,
row: DraggableBodyRow,
},
}}
/>
</Form>
);
};
export default App;
表格拖拽和可编辑行功能
最新推荐文章于 2024-02-05 12:58:40 发布