Good drag & drop library?


#1

Hi guys, I’m looking for a good drag & drop support for my app that will run in a Cordova app and desktop browsers. I’m targeting newer browsers, so it does not have to support legacy browsers (i.e. older IE versions).

Here’s my requirements:

  • Enable and disable drag & drop on source items
  • While dragging the source item around, show a copy (shadow) of it under the cursor (i.e. don’t drag the original object). This shadow should show up instantly, i.e. there should not be any noticable delay when starting the drag.
  • Allow that shadow to be dragged everywhere on screen, i.e. don’t limit its movement to the borders of the original item’s parent object
  • Define drop regions that react if the shadow overs over them.
  • It should also be possible to transform the shadow if it hovers over a drop target. As my source objects are rather big (300x200px), but my drop targets are rather small, I want to shrink the shadow on hovering. I also want to be able to modify the drop target in this case. Sample: If I drag a file object over a folder object, I want this folder to open after some seconds of hovering.
  • I want to implement the behaviours of the shadow and drop zones on my own, i.e. the framework should not be opiniated on this. I only need event hooks for that.
  • All of this should run smoothly on mobile devices and hence support touch events as well as mouse events.
  • It should also use HTML5 drag & drop, if supported by the browser, for best performance.
  • Last but not least, it would be nice to have a “sortable” feature, so that the library can also be used to move items around in relation to sibling items, like “Sortable” does. But for my use-case, this is not a must-have, since there are a lot of libraries which are doing this well.

I’ve tried a lot of libraries, but none of them satisfied all of these criteria.

  • Dragula came closest, but it is quite opinionated on how it treats the drop behaviour. It took me many “hacks” to simulate what I need (e.g. by setting dropped objects to display:none), and I don’t think these hacks are really good.
  • interact.js is a great low-level framework for implementing such behaviour, but you have to implement a lot of the basic drag functionality yourself (like: generating shadow images, showing these objects while dragging etc.). If I should not find a decent out-of-the-box solution, I will surely go this way. I’m already using it to implement a tap-hold-behaviour.
  • Dragabilly ran smooth, but it does not allow to copy the source item and move it freely on the page.
  • Pep doesn’t seem to copy the source item either, but I haven’t tried this out in practice so far.

Thanks for any tips where to find good alternatives to those mentioned above.

EDIT: I’ve now also tested [ios-html5-drag-drop-shim] (https://github.com/timruffles/ios-html5-drag-drop-shim). Worked on iOS, but did break any interactivity with image-based buttons on Android Lollipop (if you enable this shim, all images become draggable, and all other events are prevented).


#3

It’s hard to advice on this one because you want it not too low-level but also not too opinionated. Maybe you should make a more clear decision on the direction you want suggestions.


#4

Ok, I think it’s ok if the library is opinionated, as long as it supports drag and drop without inserting the source object at the target automatically. That’s the only thing I am missing in Dragula. There is no way to prevent that the source element will be copied (or moved) to the target.


#5

Because Meteor will also add it by itself? You run into a conflict there? You want Meteor to render it?

In that case you will get into the need of modifying the original script. Thing is that with Javascript it’s quite easy to do. I don’t know the Dragula thing but generally you can overwrite such a method quite easy.

In general all those scripts will have a copy and drop structure because that’s needed to make it work in plain JS. They do actually have a version for angular which contains so changes on that drop functionality: https://github.com/bevacqua/angular-dragula#special-events-for-angular-dragula so maybe you could just see what they change and create a blaze version of it.


#6

No, I don’t want to render anything at all. My use-case is to drop something on a target to execute an action. So it’s more something like this: http://tympanus.net/Development/DragDropInteractions/


#7

Quick fix? Just hide it? .container > .droppedElement {display: none} ?


#8

Yes, that’s what I actually did with Dragula. But that feels a bit “ugly”, makes the page larger than necessary and causes unneccessary DOM operations. As the app will run on mobile devices, I would prefer to have everything as slim as possible. That’s why I was looking for a solution that would better fit to my use-case instead of “tweaking” Dracula to its extremes :slight_smile:


#9

For that specific package only solution would be an override or just removing the elements off course afterwards. It’s not a very expensive operation and a user will not likely drag thousands of elements quickly after each other.


#10

Yes, maybe you’re right and I’m too cautious…


#11

Did you take a look at https://github.com/RubaXa/Sortable ?


#12

Yes, I did. But this is meant for sorting elements.


#13

i think it’s a good thing you want quality but working results are sometimes even more important. Depends on your case to focus deep onto it or just accept.