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

Try out MDB Drag & Drop Builder

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.

        
            
        <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.

        
            
        <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.

        
            
        <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.

        
            
        <div class="draggable-element shadow-1-strong" data-mdb-draggable-init data-mdb-disabled="true">
          <p>Disabled</p>
        </div>
      
        
    

Custom drag button

By adding data-mdb-drag-handle with selector you can set drag handler of your element. Note that drag handler has to be inside an element.

Drag only on button!

        
            
        <div class="draggable-element shadow-1-strong" data-mdb-draggable-init data-mdb-drag-handle=".draggable-drag-ico">
          <i class="fas fa-arrows-alt draggable-drag-ico"></i>
          <p>Drag only on button!</p>
        </div>
      
        
    

Scrolling option

When your draggable element is inside a scrollable container, the container will scroll when you approach its edge.

        
            
        <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.

Item 1
Item 2
Item 3
Item 4
Item 5
        
            
        <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.

Item 1
Item 2
Item 3
Item 4
Item 5
        
            
        <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.

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
        
            
        <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

Item 1
Item 2
Item 3
Item 4
Item 5
Disabled

Done

Item 6
Item 7
Item 8
Item 9
Item 10
        
            
            <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

Item 1
Item 2
Item 3
Item 4
Item 5

Copy

Item 6
Item 7
Item 8
Item 9
Item 10
        
            
        <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

1
2
3
4
5

Only odd numbers

7
        
            
        <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

Item 1
Item 2
Item 3
Item 4
Item 5

Sorting not available

item 6
item 7
        
            
            <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

Item 1
Item 2
Item 3
Item 4
Item 5

Done

item 6
item 7
item 8
item 9
        
            
          <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" 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(sortableCondition1, {
        ...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 deley exist before element starts to drag
disabled Boolean false Defines whether element is able to drag or not
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 / Null / String' 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);
                      });