Drag and drop
Bootstrap 5 Drag and drop plugin
Drag and Drop plugin built with Bootstrap 5. Examples of draggable list, cards, tables, grid, buttons. Available sort, copy, scroll, disable, delay, nested & other options.
Note: Read the API tab to find all available options and advanced customization
Note: Currently, the plugin is only compatible with the basic MDB package imported in UMD format. More about import MDB formats.
Draggable basic example
Make an element draggable by adding the data-mdb-draggable-init
attribute to the element with the
class .draggable-element
.
Drag me!
<div class="draggable-element shadow-3" data-mdb-draggable-init>
<p>Drag me!</p>
</div>
Custom container
Disable the x-axis or y-axis by adding the data-mdb-block-x-axis
or
data-mdb-block-y-axis
attribute, respectively.
Drag me!
<div class="draggable-element shadow-1-strong" data-mdb-draggable-init data-mdb-container="#draggable-container">
<p>Drag me!</p>
</div>
Blocked axis
Thanks to data-mdb-block-x-axis
attribute or
data-mdb-block-y-axis
attribute you can disable x or y axis.
Drag me!
Drag me!
<div class="draggable-element shadow-1-strong" data-mdb-draggable-init data-mdb-block-x-axis="true" data-mdb-container="#draggable-container-2">
<p>Drag me!</p>
</div>
<div class="draggable-element shadow-1-strong" data-mdb-draggable-init data-mdb-block-y-axis="true" data-mdb-container="#draggable-container-2">
<p>Drag me!</p>
</div>
Delay
Set the delay for starting dragging by adding the data-mdb-delay
attribute with a value in milliseconds.
Drag me after one second!
<div class="draggable-element shadow-1-strong" data-mdb-draggable-init data-mdb-delay="1000">
<p>Drag me after one second!</p>
</div>
Disabled
You can set your draggable element as disabled by adding
data-mdb-disabled
with true
value.
Disabled
<div class="draggable-element shadow-1-strong" data-mdb-draggable-init data-mdb-disabled="true">
<p>Disabled</p>
</div>
Scrolling option
When your draggable element is inside a scrollable container, the container will scroll when you approach its edge.
Drag!
<div id="draggable-scroll" class="draggable-element shadow-1-strong" data-mdb-draggable-init data-mdb-container="#draggable-container-6">
<p>Drag!</p>
</div>
Sortable basic example
Make your list sortable by adding the data-mdb-sortable
attribute with a value of sortable
. Note that only
elements with the data-mdb-sortable-init
attribute will be able to be sorted.
<div data-mdb-sortable-init class="sortable-list">
<div class="sortable-item">Item 1</div>
<div class="sortable-item">Item 2</div>
<div class="sortable-item">Item 3</div>
<div class="sortable-item">Item 4</div>
<div class="sortable-item">Item 5</div>
</div>
Horizontal example
A sortable list will work with any element configuration or direction, as it is not limited to a vertical layout.
<div data-mdb-sortable-init class="sortable-list d-flex">
<div class="sortable-item">Item 1</div>
<div class="sortable-item">Item 2</div>
<div class="sortable-item">Item 3</div>
<div class="sortable-item">Item 4</div>
<div class="sortable-item">Item 5</div>
</div>
Grid example
Sortable can also be implemented with the grid layout.
<div id="sortable-grid" data-mdb-sortable-init class="sortable-list d-flex flex-wrap">
<div class="sortable-item">Item 1</div>
<div class="sortable-item">Item 2</div>
<div class="sortable-item">Item 3</div>
<div class="sortable-item">Item 4</div>
<div class="sortable-item">Item 5</div>
<div class="sortable-item">Item 6</div>
<div class="sortable-item">Item 7</div>
<div class="sortable-item">Item 8</div>
<div class="sortable-item">Item 9</div>
<div class="sortable-item">Item 10</div>
<div class="sortable-item">Item 11</div>
<div class="sortable-item">Item 12</div>
</div>
#sortable-grid .sortable-item {
width: 125px;
height: 125px;
margin: 15px;
display: flex;
justify-content: center;
border: 1px solid var(--mdb-secondary-border-subtle);
background: var(--mdb-secondary-bg-subtle);
text-align: center;
}
Multiple tables
Connect your list with others by adding the data-mdb-connected-list
attribute. Note that you need to
set the value as a selector when initializing your component via data attributes.
To do
Done
<div id="sortable-multi-tables-1" data-mdb-sortable-init class="sortable-list" data-mdb-connected-list="#sortable-multi-tables-2">
<h4 class="text-center pt-2">To do</h4>
<div class="sortable-item">Item 1</div>
<div class="sortable-item">Item 2</div>
<div class="sortable-item">Item 3</div>
<div class="sortable-item">Item 4</div>
<div class="sortable-item">Item 5</div>
<div class="sortable-item" data-mdb-disabled="true">Disabled</div>
</div>
<div id="sortable-multi-tables-2" data-mdb-sortable-init class="sortable-list" data-mdb-connected-list="#sortable-multi-tables-1">
<h4 class="text-center pt-2">Done</h4>
<div class="sortable-item">Item 6</div>
<div class="sortable-item">Item 7</div>
<div class="sortable-item">Item 8</div>
<div class="sortable-item">Item 9</div>
<div class="sortable-item">Item 10</div>
</div>
Coping items
By adding data-mdb-copy
with value true
you can copy your items to
connected table.
Elements
Copy
<div
id="sortable-copy-1"
class="sortable-list"
data-mdb-connected-list="#sortable-copy-2"
data-mdb-copy="true"
data-mdb-sorting="false"
data-mdb-sortable-init
>
<h4 class="text-center pt-2">Elements</h4>
<div class="sortable-item">Item 1</div>
<div class="sortable-item">Item 2</div>
<div class="sortable-item">Item 3</div>
<div class="sortable-item">Item 4</div>
<div class="sortable-item">Item 5</div>
</div>
<div
id="sortable-copy-2"
class="sortable-list"
data-mdb-connected-list="#sortable-copy-1"
data-mdb-sortable-init
>
<h4 class="text-center pt-2">Copy</h4>
<div class="sortable-item">Item 6</div>
<div class="sortable-item">Item 7</div>
<div class="sortable-item">Item 8</div>
<div class="sortable-item">Item 9</div>
<div class="sortable-item">Item 10</div>
</div>
Conditions
Customize the conditions for permitting the sending or copying of items to a connected table by adding your
custom function that return true
or false
to the enterPredicate
property.
It's important to note that you can only initialize this via JavaScript.
Numbers
Only odd numbers
<div id="sortable-condition-1" class="sortable-list" data-mdb-sortable-init>
<h4 class="text-center pt-2">Numbers</h4>
<div class="sortable-item" data-mdb-value="1">1</div>
<div class="sortable-item" data-mdb-value="2">2</div>
<div class="sortable-item" data-mdb-value="3">3</div>
<div class="sortable-item" data-mdb-value="4">4</div>
<div class="sortable-item" data-mdb-value="5">5</div>
</div>
<div id="sortable-condition-2" class="sortable-list" data-mdb-sortable-init>
<h4 class="text-center pt-2">Only odd numbers</h4>
<div class="sortable-item" data-mdb-value="7">7</div>
</div>
// Your custom function with true/false return
const accessOddNumbers = (value) => {
return parseInt(value) % 2;
}
const sortableCondition1 = document.getElementById('sortable-condition-1');
const sortableCondition2 = document.getElementById('sortable-condition-2');
const instanceSortableCondition1 = new DragAndDrop.Sortable(sortableCondition1, {
connectedList: sortableCondition2,
enterPredicate: accessOddNumbers,
});
const instanceSortableCondition2 = new DragAndDrop.Sortable(sortableCondition2);
Disabled sorting
To disable sorting in a table, add the data-mdb-sorting
attribute with a value of false
.
Sorting available
Sorting not available
<div id="sortable-disabled-1" data-mdb-sortable-init class="sortable-list"
data-mdb-connected-list="#sortable-disabled-2">
<h4 class="text-center pt-2">Sorting available</h4>
<div class="sortable-item">Item 1</div>
<div class="sortable-item">Item 2</div>
<div class="sortable-item">Item 3</div>
<div class="sortable-item">Item 4</div>
<div class="sortable-item">Item 5</div>
</div>
<div id="sortable-disabled-2" data-mdb-sortable-init class="sortable-list"
data-mdb-connected-list="#sortable-disabled-1" data-mdb-sorting="false">
<h4 class="text-center pt-2">Sorting not available</h4>
<div class="sortable-item">item 6</div>
<div class="sortable-item">item 7</div>
</div>
Nested
By adding data-mdb-item-class
you can set what class has to be in your list item
to make them sortable. Thanks to that you can make nested lists.
To do
Done
<div id="sortable-multi-1-1" data-mdb-sortable-init class="sortable-list d-flex align-items-start" data-mdb-item-class="sortable-item-nested">
<div id="sortable-multi-2-2" data-mdb-sortable-init class="sortable-item-nested" data-mdb-connected-list="#sortable-multi-2-1" data-mdb-drag-handle=".drag-handler">
<h4 class="text-center pt-2 drag-handler">To do</h4>
<div class="sortable-item">Item 1</div>
<div class="sortable-item">Item 2</div>
<div class="sortable-item">Item 3</div>
<div class="sortable-item">Item 4</div>
<div class="sortable-item">Item 5</div>
</div>
<div id="sortable-multi-2-1" data-mdb-sortable-init class="sortable-item-nested" data-mdb-connected-list="#sortable-multi-2-2" data-mdb-drag-handle=".drag-handler">
<h4 class="text-center pt-2 drag-handler">Done</h4>
<div class="sortable-item">item 6</div>
<div class="sortable-item">item 7</div>
<div class="sortable-item">item 8</div>
<div class="sortable-item">item 9</div>
</div>
</div>
Drag and drop - API
Import
import { Draggable, Sortable } from 'mdb-drag-and-drop';
@import '~mdb-drag-and-drop/css/drag-and-drop.min.css';
Usage
Via data attributes
Using the Drag And Drop plugin doesn't require any additional JavaScript code - simply add
data-mdb-draggable-init
attribute to
.draggable-element
and data-mdb-sortable-init
attribute to sortable-list
and use other data attributes to set all options.
<!-- Draggable -->
<div class="draggable-element" data-mdb-draggable-init></div>
<!-- Sortable -->
<div data-mdb-sortable="sortable" data-mdb-sortable-init>
<div class="sortable-item">Item 1</div>
<div class="sortable-item">Item 2</div>
<div class="sortable-item">Item 3</div>
<div class="sortable-item">Item 4</div>
<div class="sortable-item">Item 5</div>
</div>
Via JavaScript
// Draggable
const draggableEl = document.getElementById('draggable');
const instanceDraggable = new DragAndDrop.Draggable(draggableEl, {
...options,
});
// Sortable
const sortableEl = document.getElementById('sortable');
const instanceSortable = new DragAndDrop.Sortable(sortableEl, {
...options
});
Via jQuery
Note: By default, MDB does not include jQuery and you have to add it to the project on your own.
$(document).ready(() => {
// Draggable
$('#draggable').Draggable();
// Sortable
$('#sortable').Sortable();
});
Options
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to
data-mdb-
, as in data-mdb-delay=""
.
Draggable
Name | Type | Default | Description |
---|---|---|---|
blockXAxis
|
Boolean | false |
Defines whether 'x' axis is blocked or not |
blockYAxis
|
Boolean | false |
Defines whether 'y' axis is blocked or not |
container
|
String | 'body' |
Defines container of dragging element |
delay
|
Number | 0 |
Defines how long will delay exist before element starts to drag |
disabled
|
Boolean | false |
Defines whether element is able to drag or not |
dragHandle
|
String | '' |
Defines drag handler of the element. Note, handler has to be inside of the dragging element |
draggingClass
|
String | 'dragging' |
Defines class which is using during dragging of the element |
scrollPixels
|
Number | 40 |
If container is scrollable, defines distance from edges where scrolling will begin |
Sortable
Name | Type | Default | Description |
---|---|---|---|
animationDuration
|
Number | 300 |
Defines duration of sliding and returning animations |
connectedList
|
Element | String | null | null |
Defines list which you want to connect with |
copy
|
Boolean | false |
Defines whether you want to copy elements from one list to another or send them instead |
enterPredicate
|
Function | () => true |
Defines function which check access between tables |
itemClass
|
String | 'sortable-item' |
Defines class name for sortable items. |
sorting
|
Boolean | true |
Defines whether list is able to sort or not |
Methods
Draggable
dispose
|
- | Removes draggable instance. |
instanceDraggable.dispose()
|
resetPosition
|
- | Return original position of the element. |
instanceDraggable.resetPosition()
|
getInstance |
element | Static method which allows you to get the draggable instance associated to a DOM element. | Draggable.getInstance(draggableElement) |
const draggableElement = document.getElementById('draggable');
const instanceDraggable = DragAndDrop.Draggable.getInstance(draggableElement);
instanceDraggable.resetPosition();
Sortable
dispose
|
- | Removes sortable instance. |
instanceSortable.dispose()
|
addItem |
element, index | Adds element to the sortable list. You can set position in the list of your new item by adding index number. Note: If you did not insert an index number, your element would append at the end of the list. |
instanceSortable.addItem(el, 2)
|
getInstance |
element | Static method which allows you to get the sortable instance associated to a DOM element. | Sortable.getInstance(sortableElement) |
removeItem |
id | Removes element from the sortable list. You pass element id as an argument. |
instanceSortable.removeItem(id) |
const newElement = document.createElement('div');
newElement.classList.add('sortable-item');
newElement.textContent = 'New Element';
const sortableElement = document.getElementById('sortable');
const instanceSortable = DragAndDrop.Sortable.getInstance(sortableElement);
instanceSortable.addItem(newElement);
instanceSortable.removeItem("exampleId");
Events
Draggable
Name | Description |
---|---|
start.mdb.draggable
|
Emitted when an element is started dragging. |
end.mdb.draggable
|
Emitted when an element is ended dragging. |
itemMove.mdb.draggable
|
Emitted when an element is dragging. |
const draggableItem = document.getElementById('dragging');
draggableItem.addEventListener('start.mdb.draggable', () => {
alert('Start dragging');
});
Sortable
Name | Description |
---|---|
itemMove.mdb.sortable
|
Emitted when one of the items from list changed its position. |
listChange.mdb.sortable
|
Emitted when one of the items from list will enter to connected table. |
const sortableItem = document.getElementById('sortable-item-1');
sortableItem.addEventListener('itemMove.mdb.sortable', (e) => {
alert(e.target);
});