Monday, October 8, 2018

Migrating from Dragula to Shopify/Draggable/Sortable

In the following code snippets the variable draggable refers to a Draggable.Sortable instance.
You can also check out the fiddle.

Add revertOnSpill functionality to Sortable

var outContainer;
draggable.on('drag:out:container', (e) => {
 outContainer = e.data.overContainer;
});
draggable.on('sortable:stop', (e) => {
 var newContainer = e.data.newContainer;
  var spill = outContainer && outContainer === newContainer;
  if (spill) {
    var oldContainer = e.data.oldContainer;
    var oldContainerChildren = draggable.getDraggableElementsForContainer(oldContainer);
    var emptyOldContainer = !oldContainerChildren.length;
    var source = e.data.dragEvent.data.source;
    if (emptyOldContainer) {
     oldContainer.appendChild(source);
    } else {
      var oldIndex = e.data.oldIndex;
     oldContainer.insertBefore(source, oldContainer.children[oldIndex]);
    }    
  }
});

Figuring out Dragula library usage

The library in use: https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.2/dragula.js
plus its CSS: https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.2/dragula.css

Default configuration

HTML body content

<ul class="container">
<li class="draggable">1</li>
<li class="draggable">2</li>
<li class="draggable">3</li>
</ul>
<ul class="container">
<li class="draggable">1</li>
<li class="draggable">2</li>
<li class="draggable">3</li>
</ul>
<ul class="container">
<li class="draggable">1</li>
<li class="draggable">2</li>
<li class="draggable">3</li>
</ul>

JavaScript content

var containers = Array.prototype.slice.call(document.querySelectorAll('.container'));
var drake = window.dragula(containers);

How it looks like

With its CSSWithout its CSS
See the fiddle for yourself!

Figuring out Shopify/Draggable/Sortable library usage

The library in use: https://cdn.jsdelivr.net/npm/@shopify/draggable@1.0.0-beta.8/lib/draggable.bundle.js

Default configuration

The following plugins come with Draggable by default:
  • Announcement - announcing draggable events for a screenreader.
  • Focusable - adds tabindex to all draggable and container elements and thus makes them focusable
  • Mirror - creates a similar element to the original that will follow the cursor
  • Scrollable - scrolls the container while dragging when container edge is reached
Sortable is built on top of Draggable, so it has also all of this.

HTML body content

<ul class="container">
<li class="draggable">1</li>
<li class="draggable">2</li>
<li class="draggable">3</li>
</ul>
<ul class="container">
<li class="draggable">1</li>
<li class="draggable">2</li>
<li class="draggable">3</li>
</ul>
<ul class="container">
<li class="draggable">1</li>
<li class="draggable">2</li>
<li class="draggable">3</li>
</ul>

JavaScript content

var containers = document.querySelectorAll('.container');
var draggable = new window.Draggable.Sortable(containers, {
  draggable: '.draggable'
});

How it looks like

See the fiddle for yourself!