React-sortable-hoc: How to sortable with the <tr> table

Created on 30 Mar 2018  路  10Comments  路  Source: clauderic/react-sortable-hoc

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

Most helpful comment

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

All 10 comments

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

Still getting this issue. Ideally, want a purely CSS solution without having to do _stuff_ onSortStart 馃

Saying that though, @zhaoyao91 answer works perfectly!

Was this page helpful?
0 / 5 - 0 ratings