react-sortable-hoc icon indicating copy to clipboard operation
react-sortable-hoc copied to clipboard

How to sortable with the <tr> table

Open vxba opened this issue 6 years ago • 13 comments

I'm trying to sort the tr of the table, it can sorting but the SortableGhost display not correctly.

vxba avatar Mar 30 '18 11:03 vxba

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.

darkrift avatar Jul 03 '18 17:07 darkrift

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 */
  }
}

MartinsLapsa avatar Aug 01 '18 07:08 MartinsLapsa

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 avatar Sep 12 '18 17:09 christiangenco

@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 avatar Sep 28 '18 17:09 samharad

@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.

christiangenco avatar Oct 01 '18 18:10 christiangenco

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}
  ...
/>;

tohu12 avatar Mar 12 '19 08:03 tohu12

+1 to @christiangenco's idea of "append[ing] the cloned sorted element as a sibling of the original instead of on the body."

Dpetters avatar Jun 27 '19 16:06 Dpetters

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.

p-himik avatar Jul 17 '19 19:07 p-himik

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 trs 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

zhaoyao91 avatar Aug 28 '20 14:08 zhaoyao91

Still getting this issue. Ideally, want a purely CSS solution without having to do stuff onSortStart 🤔

Saying that though, @zhaoyao91 answer works perfectly!

jtsalva avatar Feb 11 '21 16:02 jtsalva

Works fine for me!

Screenshot 2022-01-09 at 10 25 13

now i need to fix the even and odd css

ruijadom avatar Jan 09 '22 10:01 ruijadom

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.

  1. 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.

  1. 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 because tr on drag has position: fixed. Does anyone know a better way to keep cells width when the row has position: fixed?

dennis-8 avatar Jun 19 '22 17:06 dennis-8

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 trs 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

Much thanks sir, you saved my day.

zhihongzhong avatar Nov 28 '22 07:11 zhihongzhong