Draggable

Vue Bootstrap Draggable

Note: This documentation is for an older version of Bootstrap (v.4). A newer version is available for Bootstrap 5. We recommend migrating to the latest version of our product - Material Design for Bootstrap 5.
Go to docs v.5

MDB Vue Draggable plugin provides a custom directive which allows moving objects by clicking on them and dragging them anywhere within the container.

To start working with the Draggable plugin, see the - "API" tab on this page.


Basic example

        
            
            <template>
              <div class="drag-container">
                <div v-mdb-draggable class="dragged-element green"></div>
              </div>
            </template>
          
        
    
        
            
            <script>
              import { mdbDraggable } from "mdb-draggable";
              export default {
                directives: {
                  mdbDraggable
                }
              };
            </script>
          
        
    
        
            
            <style>
              .drag-container {
                width: 100%;
                height: 500px;
                border-radius: 5px;
                box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
                -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
              }
              .dragged-element {
                width: 100px;
                height: 100px;
                border-radius: 5px;
                font-size: 12px;
                padding: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                text-align: center;
                transition: all 0.4s linear;
                transition-property: background-color;
              }
              .green {
                background-color: rgba(76, 175, 80, 0.3);
              }
            </style>
          
        
    

Auto-scroll

Adding .scroll modifier enables auto-scrolling when element its move beyond a scroll container boundaries. In the directive's value, specify the scroll speed and scroll container's ID (if this value is undefined the directive will use the parent's parentNode ).

        
            
            <template>
              <div class="drag-container" id="scroll-container">
                <div :style="{ height: '900px', width: '120vw' }">
                  <div
                    v-mdb-draggable.scroll="{ scroll: { containerId: 'scroll-container', speed: 10 } }"
                    class="dragged-element green"
                  ></div>
                </div>
              </div>
            </template>
          
        
    
        
            
            <script>
              import { mdbDraggable } from "mdb-draggable";
              export default {
                directives: {
                  mdbDraggable
                }
              };
            </script>
          
        
    
        
            
            <style>
              .drag-container {
                width: 100%;
                max-height: 400px;
                overflow: scroll;
                border-radius: 5px;
                box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
                -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
              }
              .dragged-element {
                width: 100px;
                height: 100px;
                border-radius: 5px;
                font-size: 12px;
                padding: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                text-align: center;
                transition: all 0.4s linear;
                transition-property: background-color;
              }
              .green {
                background-color: rgba(76, 175, 80, 0.3);
              }
            </style>
          
        
    

Axis

Use .x and .y modifiers to enable dragging to only one axis.

X

Y

        
            
            <template>
              <div class="drag-container">
                <div
                  v-mdb-draggable.x
                  :style="{ top: '200px', left: 'calc(100% - 120px)' }"
                  class="dragged-element grey"
                >
                  <p>X</p>
                </div>
                <div v-mdb-draggable.y class="dragged-element green">
                  <p>Y</p>
                </div>
              </div>
            </template>
          
        
    
        
            
            <script>
              import { mdbDraggable } from "mdb-draggable";
              export default {
                directives: {
                  mdbDraggable
                }
              };
            </script>
          
        
    
        
            
            <style>
              .drag-container {
                width: 100%;
                height: 500px;
                border-radius: 5px;
                box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
                -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
              }
              .dragged-element {
                width: 100px;
                height: 100px;
                border-radius: 5px;
                font-size: 12px;
                padding: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                text-align: center;
                transition: all 0.4s linear;
                transition-property: background-color;
              }
              .green {
                background-color: rgba(76, 175, 80, 0.3);
              }
              .grey {
                background-color: rgba(96, 125, 139, 0.3);
              }
            </style>
          
        
    

Cursor style

By default, the cursor style is set to crosshair - you can change that by adding the cursor option in the directive's value.

Move

Pointer

        
            
            <template>
              <div class="drag-container">
                <div
                  v-mdb-draggable="{ cursor: 'move' }"
                  :style="{ top: '200px', left: 'calc(100% - 120px)' }"
                  class="dragged-element grey"
                >
                  <p>Move</p>
                </div>
                <div
                  v-mdb-draggable="{ cursor: 'pointer' }"
                  class="dragged-element green"
                >
                  <p>Pointer</p>
                </div>
              </div>
            </template>
          
        
    
        
            
            <script>
              import { mdbDraggable } from "mdb-draggable";
              export default {
                directives: {
                  mdbDraggable
                }
              };
            </script>
          
        
    
        
            
            <style>
              .drag-container {
                width: 100%;
                height: 500px;
                border-radius: 5px;
                box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
                -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
              }
              .dragged-element {
                width: 100px;
                height: 100px;
                border-radius: 5px;
                font-size: 12px;
                padding: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                text-align: center;
                transition: all 0.4s linear;
                transition-property: background-color;
              }
              .green {
                background-color: rgba(76, 175, 80, 0.3);
              }
              .grey {
                background-color: rgba(96, 125, 139, 0.3);
              }
            </style>
          
        
    

Handles

You can enable dragging only when the cursor is over a specific part of your element, by binding it's ID to the handle key in the directive's value object.

        
            
            <template>
              <div class="drag-container">
                <div
                  v-mdb-draggable="{ handle: 'drag-handle' }"
                  :style="{ top: '100px', left: '10px' }"
                  class="dragged-element grey"
                >
                  <div
                    id="drag-handle"
                    :style="{ borderRadius: '50%', width: '40%', height: '40%' }"
                    class="green"
                  ></div>
                </div>
              </div>
            </template>
          
        
    
        
            
            <script>
              import { mdbDraggable } from "mdb-draggable";
              export default {
                directives: {
                  mdbDraggable
                }
              };
            </script>
          
        
    
        
            
            <style>
              .drag-container {
                width: 100%;
                height: 500px;
                border-radius: 5px;
                box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
                -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
              }
              .dragged-element {
                width: 100px;
                height: 100px;
                border-radius: 5px;
                font-size: 12px;
                padding: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                text-align: center;
                transition: all 0.4s linear;
                transition-property: background-color;
              }
              .green {
                background-color: rgba(76, 175, 80, 0.3);
              }
              .grey {
                background-color: rgba(96, 125, 139, 0.3);
              }
            </style>
          
        
    

Events

You can specify custom callbacks for start, drag and end events. Additionally, the drag callback is called with two arguments - top and left values of the dragged element.

  • @start: 0
  • @drag: 0
  • @end 0
        
            
            <template>
              <div class="drag-container">
                <div
                  v-mdb-draggable="{
                    start: handleStart,
                    drag: handleDrag,
                    end: handleEnd
                  }"
                  class="dragged-element green"
                >
                  <ul>
                    <li>
                      @start: {{count.start}}
                    </li>
                    <li>
                      @drag: {{count.drag}}
                    </li>
                    <li>
                      @end: {{count.end}}
                    </li>
                  </ul>
                </div>
              </div>
            </template>
          
        
    
        
            
            <script>
              import { mdbDraggable } from "mdb-draggable";
              export default {
                directives: {
                  mdbDraggable
                },
                data() {
                  return {
                    count: {
                      start: 0,
                      drag: 0,
                      end: 0
                    }
                  };
                },
                methods: {
                  handleStart() {
                    this.count.start++;
                  },
                  handleDrag() {
                    this.count.drag++;
                  },
                  handleEnd() {
                    this.count.end++;
                  }
                }
              };
            </script>
          
        
    
        
            
            <style>
              .drag-container {
                width: 100%;
                height: 500px;
                border-radius: 5px;
                box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
                -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
              }
              .dragged-element {
                width: 100px;
                height: 100px;
                border-radius: 5px;
                font-size: 12px;
                padding: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                text-align: center;
                transition: all 0.4s linear;
                transition-property: background-color;
              }
              .dragged-element ul {
                padding: 0;
                list-style: none;
              }
              .dragged-element ul li {
                margin: 5px 0;
                padding: 5px 0;
                border-bottom: 1px solid rgba(0, 0, 0, 0.3);
              }
              .green {
                background-color: rgba(76, 175, 80, 0.3);
              }
              .grey {
                background-color: rgba(96, 125, 139, 0.3);
              }
            </style>
          
        
    

