app-base-web
Version:
web development common base package.
197 lines (183 loc) • 4.64 kB
JavaScript
import React, { useContext, useState, useEffect, useRef } from 'react';
import { Table, Input, Button, Popconfirm, Form } from 'antd';
import { EditOutlined } from '@ant-design/icons';
const EditableContext = React.createContext();
const EditableRow = ({ index, ...props }) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};
const EditableCell = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef();
const form = useContext(EditableContext);
useEffect(() => {
if (editing) {
inputRef.current.focus();
}
}, [editing]);
const toggleEdit = () => {
setEditing(!editing);
form.setFieldsValue({
[dataIndex]: record[dataIndex],
});
};
const save = async e => {
try {
const values = await form.validateFields();
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}
>
<Input ref={inputRef} onPressEnter={save} onBlur={save} />
</Form.Item>
) : (
<div
style={{
paddingRight: 24,
display:'flex',
alignItems: 'center',
justifyContent: 'space-between'
}}
onClick={toggleEdit}
>
{children}
<EditOutlined />
</div>
);
}
return <td {...restProps}>{childNode}</td>;
};
export default class EditableTable extends React.Component {
constructor(props) {
super(props);
this.columns = [
{
title: 'key',
dataIndex: 'paramKey',
width: '40%',
editable: true,
},
{
title: 'value',
dataIndex: 'paramValue',
width: '40%',
editable: true,
},
{
title: '操作',
dataIndex: 'operation',
width: '20%',
render: (text, record) =>
this.state.dataSource.length >= 1 ? (
<Popconfirm title="确定删除吗?" onConfirm={() => this.handleDelete(record.key)}>
<a>删除</a>
</Popconfirm>
) : null,
},
];
this.state = {
dataSource: this.props.dataSource?this.props.dataSource:[],
count: this.props.dataSource?this.props.dataSource.length:0,
};
}
handleDelete = key => {
const dataSource = [...this.state.dataSource];
this.setState({
dataSource: dataSource.filter(item => item.key !== key),
});
};
handleAdd = () => {
const { count, dataSource } = this.state;
const newData = {
key: count,
paramKey: "",
paramValue: "",
};
this.setState({
dataSource: [...dataSource, newData],
count: count + 1,
});
};
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() {
console.log('this.state.dataSource',this.state.dataSource)
const { dataSource } = this.state;
const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const columns = this.columns.map(col => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: record => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave: this.handleSave,
}),
};
});
return (
<div>
<Button
onClick={this.handleAdd}
type="primary"
style={{
marginBottom: 16,
}}
>
新增行
</Button>
<Table
components={components}
rowClassName={() => 'editable-row'}
bordered
dataSource={dataSource}
columns={columns}
//去掉分页
pagination={ false }
scroll={{ y: 300 }}
/>
</div>
);
}
}