
dragula.js is a simple, dependency-free, touch-enabled JavaScript library that provides drag and drop functionality on DOM elements.
Install & Download
# NPM $ npm i dragula --save
Basic usage:
1. Load the dragula.js JS library at the end of the document.
<link href="dist/dragula.min.css" rel="stylesheet" /> <script src="dist/dragula.min.js"></script>
2. Create two containers that you can move stuff between these two containers.
<div class="wrapper">
<div id="left" class="container">
<div>Item 1.</div>
<div>Item 2.</div>
<div>Item 3.</div>
<div>Item 4.</div>
</div>
<div id="right" class="container">
<div>Item 5.</div>
<div>Item 6.</div>
<div>Item 7.</div>
</div>
</div>3. Enable the drag and drop on these two lists. That’s it.
dragula([document.querySelector('#left'), document.querySelector('#right')]);4. Config the drag and drop behavior by passing the options object as the second object to the dragula method:
dragula([document.querySelector('#left'), document.querySelector('#right')],{
// or 'horizontal'
direction: 'vertical',
// determine whether to copy elements rather than moving
// if a method is passed, it'll be called whenever an element starts being dragged in order to decide whether it should follow copy behavior or not.
copy: false,
// determine whether to sort elements in copy-source containers.
copySortSource: false,
// spilling will put the element back where it was dragged from, if this is true
revertOnSpill: false,
// spilling will `.remove` the element, if this is true
removeOnSpill: false,
// set the element that gets mirror elements appended
mirrorContainer: document.body,
// allows users to select input text
ignoreInputTextSelection: true,
// allows users to select the amount of movement on the X axis before it is considered a drag instead of a click
slideFactorX: 0,
// allows users to select the amount of movement on the Y axis before it is considered a drag instead of a click
slideFactorY: 0,
// only elements in drake.containers will be taken into account
isContainer: function (el) {
return false;
},
// elements are always draggable by default
moves: function (el, source, handle, sibling) {
return true;
},
// elements can be dropped in any of the `containers` by default
accepts: function (el, target, source, sibling) {
return true;
},
// don't prevent any drags from initiating by default
invalid: function (el, handle) {
return false;
}
});5. API methods.
var drake = dragula({
// options here
});
// add new containers
drake.containers.push(container);
// determine if an element is dragging
drake.dragging
// enter drag mode without a shadow
drake.start(item);
// gracefully end the drag event
drake.end();
// gracefully cancel the drag action
drake.cancel(revert);
// gracefully remove a dragging element from the DOM
drake.remove();
// return whether the drake instance can accept drags for a DOM element item.
drake.canMove(item);
// destroy the instance
drake.destroy();6. Event handlers.
drake.on('drag', function(el, source){
// do something
});
drake.on('dragend', function(el){
// do something
});
drake.on('drop', function(el, target, source, sibling){
// do something
});
drake.on('cancel', function(el, container, source){
// do something
});
drake.on('remove', function(el, container, source){
// do something
});
drake.on('shadow', function(el, container, source){
// do something
});
drake.on('over', function(el, container, source){
// do something
});
drake.on('out', function(el, container, source){
// do something
});
drake.on('cloned', function(clone, original, type){
// do something
});Changelog:
v3.7.3 (10/03/2020)
- Changed to NPM.
09/12/2016
- Fixed Bug when revert on spill and drag a copy item








Poor documentation, too confusing, too convoluted.
Two Fundamental Problems – 1. How do you UNDO and 2. how do you bring back a box of items if I remove ALL the items from one of the boxes