Snap to the container (inner mode)

Add the snap options to the directive's value in order to enable snapping to other elements/container. There are three options available:

  • tolerance (Number) - required
  • mode (String) - required, two values acceptable: inner and outer
  • referenceId (String, Array) - id of the reference element/elements - if not specified, the directive will use the parent.
        
            
            <template>
              <div class="drag-container">
                <div
                  v-mdb-draggable="{ snap: { tolerance: 80, mode: 'inner' } }"
                  class="dragged-element green"
                ></div>
              </div>
            </template>
          
        
    
        
            
            <script>
              import { mdbDraggable } from "mdb-draggable";
              export default {
                directives: {
                  mdbDraggable
                }
              };
            </script>
          
        
    
        
            
            <style>
              .drag-container {
                width: 100%;
                height: 500px;
                border-radius: 5px;
                box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
                -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
              }
              .dragged-element {
                width: 100px;
                height: 100px;
                border-radius: 5px;
                font-size: 12px;
                padding: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                text-align: center;
                transition: all 0.4s linear;
                transition-property: background-color;
              }
              .green {
                background-color: rgba(76, 175, 80, 0.3);
              }
              .grey {
                background-color: rgba(96, 125, 139, 0.3);
              }
            </style>
          
        
    

Snap to the other elements (outer mode)

        
            
            <template>
              <div class="drag-container">
                <div
                  id="el-1"
                  v-mdb-draggable="{
                    snap: { referenceId: ['el-2'], tolerance: 30, mode: 'outer' }
                  }"
                  class="dragged-element green"
                ></div>
                <div
                  id="el-2"
                  v-mdb-draggable="{
                    snap: {
                      referenceId: 'el-1',
                      tolerance: 30,
                      mode: 'outer'
                    }
                  }"
                  class="dragged-element grey"
                  :style="{ top: '250px' }"
                ></div>
              </div>
            </template>
          
        
    
        
            
            <script>
              import { mdbDraggable } from "mdb-draggable";
              export default {
                directives: {
                  mdbDraggable
                }
              };
            </script>
          
        
    
        
            
            <style>
              .drag-container {
                width: 100%;
                height: 500px;
                border-radius: 5px;
                box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
                -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
              }
              .dragged-element {
                width: 100px;
                height: 100px;
                border-radius: 5px;
                font-size: 12px;
                padding: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                text-align: center;
                transition: all 0.4s linear;
                transition-property: background-color;
              }
              .green {
                background-color: rgba(76, 175, 80, 0.3);
              }
              .grey {
                background-color: rgba(96, 125, 139, 0.3);
              }
            </style>
          
        
    

