react-sortable-hoc
react-sortable-hoc copied to clipboard
How to sortable with the <tr> table
I'm trying to sort the tr of the table, it can sorting but the SortableGhost display not correctly.
I'm having the same issue, I added a css rule "body > tr { display: table !important; }" to cope for that issue. The rendering is not perfect, but it's closer to what it should look like.
Just use helperClass
prop to add a class to dragging item to style it the same way as your table.
.sorting-row {
td {
/* necessary css rules */
}
}
I had this problem specifically with Bootstrap tables. I fixed it with a combination of @MartinsLapsa's and @darkrift's answers:
body > tr {
display: table !important;
td {
padding: 8px;
line-height: 1.428571429;
vertical-align: top;
border-top: 1px solid #ddd;
}
}
This is happening because Bootstrap's CSS rules are only applying to the td
and tr
when they're inside of a table with class table
:
.table > thead > tr > th,
.table > thead > tr > td,
.table > tbody > tr > th,
.table > tbody > tr > td,
.table > tfoot > tr > th,
.table > tfoot > tr > td {
padding: 8px;
line-height: 1.428571429;
vertical-align: top;
border-top: 1px solid #ddd;
}
and react-sortable-soc
is cloning the tr
and appending it to the body outside of the .table
, so these CSS rules aren't applying anymore.
@christiangenco: Did you not still have problems with the column widths of the draggable element? I can't figure out how to get appropriate column widths, since they need to be calculated based on the other rows in the table, which aren't taken into consideration when the row is appended to
.
@samharad Ahh yeah, that would be a problem. My table has constant column widths between rows so that wasn't an issue for me.
I think a more general solution here would be to append the cloned sorted element as a sibling of the original instead of on the body.
Hi, my workaround - use onSortStart callback and sets column width for dragged row according to original row:
const handleSortStart = ({ node }) => {
const tds = document.getElementsByClassName("SortableHelper")[0].childNodes;
node.childNodes.forEach(
(node, idx) => tds[idx].style.width = `${node.offsetWidth}px`
);
};
<SortableTable
helperClass="SortableHelper"
onSortStart={handleSortStart}
...
/>;
+1 to @christiangenco's idea of "append[ing] the cloned sorted element as a sibling of the original instead of on the body."
It is possible to do so with helperContainer
. However, it does not solve all problems. At least in my case, rows where there's empty space inside columns still get squished because of display: fixed;
. I have no idea why though.
Thanks for all the clues above. My current workarrount is:
First, set the width of every colum onSortStart:
({ node, helper }: any) => {
node.childNodes.forEach((td: HTMLTableDataCellElement, index: number) => {
helper.childNodes[index].style.width = `${td.offsetWidth}px`;
});
}
Then, add helperClass
like dragging
Then, set helperContainer
to the tbody
of the table (since all my tr
s are inside the tbody
)
Then, set the css of class dragging
to
display: table;
// keep it as the your table table
table-layout: fixed;
That's it
Still getting this issue. Ideally, want a purely CSS solution without having to do stuff onSortStart
🤔
Saying that though, @zhaoyao91 answer works perfectly!
Works fine for me!
![Screenshot 2022-01-09 at 10 25 13](https://user-images.githubusercontent.com/11139970/148678363-852f6e4d-26e2-4e95-adb3-9b2954308e46.png)
now i need to fix the even and odd css
In my case the sortable row is:
const SortableRow = SortableElement((props) => ( <Row value={props.value} /> ));
It's possible to make the tr
sorting look better.
- use SortableContainer's
helperContainer
.
My table has a tbody and I'm using useRef to get a ref to tbody and use it in helperContainer
.
This means the dragged row will be added to the tbody
of sortable table, and not added to document's body
.
- Set all cells width to
inherit
. Some cells (td
) unexpectedly grow, they will need to have a width set in pixels. I think the cells lose their width becausetr
on drag hasposition: fixed
. Does anyone know a better way to keep cells width when the row hasposition: fixed
?
Thanks for all the clues above. My current workarrount is:
First, set the width of every colum onSortStart:
({ node, helper }: any) => { node.childNodes.forEach((td: HTMLTableDataCellElement, index: number) => { helper.childNodes[index].style.width = `${td.offsetWidth}px`; }); }
Then, add
helperClass
likedragging
Then, set
helperContainer
to thetbody
of the table (since all mytr
s are inside thetbody
)Then, set the css of class
dragging
todisplay: table; // keep it as the your table table table-layout: fixed;
That's it
Much thanks sir, you saved my day.