gregnb / mui-datatables

Datatables for React using Material-UI
MIT License
2.7k stars 931 forks source link

[Feature Suggestion] Draggable Rows #1423

Open trentschnee opened 4 years ago

trentschnee commented 4 years ago

There are often times when people need to draggable rows for their personal projects. For example, some people like to sort rows by a certain sort order. I've noticed that this feature is really something that has to be hard coded into mui-datatables if we want 100% working draggable rows. Furthermore, I've noticed this functionality has been talked about in the "tables" community and this could be a feature that makes developers want to use mui-datatables. With my specific use case, I use react-beautiful-dnd on a customRowRender option, but I am unable to get the provided placeholder to work properly because I don't have control of the tablebody. When I use the tablebody custom component, it re-renders the whole body.

TLDR; It would be awesome to have a draggableRows option :)

Thanks for your time and have a great day.

patorjk commented 4 years ago

I can look into this. The table uses react-dnd for the column dragging, so it would probably use that over react-beautiful-dnd (react-dnd is a little more fine grained). However. row dragging presents a number of issues. Thinking out loud:

  1. Let's say I have a table with 4 rows:

    A
    B
    C
    D

    And I drag a row so the table now looks like this:

    A
    D
    B
    C

    When the table re-renders (due to options changing or it's parent element re-rendering), how will it know to re-render with the new order? Draggable columns solves this by having columnOrder array (which is internal and users don't have to worry about it unless they want to manually set the column order). I suppose a similar rowOrder array could be created (which could be passed to an onRowDragged callback).

  2. Assuming an internal rowOrder array is kept of the row order. What happens when the data in the table changes (for example, rows added or removed)? Does the rowOrder reset? Currently that's how the selectableRows and expandableRows work (ref: https://github.com/gregnb/mui-datatables/blob/master/src/MUIDataTable.js#L847). If the table detects that the data has changed, it's resets the internal selectableRows and expandableRows data (since there's no way to tell if the same data should be selected). Users can override this by inputting in their own selectableRows/expandableRows arrays that they've kept track of through callbacks. The same could be done for rowOrder, it's a rather annoying solution, but logically I'm not sure of a better way.

  3. What happens if a column is sorted? Logically it doesn't seem to make sense to allow a row to be dragged if a column is sorted, but currently, once a column is toggled, it's toggled. The table would need to allow a 3rd click to unsort an array (something like what's described here: https://github.com/gregnb/mui-datatables/issues/1288). Assuming that route is taken, dragging could be setup to only be allowed on unsorted data.

  4. What happens if filters or searchText are applied to the table?

  5. If rowOrder is used for keeping row of the row order, it'd need to be used in other places like the CSV generation.

I will need to think a bit more about this. I think the actual dragging part of the rows is pretty straight forward, it's ironing out some of the other details that makes this tricky.

trentschnee commented 4 years ago

1& 2. The way I am currently keeping track of the sortOrder is by just ordering an array of objects by their sortOrder property. Everytime the state changes it just changes it conveniently for me. I do think having a rowOrder array would be awesome to have! As for the expandableRows, I don't currently use them but I would imagine draggable rows would work with them

  1. I don't think it would mess with the columns, at least it doesn't for me. I will try with my current setup and get back to you and see if it messes with the sortOrder.
  2. Awesome point, I have a filterOpen state and it sets to true when the filter is open. If it is, it disables the drag
  3. CSV generation is something I have not worked with.

side note: I'm not the most experienced programmer in the world but I am really driven and would love to maybe help on this and provide more insight.

atlanteh commented 3 years ago

This is something we need as well and would love to see this implemented in mui-datatabels

ElodieBatista commented 3 years ago

Would love to have this feature too! Any plans on implementing it? Any suggestions on alternative solutions?

wilav-dev commented 1 year ago

I need this feature. I can implement it using another library but need to define customRowRender and don't won't to render the row manually. Any idea?