Revert position

To return the dragged object to its original position after dragging has ended, use the .revert modifier.

Element will return to its initial position

        
            
            <template>
              <div class="drag-container">
                <div v-mdb-draggable.revert class="dragged-element green">
                  <p>Element will return to its initial position</p>
                </div>
              </div>
            </template>
          
        
    
        
            
            <script>
              import { mdbDraggable } from "mdb-draggable";
              export default {
                directives: {
                  mdbDraggable
                }
              };
            </script>
          
        
    
        
            
            <style>
              .drag-container {
                width: 100%;
                height: 500px;
                border-radius: 5px;
                box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
                -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
              }
              .dragged-element {
                width: 100px;
                height: 100px;
                border-radius: 5px;
                font-size: 12px;
                padding: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                text-align: center;
                transition: all 0.4s linear;
                transition-property: background-color;
              }
              .green {
                background-color: rgba(76, 175, 80, 0.3);
              }
            </style>
          
        
    

Offset

You can customize offset from each container's edge, by adding offset object to the directive's value. The offset object:

  • top - offset from the top edge in px (Number, default: 0)
  • bottom - offset from the bottom edge in px (Number, default: 0)
  • left - offset from the left edge in px (Number, default: 0)
  • right - offset from the right edge in px (Number, default: 0)
        
            
            <template>
              <div class="drag-container">
                <div
                  v-mdb-draggable="{
                    offset: { top: 10, bottom: 30, left: 10, right: 60 }
                  }"
                  :style="{ left: 'calc(50% - 60px', top: '10px' }"
                  class="dragged-element green"
                >
                  <p>Try moving the element towards the container's edges</p>
                </div>
              </div>
            </template>
          
        
    
        
            
            <script>
              import { mdbDraggable } from "mdb-draggable";
              export default {
                directives: {
                  mdbDraggable
                }
              };
            </script>
          
        
    
        
            
            <style>
              .drag-container {
                width: 100%;
                height: 500px;
                border-radius: 5px;
                box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
                -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
              }
              .dragged-element {
                width: 100px;
                height: 100px;
                border-radius: 5px;
                font-size: 12px;
                padding: 10px;
                display: flex;
                align-items: center;
                justify-content: center;
                user-select: none;
                text-align: center;
                transition: all 0.4s linear;
                transition-property: background-color;
              }
              .green {
                background-color: rgba(76, 175, 80, 0.3);
              }
              .grey {
                background-color: rgba(96, 125, 139, 0.3);
              }
            </style>
          
        
    

