Lightweight JS Sorting Library with Native HTML5 Drag and Drop – SortableJS

Category: Drag & Drop , Javascript , Recommended | April 21, 2019
Author: SortableJS
Views Total: 7,246
Official Page: Go to website
Last Update: April 21, 2019
License: MIT

Preview:

Lightweight JS Sorting Library with Native HTML5 Drag and Drop – SortableJS

Description:

Sortable is a lightweight and simple javascript library that makes a list of items sortable by using native Html5 drag and drop API. Works with all the modern browsers and touch devices.

Installation:

# NPM
$ npm install sortablejs --save

How to use it:

Create a list of items on the page.

<ul id="foo">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ul>

Include Sortable.js script at the bottom of your page to reduce the page load time.

<script src="Sortable.js"></script>

The javascript to enable the Sortable.

var el = document.getElementById('foo');
new Sortable(el, {
    group: "words",
    handle: ".my-handle",
    draggable: ".item",
    ghostClass: "sortable-ghost",
    onAdd: function (evt){
      var itemEl = evt.item;
    },
    onUpdate: function (evt){
      var itemEl = evt.item; // the current dragged HTMLElement
    },
    onRemove: function (evt){
      var itemEl = evt.item;
    }
});

4. All possible options with default values.

new Sortable(el, {

    // name: String — group name
    // pull: true|false|["foo", "bar"]|'clone'|function — ability to move from the list. clone — copy the item, rather than move. Or an array of group names which the elements may be put in. Defaults to true.
    // put: true|false|["baz", "qux"]|function — whether elements can be added from other lists, or an array of group names from which elements can be added.
    // revertClone: boolean — revert cloned element to initial position after moving to a another list.
    group: "name",  // or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }

    // enable sorting
    sort: true,  

    // time to wait before the sorting should start
    delay: 0

    // enable delay on touch
    delayOnTouchOnly: false,

    // how many pixels the point should move before cancelling a delayed drag event
    touchStartThreshold: 0, 

    // disables the sortable if set to true.
    disabled: false, 

    // save and restore the sort.
    store: null,

    // animation speed
    animation: 150,

    // easing function
    easing: "cubic-bezier(1, 0, 0, 1)", 

    // drag handle
    handle: ".my-handle",

    // filter selector
    filter: ".ignore-elements", 

    // preverntDefault when filtering
    preventOnFilter: true,

    // draggable element
    draggable: ".item",

    // drop placeholder
    ghostClass: "sortable-ghost",

    // chosen class
    chosenClass: "sortable-chosen",

    // dragging class
    dragClass: "sortable-drag",

    // default data attribute
    dataIdAttr: 'data-id',

    // threshold of the swap zone
    swapThreshold: 1,

    // invert swap
    invertSwap: false,

    // threshold of the inverted swap zone
    invertedSwapThreshold: 1,

    // will be detected automatically if not given
    direction: 'horizontal',

    // ignore the HTML5 DnD behaviour
    forceFallback: false,

    // fallback class
    fallbackClass: "sortable-fallback",

    // appends the cloned DOM Element into the document body
    fallbackOnBody: false,  

    // how far the mouse should move before it's considered as a drag.
    fallbackTolerance: 0, 

    // or HTMLElement
    scroll: true, 

    // custom scroll function
    scrollFn: function(offsetX, offsetY, originalEvent, touchEvt, hoverTargetEl) { ... }, 

    // how near the mouse must be to an edge to start scrolling.
    scrollSensitivity: 30,

    // scroll speed in px
    scrollSpeed: 10,

    // auto scroll
    bubbleScroll: true,

    dragoverBubble: false,

    // remove the cloned element when it is not showing
    removeCloneOnHide: true, 

    // distance mouse must be from empty sortable to insert drag element into it
    emptyInsertThreshold: 5, // px, 

    // set data
    setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {
      dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent
    }
    
});

Callback functions.

new Sortable(el, {

    // Element is chosen
    onChoose: function (/**Event*/evt) {
      evt.oldIndex;  // element index within parent
    },

    // Element is unchosen
    onUnchoose: function(/**Event*/evt) {
      // same properties as onEnd
    },

    // Element dragging started
    onStart: function (/**Event*/evt) {
      evt.oldIndex;  // element index within parent
    },

    // Element dragging ended
    onEnd: function (/**Event*/evt) {
      var itemEl = evt.item;  // dragged HTMLElement
      evt.to;    // target list
      evt.from;  // previous list
      evt.oldIndex;  // element's old index within old parent
      evt.newIndex;  // element's new index within new parent
      evt.clone // the clone element
      evt.pullMode;  // when item is in another sortable: `"clone"` if cloning, `true` if moving
    },

    // Element is dropped into the list from another list
    onAdd: function (/**Event*/evt) {
      // same properties as onEnd
    },

    // Changed sorting within list
    onUpdate: function (/**Event*/evt) {
      // same properties as onEnd
    },

    // Called by any change to the list (add / update / remove)
    onSort: function (/**Event*/evt) {
      // same properties as onEnd
    },

    // Element is removed from the list into another list
    onRemove: function (/**Event*/evt) {
      // same properties as onEnd
    },

    // Attempt to drag a filtered element
    onFilter: function (/**Event*/evt) {
      var itemEl = evt.item;  // HTMLElement receiving the `mousedown|tapstart` event.
    },

    // Event when you move an item in the list or between lists
    onMove: function (/**Event*/evt, /**Event*/originalEvent) {
      // Example: https://jsbin.com/nawahef/edit?js,output
      evt.dragged; // dragged HTMLElement
      evt.draggedRect; // DOMRect {left, top, right, bottom}
      evt.related; // HTMLElement on which have guided
      evt.relatedRect; // DOMRect
      evt.willInsertAfter; // Boolean that is true if Sortable will insert drag element after target by default
      originalEvent.clientY; // mouse position
      // return false; — for cancel
      // return -1; — insert before target
      // return 1; — insert after target
    },

    // Called when creating a clone of element
    onClone: function (/**Event*/evt) {
      var origEl = evt.item;
      var cloneEl = evt.clone;
    },

    // Called when dragging element changes position
    onChange: function(/**Event*/evt) {
      evt.newIndex // most likely why this event is used is to get the dragging element's current index
      // same properties as onEnd
    }

});

Changelog:

v1.9.0 (04/21/2019)

  • Use real event properties when doing empty insert
  • Fixed _lastChild failing to ignore display:none
  • Stricter requirements for supportPointer
  • Better fix for unwanted IE event capturing
  • Optimize nearestEmptyInsertDetectEvent callback
  • Added oldDraggableIndex + newDraggableIndex
  • Detect for empty insert always if not inserted
  • Fix infinite loop in detecting shadow DOM
  • Improved repaint trigger
  • Fixed delay option on Android
  • Added delayOnTouchOnly option

v1.8.4 (03/11/2019)

  • Automatic direction detection for grids
  • Better cross-browser compatibility for delay option
  • Fixed text selection in fallback on MacOS Safari
  • Fixed auto-scrolling in MacOS Safari
  • Added compensation for Chrome’s adjustment of scroll position if swapped element is out of viewport
  • Added pullMode to event object
  • Improved detection of empty sortables
  • Fixed setting of ghostClass, as well as animating items only after clones are shown

You Might Be Interested In:


Leave a Reply