fixed-data-table-2 icon indicating copy to clipboard operation
fixed-data-table-2 copied to clipboard

Dragging and dropping rows within fixed data table.

Open MattJonesCreation opened this issue 8 years ago • 13 comments

Is there a preferred react drag and drop library used to implement drag and drop inside of a fixed data table?

I've been having trouble finding an example of this functionality within any FDT.

MattJonesCreation avatar Jan 03 '17 17:01 MattJonesCreation

We've implemented our own solution, but any of them should work. The cell element is very dynamic and works with most everything.

Can you share a fiddle with a WIP so we can help debug it?

KamranAsif avatar Jan 09 '17 14:01 KamranAsif

Thanks for your answer @KamranAsif !

I've been able to successfully use react-dnd to drag cell elements. I'm looking more for the ability to drag entire rows. That is without having to make each individual cell element it's own drag source.

Since FDT are constructed Table -> Column -> Cell, I haven't been able to work with any row element. Thus, my drag and drop solution feels very ad hoc to me.

Is your drag and drop solution using cells (then selecting the associated row) to do drag rows or is it only interested in dragging the individual cells?

MattJonesCreation avatar Jan 09 '17 14:01 MattJonesCreation

Ah I see. We only support dragging cells at the moment. Can you throw up a quick POC of react-dnd working with a cell so I can have a better understanding of how it works?

KamranAsif avatar Jan 09 '17 15:01 KamranAsif

Here is a POF of react-dnd working with a cell for the dragging portion. I left out the Target Cell but this should be enough to see the dragging of the cell component.

import ReactDOM from 'react-dom';
import {Table, Column, Cell} from 'fixed-data-table';
import { DragDropContext, DragSource} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';

/* Item Types */
var ItemTypes = {
  CELL: 'cell'
};

/* Drag source specification */
var source = {
  // Required. Return back the dragged item if necessary.
  beginDrag: function (props, monitor, component) {
  	console.log("beginning drag");
    return { };
  }, 

  // Actually call the vehicle action to make the assignment
  endDrag: function (props, monitor, component) {
  	if (!monitor.didDrop()) {
      // You can check whether the drop was successful
      // or if the drag ended but nobody handled the drop
      return;
    }
  	
  	// Get the dragged cell and target cell 
  	var draggedCell = monitor.getItem();
  	var targetCell = monitor.getDropResult();

  	// Good time to call flux action
  }
};

/* Collection function, needs to know if a row is dragging or not */
function collect(connect, monitor) {
  return {
    connectDragSource: connect.dragSource(),
    connectDragPreview: connect.dragPreview(),
    isDragging: monitor.isDragging()
  }
};

// Normal data cell for dragging
var DataCell = React.createClass({
    // Connects this.state in component to this.data in store
    render: function(){
      const {data, rowIndex, col, columnKey, 
            connectDragSource, connectDragPreview, 
            isDragging, ...props} = this.props;

		// If no vehicleData is loaded yet then put in the loading cell
		if (data[rowIndex] === undefined) {
			// Loading cell goes here
			return (<Cell {...props}></Cell>);
		}
		return connectDragSource(
		  <div {...props}><Cell {...props}>{data[rowIndex][col]}</Cell></div>
		);
    }

});


var TableComponent = React.createClass({
    render: function(){
    	var rows = [{Model: 1}, {Model: 2}];

		// Set up the necessary initialization calls for dragging
		var DragDataCell = DragSource(ItemTypes.CELL, source, collect)(DataCell);

		// Return a fixed data table 
		return (			
				<Table			
                rowHeight={30}
				headerHeight={30}
				rowsCount={2}
				width={500}
				height={500}
				{...this.props}>
				<Column
				  header={<Cell>Model</Cell>}
				  cell={<DragDataCell data={rows} col="Model" />}
				  width={175}
				/>
				</Table>
		); 
	}, 
});

var DragTableComponent = DragDropContext(HTML5Backend)(TableComponent);


ReactDOM.render(
  <DragTableComponent />,
  document.getElementById('content')
);

MattJonesCreation avatar Jan 09 '17 16:01 MattJonesCreation

You probably need a column that will initiate your row dragging right? I think you just need to change the preview to be the entire row, which you can get via refs.

If you can throw everything into a JSFiddle I might be able to get it working

KamranAsif avatar Jan 09 '17 16:01 KamranAsif

Awesome, I appreciate this a lot @KamranAsif !

This would be a huge help!

I actually went down this route using the preview functionality and the custom drag layer to try and get the preview to be the row, but I wasn't able to figure out how to add the refs to the FDT row. My workaround for this was to recreate the entire table (with no headers and only the row information).

I'll get you a working JSFiddle as soon as I can.

MattJonesCreation avatar Jan 09 '17 16:01 MattJonesCreation

@KamranAsif Here is a small working jsfiddle.

https://jsfiddle.net/jonesm33/7yudtyt4/1/

MattJonesCreation avatar Jan 10 '17 15:01 MattJonesCreation

Hey,

Looks like react-dnd updated their API a while ago. What I'm thinking is using rowClassNameGetter to assign a unique id to each row. Then, when configuring your drag preview, you can use querySelectorAll to get the desired row.

Thoughts?

KamranAsif avatar Jan 25 '17 16:01 KamranAsif

What I ended up doing was the following: a) Inside of the DragSourceSpecification beginDrag, I return the row using the data and rowindex props from the cell b) Inside of the CustomDragLayer, I now can access this row and create a drag preview that contains a new fixed data table with no headers and one row matching the original row.

MattJonesCreation avatar Jan 25 '17 17:01 MattJonesCreation

Can you add a jsfiddle or a simple example for this, as we need to do sort of the same thing?

danny-larsen avatar Oct 11 '17 08:10 danny-larsen

@jonesm33 im using fixed-data-table-2 i just started to learning row reorder u have done already i tried it's not working for me in new fixed-data-table-2 and DND pls help me on this

kamaldlk avatar Dec 20 '17 11:12 kamaldlk

Is this possible to exclude particular cell which contain react-dnd component? Looks like these 2 features are conflicting.

jk171505 avatar Apr 22 '20 07:04 jk171505

Would anyone be interested in creating a PR with an example of FDT working w/ react DND?

wcjordan avatar May 04 '20 18:05 wcjordan