Vue Draggable - getting started : download & setup


Download

This plugin requires a purchase.

Buy Draggable plugin

Modifiers

Name Description Example
.scroll Enables auto scroll <div v-mdb-draggable.scroll="{ scroll: { containerId: '..', speed: '..'}}" ></div>
.x Disables dragging along Y axis <div v-mdb-draggable.x ></div>
.y Disables dragging along X axis <div v-mdb-draggable.y ></div>
.revert Reverts the element to its original position after dragging has ended <div v-mdb-draggable.revert ></div>

Value - keys

Name Type Description Example
scroll Object Two options available: speed (Number) and containerId (String) <div v-mdb-draggable="{ scroll: { speed: 10, containerId: '..'}}" ></div>
snap Object Three options available: mode (String: 'outer' / 'inner'), referenceId (String, Array) and tolerance (Number) <div v-mdb-draggable="{ snap: { tolerance: 10, referenceId: '..', mode: 'inner'}}" ></div>
offset Object You can specify an offset in pixels (Number) from all container's edges. <div v-mdb-draggable="{ offset: { top: 10, left: 10, bottom: 30, right: 16 }}" ></div>
handle String The id of the drag-handle. <div v-mdb-draggable="{ handle: 'handle-id' }" ></div>
cursor String The cursor's style <div v-mdb-draggable="{ cursor: 'pointer' }" ></div>
parentId String The parent container's id - if not specified, the directive will use the parentNode. <div v-mdb-draggable="{ parentId: '...' }" ></div>
start Function The callback for the start event <div v-mdb-draggable="{ start: onStart }" ></div>
drag Function The callback for the drag event which will be called with two arguments: top and left values. <div v-mdb-draggable="{ drag: onDrag }" ></div>
end Function The callback for the end event <div v-mdb-draggable="{ end: onEnd }" ></div>

Example

        
            
    <template>
      <div class="drag-container" id="parent">
        <div id="el-1" v-mdb-draggable.revert.x.scroll="options" class="dragged-element green">
          <div class="handle grey" id="handle"></div>
        </div>
      </div>
    </template>
    
        
    
        
            
    <script>
      import {
        mdbDraggable
      } from "mdb-draggable";

      export default {
        directives: {
          mdbDraggable
        },
        data() {
          return {
            options: {
              scroll: {
                speed: 10,
                containerId: "../"
              },
              snap: {
                tolerance: 50,
                referenceId: "...",
                mode: "outer"
              },
              offset: {
                top: 10,
                left: 10,
                right: 70,
                bottom: 100
              },
              handle: "handle",
              parentId: "parent",
              cursor: "pointer",
              drag: () => {},
              start: () => {},
              end: () => {}
            }
          };
        }
      };
    </script>
    
        
    
        
            
    <style>
      .drag-container {
        width: 100%;
        height: 500px;
        border-radius: 5px;
        box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
        -webkit-box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.09);
      }

      .dragged-element {
        width: 100px;
        height: 100px;
        border-radius: 5px;
        font-size: 12px;
        padding: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
        user-select: none;
        text-align: center;
        transition: all 0.4s linear;
        transition-property: background-color;
      }

      .handle {
        width: 30px;
        height: 30px;
        border-radius: 50%;
      }

      .green {
        background-color: rgba(76, 175, 80, 0.3);
      }

      .grey {
        background-color: rgba(96, 125, 139, 0.3);
      }
    </style>