
An easy-to-use, framework-agnostic drag’n’drop JavaScript library that enables any element to be draggable, droppable, and sortable.
Inspired by jQuery UI and without any 3rd libraries like jQuery.
Table Of Contents:
Installation:
1. Install & Download the package.
# NPM $ npm i agnostic-draggable --save
2. Import the Draggable/Droppable/Sortable components as ES modules.
// draggable
import { Draggable } from 'agnostic-draggable';
// sortable
import { Sortable } from 'agnostic-draggable';
// draggable + droppable
import { Draggable, Droppable } from 'agnostic-draggable';3. Or directly load the agnostic-draggable.min.js JavaScript in the document.
<script src="https://cdn.jsdelivr.net/npm/agnostic-draggable@latest/dist/agnostic-draggable.min.js"></script>
Draggable:
1. Enables an element to be draggable.
<div id="draggable">Drag Me</div>
new Draggable(document.querySelector('#draggable'), {
// options here
}, eventHandlers);2. Available options for Draggable.
new Draggable(document.querySelector('#draggable'), {
// append the draggable element to a specific element
appendTo: 'parent',
// x or y
axis: null,
// connect to a Sortable list
// e.g. '#sort'
connectToSortable: null,
// parent, document, window, a CSS selector or an array of 4 numbers in the form [x1, y1, x2, y2]
containment: null,
// cursor type
cursor: null,
// if the draggable element is disabled
disabled: false,
// distance in pixels that the mouse should move before the dragging should start.
distance: 0,
// snap the dragging helper to a grid
// e.g. [10, 10]
grid: null,
// drag handle element
handle: null,
// original, clone or a function
helper: 'original',
// opacity of the draggable element while being dragged
opacity: null,
// invalid, valid, true, false or a function
revert: false,
// duration in milliseconds
revertDuration: 200,
// used to group sets of Draggable, Droppable and Sortable elements
scope: 'default',
// determine whether the container is scrollable
scroll: true,
scrollSensitivity: 20,
scrollSpeed: 10,
// stack to another element
stack: null,
// ignore these elements
skip: 'input, textarea, button, select, option',
// z-index property
zIndex: null
});3. Available events for Draggable.
new Draggable(document.querySelector('#draggable'), {OPTIONS}, {
'draggable:init ': function (event) {
// do something
},
'drag:start': function (event) {
// do something
},
'drag:move': function (event) {
// do something
},
'drag:stop': function (event) {
// do something
},
'draggable:destroy': function (event) {
// do something
}
});Droppable:
1. Enables an element to be droppable.
<div id="droppable">Drop Here</div>
new Droppable(document.querySelector('#droppable'), {
// options here
}, eventHandlers);2. Available options for Droppable.
new Droppable(document.querySelector('#droppable'), {
// which Draggable elements are accepted
accept: '*',
// disable the Droppable behaviour
disabled: false,
// handle dropping on nested Droppable elements
greedy: false,
// used to group sets of Draggable, Droppable and Sortable elements
scope: 'default',
// fit, intersect, pointer or touch
tolerance: 'intersect'
}, eventHandlers);3. Available events for Droppable.
new Droppable(document.querySelector('#droppable'), {OPTIONS}, {
'droppable:init': function (event) {
// do something
},
'droppable:activate': function (event) {
// do something
},
'droppable:over': function (event) {
// do something
},
'droppable:drop': function (event) {
// do something
},
'droppable:out': function (event) {
// do something
},
'droppable:deactivate': function (event) {
// do something
},,
'draggable:destry': function (event) {
// do something
},
});Sortable
1. Enables an list to be sortable.
<div id="sortable"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> ... </div>
new Sortable(document.querySelector('#sortable'), {
// options here
}, eventHandlers);2. Available options for Sortable.
new Sortable(document.querySelector('#sortable'), {
// append the draggable element to a specific element
appendTo: 'parent',
// x or y
axis: null,
// connect to a Sortable list
// e.g. '#sort'
connectToSortable: null,
// parent, document, window, a CSS selector or an array of 4 numbers in the form [x1, y1, x2, y2]
containment: null,
// cursor type
cursor: null,
// if the draggable element is disabled
disabled: false,
// distance in pixels that the mouse should move before the dragging should start.
distance: 0,
// if false, items from this Sortable can't be dropped on an empty connected Sortable
dropOnEmpty: true,
// force the sorting helper to have a size
forceHelperSize: false,
// force the sorting placeholder to have a size
forcePlaceholderSize: false,
// set the visibility of the placeholder to hidden
hidePlaceholder: false,
// snap the dragging helper to a grid
// e.g. [10, 10]
grid: null,
// drag handle element
handle: null,
// original, clone or a function
helper: 'original',
// specify which items should be sortable
items: null,
// opacity of the draggable element while being dragged
opacity: null,
// invalid, valid, true, false or a function
revert: false,
// duration in milliseconds
revertDuration: 200,
// used to group sets of Draggable, Droppable and Sortable elements
scope: 'default',
// determine whether the container is scrollable
scroll: true,
scrollSensitivity: 20,
scrollSpeed: 10,
// stack to another element
stack: null,
// ignore these elements
skip: 'input, textarea, button, select, option',
// z-index property
zIndex: null
});3. Available events for Sortable.
new Droppable(document.querySelector('#droppable'), {OPTIONS}, {
'sortable:init': function (event) {
// do something
},
'sortable:activate': function (event) {
// do something
},
'sort:start': function (event) {
// do something
},
'sort:move': function (event) {
// do something
},
'sort:stop': function (event) {
// do something
},
'sortable:over': function (event) {
// do something
},
'sortable:change': function (event) {
// do something
},
'sortable:remove': function (event) {
// do something
},
'sortable:receive': function (event) {
// do something
},
'sortable:update': function (event) {
// do something
},
'sortable:out': function (event) {
// do something
},
'sortable:deactivate': function (event) {
// do something
},
'sortable:destroy': function (event) {
// do something
}
});Changelog:
v1.6.0 (09/17/2023)
- dev tools upgrades: eslint, prettier, husky
v1.5.1 (09/10/2023)
- added a ‘setOption’ method on draggable, droppable, sortable and resizable widgets to allow dynamic overriding of component options
- bugfix
v1.4.6 (05/27/2023)
- Bug Fixes
v1.4.5 (04/11/2022)
- Bug Fixes
v1.4.1 (08/29/2021)
- added proxy methods to prevent default and stop propagation using the original event
- Bug Fixes
v1.3.1 (08/27/2020)
- Fixed resizable: event listeners were not being destroyed correctly
v1.3.0 (08/24/2020)
- plugins refactored to reference the parent widget as ‘container’
- resizable: ported resizable widget from jquery ui
- sensor: added mouse:down event to mouse sensor
- Bug Fixes
v1.2.1 (08/16/2020)
- improve sortable event arguments
v1.1.2 (07/15/2020)
- Fixed: helper/placeholder size sync should not consider padding
v1.1.0 (07/15/2020)
- Added new option hidePlaceholder
- Fixed bugs
v1.0.6 (06/07/2020)
- Bug Fixes
v1.0.5 (04/19/2020)
- style: linting fixes
12/03/2020
- fix: fixed wrong and missing parameters when emitting the sortmove event








Nice! Does it support touch events for mobile devices?