What I want is an example about how to make the drag and drop of my Table that works properly, but I cannot figure out how to make it works in (functional ponents)
My code :
function Preview() {
const { name } = useParams();
const [fieldsOfForm, setFieldsOfForm] = useState([]);
const [selectedForm, setSelectedForm] = useState([]);
const columns = [
{
title: 'Posição',
dataIndex: 'pos',
width: 30,
className: 'drag-visible',
render: () =>
<MenuOutlined style={{ cursor: 'grab', color: '#999' }}/>
},
{
title: "Form Name",
dataIndex: "field",
key: "field",
render: (text) => <a>{text}</a>,
},
{
title: "Tipo",
dataIndex: "fieldtype",
key: "fieldtype",
},
];
useEffect(() => {
let mounted = true;
let loadingStates = loading;
if (mounted) {
setFieldsOfForm(location.state);
loadingStates.allFields = false;
setLoading(false);
}
return () => (mounted = false);
}, [selectedForm]);
return (
//Some jsx....
<Row gutter={1}>
<Col span={1}></Col>
<Table dataSource={fieldsOfForm}
columns= {columns}/>
</Row>
// More jsx...
);
}
export default Preview;
Everything that I found on internet about this drag and drop from the lib of antd is in class ponent , but I wanted to make it works in my functional one.
Example that I found : multi row drag-able table (antd)
I want some example in function ponent if someone has tried it already and could help me ?
What I want is an example about how to make the drag and drop of my Table that works properly, but I cannot figure out how to make it works in (functional ponents)
My code :
function Preview() {
const { name } = useParams();
const [fieldsOfForm, setFieldsOfForm] = useState([]);
const [selectedForm, setSelectedForm] = useState([]);
const columns = [
{
title: 'Posição',
dataIndex: 'pos',
width: 30,
className: 'drag-visible',
render: () =>
<MenuOutlined style={{ cursor: 'grab', color: '#999' }}/>
},
{
title: "Form Name",
dataIndex: "field",
key: "field",
render: (text) => <a>{text}</a>,
},
{
title: "Tipo",
dataIndex: "fieldtype",
key: "fieldtype",
},
];
useEffect(() => {
let mounted = true;
let loadingStates = loading;
if (mounted) {
setFieldsOfForm(location.state);
loadingStates.allFields = false;
setLoading(false);
}
return () => (mounted = false);
}, [selectedForm]);
return (
//Some jsx....
<Row gutter={1}>
<Col span={1}></Col>
<Table dataSource={fieldsOfForm}
columns= {columns}/>
</Row>
// More jsx...
);
}
export default Preview;
Everything that I found on internet about this drag and drop from the lib of antd is in class ponent , but I wanted to make it works in my functional one.
Example that I found : multi row drag-able table (antd)
I want some example in function ponent if someone has tried it already and could help me ?
Share Improve this question edited Jan 13, 2022 at 19:03 Shoyeb Memon 1,1591 gold badge12 silver badges27 bronze badges asked Jan 12, 2022 at 17:18 Guilherme CavenaghiGuilherme Cavenaghi 2451 gold badge4 silver badges22 bronze badges1 Answer
Reset to default 5Here's a functional working example:
import React from "react";
import "antd/dist/antd.css";
import { Table } from "antd";
import {
sortableContainer,
sortableElement,
sortableHandle
} from "react-sortable-hoc";
import { MenuOutlined } from "@ant-design/icons";
const data = [
{
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
},
{
key: "4",
name: "4",
age: 32,
address: "New York No. 1 Lake Park",
index: 3
},
{
key: "5",
name: "5",
age: 42,
address: "London No. 1 Lake Park",
index: 4
},
{
key: "6",
name: "6",
age: 32,
address: "Sidney No. 1 Lake Park",
index: 5
}
];
const DragHandle = sortableHandle(({ active }) => (
<MenuOutlined style={{ cursor: "grab", color: active ? "blue" : "#999" }} />
));
const SortableItem = sortableElement((props) => <tr {...props} />);
const SortableContainer = sortableContainer((props) => <tbody {...props} />);
function SortableTable() {
const [dataSource, setDataSource] = React.useState(data);
const [selectedItems, setSelectedItems] = React.useState([]);
const getColumns = () => {
return [
{
title: "Sort",
dataIndex: "",
width: 30,
className: "drag-visible",
render: (d, dd, i) => (
<>
<DragHandle active={selectedItems.includes(i)} />
</>
)
},
{
title: "Name",
dataIndex: "name",
className: "drag-visible"
},
{
title: "Age",
dataIndex: "age"
},
{
title: "Address",
dataIndex: "address"
}
];
};
const merge = (a, b, i = 0) => {
let aa = [...a];
return [...a.slice(0, i), ...b, ...aa.slice(i, aa.length)];
};
const onSortEnd = ({ oldIndex, newIndex }) => {
let tempDataSource = dataSource;
if (oldIndex !== newIndex) {
if (!selectedItems.length) {
let movingItem = tempDataSource[oldIndex];
tempDataSource.splice(oldIndex, 1);
tempDataSource = merge(tempDataSource, [movingItem], newIndex);
} else {
let filteredItems = [];
selectedItems.forEach((d) => {
filteredItems.push(tempDataSource[d]);
});
let newData = [];
tempDataSource.forEach((d, i) => {
if (!selectedItems.includes(i)) {
newData.push(d);
}
});
tempDataSource = [...newData];
tempDataSource = merge(tempDataSource, filteredItems, newIndex);
}
setDataSource(tempDataSource);
setSelectedItems([]);
}
};
const DraggableContainer = (props) => (
<SortableContainer
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 = dataSource.findIndex(
(x) => x.index === restProps["data-row-key"]
);
return (
<SortableItem
index={index}
{...restProps}
selected={selectedItems.length}
onClick={(e) => {
if (e.ctrlKey || e.metaKey) {
selectedItems.includes(index)
? selectedItems.splice(selectedItems.indexOf(index), 1)
: selectedItems.push(index);
setSelectedItems(selectedItems);
} else {
setSelectedItems([]);
}
}}
/>
);
};
return (
<>
<h3>"CNTRL + Click" to select multiple items</h3>
<Table
pagination={false}
dataSource={dataSource}
columns={getColumns()}
rowKey="index"
ponents={{
body: {
wrapper: DraggableContainer,
row: DraggableBodyRow
}
}}
/>
{selectedItems.length ? <>{selectedItems.length} items selected </> : ""}
</>
);
}
You can play with it in Sandbox