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