marcojakob / dart-dnd

Drag and Drop for Dart web apps with mouse and touch support.
https://code.makery.ch/library/dart-drag-and-drop/
MIT License
136 stars 91 forks source link

Please add drag&drop reordering #2

Closed Emasoft closed 10 years ago

Emasoft commented 10 years ago

Wow, this must be one of the best drag&drop library ever! Only one request: can you support a drag&drop reordering of vertical (or horizontal) lists of elements? For example if I want to move an element from the position 4 of the list to the position 10, it should be able to do it in the following ways:

Also those features should be useful: REALTIME REORDERING WHILE WE DRAG: dragging an element or a group of elements above the list should animate the list showing the auto reordering of the list in case the element is dropped at the current point. MULTI-COLUMNS / ROWS SUPPORT : drag&drop reordering should work in multi columns or multi rows elements lists, with the possibility to drag&drop between different columns or rows. UNDO: an animation should undo the latest drag&drop reordering

marcojakob commented 10 years ago

Thanks.

Actually, I had done something like that before in the old HTML5 dnd library. It is implemented in the sortable.dart file. I took some inspiration from jQuery Sortable and Ali Farhadi's sortable.

For this new library my intention was to create an easy way to detect dragging across mouse and touch and provide some basic functionality. More specific use cases can be built upon this layer.

So, it should all be ready and flexible enough to build reordering functionality like you describe. Here are some rough ideas how it could be done:

  1. Install the elements you want to reorder both as Draggables and Dropzones (I'll have to test if that actually works).
  2. It's probably better to use the CloneAvatarHandler as option on the Draggable. This leaves the original element as it is. Or create your own implementation of an AvatarHandler.
  3. Listen to onDragStart to set the original element into a placeholder like state.
  4. Listen to onDragEnter / onDragLeave to move the placeholder around.
  5. When dropped on an element do the reordering.

It would be great to see multiple versions of reorderings or sortables that are based on this library. As I expect the use cases to be quite diverse, it might be better to keep those in different Dart packages. But maybe we find a good general case that could be included in this package.

Just curious: Guessing from the length of your comment you might have already worked with a few drag and drop solutions. Do you have an application where you need this or you just think it would be great if it were included? If you are working on an app, is it in Dart or JavaScript?

marcojakob commented 10 years ago

I've created a small test example for basic sortable behavior. It was quite easy to do, with just a few lines of code.

See the sortable-test and its source

Emasoft commented 10 years ago

Thank you for the sample. It's useful but still not quite what I need. I'm working on a Dart web project for a online preferential voting system. The component can be configure to vote on anything (candidates, things, songs, proposals, bugs, etc.). The system used is the preferential voting, that means using a condorcet method like the Schulze method ( http://en.wikipedia.org/wiki/Schulze_method ). An example of this is the voting system implemented by the popular Liquid Feedback direct democracy software:

http://blog.liquidfeedback.org/lqfb/preferential_voting/

The system works by having 5 "baskets":

-Full Approval -Partial Approval -Neutral -Partial Disapproval -Full Disapproval

In those 5 containers the user should Drag&Drop the various candidates (proposals, things, anything...) taking them from a sixth basket, called "Unsorted Candidates". Each basket is nothing but a list. The 5 baskets are vertical lists, while the sixth basket is an horizontal list.

The Drag&Drop part is needed to:

When all the elements are in the 5 baskets and the Unsorted basket is empty, you can press OK and your preferential vote will be casted, generating a list of sorted and weighted preferences that would be used to compute not the most voted candidate but the candidate that has the best approval rating according to the Schulze method.

What I need is maybe a generic Dart container element (possibly a skinnable polymer dart component), capable of automatically accepting dropped elements and automatically reordering any valid html element you put inside it (other divs, images, text labels, svg icons, etc.), and able to return a current index of the elements. The various behaviours I mentioned should be configurable for each container (INSERT AFTER, INSERT BEFORE, SWITCH, GROUP INSERT, GROUP INSERT AFTER, GROUP SWITCH), and to keep the entire list of candidates visibles a multicolumn option should be available. With multicolumns the user would not be forced to drag an element all the way down and up scrolling the web page in long lists with thousands of candidates. A difficult task, especially on Touch devices like iPhone or Ipad.

marcojakob commented 10 years ago

Sounds like an interesting project. Obviousely, I can't provide a solution for all the things you need. But let me know if and how the dnd library plays a part in your project. It would also be great if you design code on top of dnd like reordering if you could share it.