Vue Bootstrap Sortable
Vue Sortable Plugin - Bootstrap 4 & Material Design
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
Vue Bootstrap sortable plugin is an extension that allows you to move, reorder, sort and organize elements on your website by using drag and drop functionality.
To start working with sortable plugin see "API" tab on this page.
Basic Example
Change the order of elements in the DOM tree by dragging the element.
- Item 1
- Item 2
- Item 3
- Item 4
- Item 5
- Item 6
- Item 7
- Item 8
<template>
<mdb-container>
<mdb-list-group>
<mdb-sortable :list="list">
<mdb-list-group-item v-for="element in list" :key="element.id" :active="element.active">
{{ element.name }}
</mdb-list-group-item>
</mdb-sortable>
</mdb-list-group>
</mdb-container>
</template>
<script>
import mdbSortable from 'mdb-sortable'
import {
mdbContainer,
mdbListGroup,
mdbListGroupItem
} from 'mdbvue'
export default {
name: 'app',
components: {
mdbSortable,
mdbContainer,
mdbListGroup,
mdbListGroupItem
},
data() {
return {
list: [{
name: "Item 1",
id: 0,
active: true
},
{
name: "Item 2",
id: 1
},
{
name: "Item 3",
id: 2
},
{
name: "Item 4",
id: 3
},
{
name: "Item 5",
id: 4
},
{
name: "Item 6",
id: 5
},
{
name: "Item 7",
id: 6
},
{
name: "Item 8",
id: 7
}
]
}
}
}
</script>
Merging lists
Sorting items between two lists
- Lion
- Dog
- Cat
- Tiger
- Fish
- Bird
- Falcon
- Mouse
<template>
<mdb-container>
<mdb-row>
<mdb-col sm="6">
<mdb-list-group>
<mdb-sortable :list="list2" group="merge">
<mdb-list-group-item v-for="element in list2" :key="element.id" :active="element.active">
{{ element.name }}
</mdb-list-group-item>
</mdb-sortable>
</mdb-list-group>
</mdb-col>
<mdb-col sm="6">
<mdb-list-group>
<mdb-sortable :list="list3" group="merge">
<mdb-list-group-item v-for="element in list3" :key="element.id" :active="element.active">
{{ element.name }}
</mdb-list-group-item>
</mdb-sortable>
</mdb-list-group>
</mdb-col>
</mdb-row>
</mdb-container>
</template>
<script>
import mdbSortable from 'mdb-sortable'
import {
mdbContainer,
mdbRow,
mdbCol,
mdbListGroup,
mdbListGroupItem
} from 'mdbvue'
export default {
name: 'app',
components: {
mdbSortable,
mdbContainer,
mdbRow,
mdbCol,
mdbListGroup,
mdbListGroupItem
},
data() {
return {
list2: [{
name: "Lion",
id: 0,
active: true
},
{
name: "Cat",
id: 1
},
{
name: "Tiger",
id: 2
},
{
name: "Dog",
id: 3
}
],
list3: [{
name: "Fish",
id: 4,
active: true
},
{
name: "Bird",
id: 5
},
{
name: "Falcon",
id: 6
},
{
name: "Mouse",
id: 7
}
]
}
}
}
</script>
Display as grid
Displays items in a sortable grid - this can be used to determine the order in which photos or files are uploaded.
<template>
<mdb-container>
<mdb-row>
<mdb-sortable :list="list4" class="col-md-5 d-flex flex-center flex-wrap">
<div v-for="element in list4" :key="element.id" class="text-center white-text blue m-2 square">
{{ element.id }}
</div>
</mdb-sortable>
</mdb-row>
</mdb-container>
</template>
<script>
import mdbSortable from 'mdb-sortable'
import {
mdbContainer,
mdbRow
} from 'mdbvue'
export default {
name: 'app',
components: {
mdbSortable,
mdbContainer,
mdbRow
},
data() {
return {
list4: [{
id: 1
},
{
id: 2
},
{
id: 3
},
{
id: 4
},
{
id: 5
},
{
id: 6
},
{
id: 7
},
{
id: 8
},
{
id: 9
},
{
id: 10
},
{
id: 11
},
{
id: 12
}
]
}
}
}
</script>
<style>
.square {
height: 90px;
width: 90px;
line-height: 90px;
font-size: 32px;
}
</style>
Handle empty lists
By default, it is not possible to place an item in an empty list. In this example, this has been changed.
From the first list, it is possible to drag to an empty list, while from the second list you cannot drag elements if the target list is empty.
The dropOnEmpty: false
parameter is responsible for this behavior.
- Lion
- Dog
- Cat
- Tiger
- Fish
- Bird
- Falcon
- Mouse
<template>
<mdb-container>
<mdb-row>
<mdb-col sm="4">
<mdb-list-group>
<mdb-sortable :list="list5" group="empty-lists">
<mdb-list-group-item v-for="element in list5" :key="element.id" :active="element.active">
{{ element.name }}
</mdb-list-group-item>
</mdb-sortable>
</mdb-list-group>
</mdb-col>
<mdb-col sm="4">
<mdb-list-group>
<mdb-sortable :list="list6" group="empty-lists">
<mdb-list-group-item v-for="element in list6" :key="element.id" :active="element.active">
{{ element.name }}
</mdb-list-group-item>
</mdb-sortable>
</mdb-list-group>
</mdb-col>
<mdb-col sm="4">
<mdb-list-group class="grey lighten-1 py-2">
<mdb-sortable :list="list7" group="empty-lists">
<mdb-list-group-item v-for="element in list7" :key="element.id" :active="element.active">
{{ element.name }}
</mdb-list-group-item>
</mdb-sortable>
</mdb-list-group>
</mdb-col>
</mdb-row>
</mdb-container>
</template>
<script>
import mdbSortable from 'mdb-sortable'
import {
mdbContainer,
mdbRow,
mdbCol,
mdbListGroup,
mdbListGroupItem
} from 'mdbvue'
export default {
name: 'app',
components: {
mdbSortable,
mdbContainer,
mdbRow,
mdbCol,
mdbListGroup,
mdbListGroupItem
},
data() {
return {
list5: [{
name: "Lion",
id: 0,
active: true
},
{
name: "Dog",
id: 1
},
{
name: "Cat",
id: 2
},
{
name: "Tiger",
id: 3
},
],
list6: [{
name: "Fish",
id: 4,
active: true
},
{
name: "Bird",
id: 5
},
{
name: "Falcon",
id: 6
},
{
name: "Mouse",
id: 7
}
],
list7: [],
}
}
}
</script>
Include / exclude items
It is possible to exclude items from the possibility of sorting or dragging items before / after them.
- I'm sortable
- I'm not sortable
- I'm not sortable
- I'm sortable
<template>
<mdb-container>
<mdb-row>
<mdb-col sm="6">
<mdb-list-group>
<mdb-sortable :list="list12">
<mdb-list-group-item v-for="element in list12" :key="element.id" :active="element.active"
:disabled="element.disabled">
{{ element.name }}
</mdb-list-group-item>
</mdb-sortable>
</mdb-list-group>
</mdb-col>
</mdb-row>
</mdb-container>
</template>
<script>
import mdbSortable from 'mdb-sortable'
import {
mdbContainer,
mdbRow,
mdbCol,
mdbListGroup,
mdbListGroupItem
} from 'mdbvue'
export default {
name: 'app',
components: {
mdbSortable,
mdbContainer,
mdbRow,
mdbCol,
mdbListGroup,
mdbListGroupItem
},
data() {
return {
list12: [{
name: "I'm sortable",
id: 0,
active: true
},
{
name: "I'm sortable",
id: 1
},
{
name: "I'm not sortable",
id: 2,
disabled: true
},
{
name: "I'm not sortable",
id: 3,
disabled: true
}
]
}
}
}
</script>
Sortable collapsed cards
Cards with collapsed content and sorting between lists - similar behavior can be observed on Trello.
<template>
<mdb-container>
<mdb-row>
<mdb-col sm="4" class="blue mx-auto mb-5 pb-4 white-text">
<mdb-sortable :list="list8" group="cards">
<div class="portlet" v-for="element in list8" :key="element.id">
<mdb-btn color="blue" block class="portlet-header white-text blue darken-3 text-capitalize my-3"
@click.native="element.collapse ? element.collapse = false : element.collapse = true">
{{element.name}} <i class="fas ml-2"
:class="element.collapse ? 'fa-caret-up' : 'fa-caret-down'"></i></mdb-btn>
<transition @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave">
<p v-if="element.collapse" class="collapse-item text-center">Lorem ipsum dolor sit amet,
consectetuer adipiscing elit</p>
</transition>
</div>
</mdb-sortable>
</mdb-col>
<mdb-col sm="4" class="blue mx-auto mb-5 pb-4 white-text">
<mdb-sortable :list="list9" group="cards">
<div class="portlet" v-for="element in list9" :key="element.id">
<mdb-btn color="blue" block class="portlet-header white-text blue darken-3 text-capitalize my-3"
@click.native="element.collapse ? element.collapse = false : element.collapse = true">
{{element.name}} <i class="fas ml-2"
:class="element.collapse ? 'fa-caret-up' : 'fa-caret-down'"></i></mdb-btn>
<transition @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave">
<p v-if="element.collapse" class="collapse-item text-center">Lorem ipsum dolor sit amet,
consectetuer adipiscing elit</p>
</transition>
</div>
</mdb-sortable>
</mdb-col>
<mdb-col sm="4" class="blue mx-auto mb-5 pb-4 white-text">
<mdb-sortable :list="list10" group="cards">
<div class="portlet" v-for="element in list10" :key="element.id">
<mdb-btn color="blue" block class="portlet-header white-text blue darken-3 text-capitalize my-3"
@click.native="element.collapse ? element.collapse = false : element.collapse = true">
{{element.name}} <i class="fas ml-2"
:class="element.collapse ? 'fa-caret-up' : 'fa-caret-down'"></i></mdb-btn>
<transition @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave">
<p v-if="element.collapse" class="collapse-item text-center">Lorem ipsum dolor sit amet,
consectetuer adipiscing elit</p>
</transition>
</div>
</mdb-sortable>
</mdb-col>
</mdb-row>
</mdb-container>
</template>
<script>
import mdbSortable from 'mdb-sortable'
import {
mdbContainer,
mdbRow,
mdbCol,
mdbListGroup,
mdbListGroupItem,
mdbBtn
} from 'mdbvue'
export default {
name: 'app',
components: {
mdbSortable,
mdbRow,
mdbCol,
mdbContainer,
mdbListGroup,
mdbListGroupItem,
mdbBtn
},
data() {
return {
list12: [{
name: "I'm sortable",
id: 0,
active: true
},
{
name: "I'm sortable",
id: 1
},
{
name: "I'm not sortable",
id: 2,
disabled: true
},
{
name: "I'm not sortable",
id: 3,
disabled: true
}
]
}
},
methods: {
beforeEnter(el) {
el.style.height = 0;
},
enter(el) {
el.style.height = el.scrollHeight + 'px';
},
beforeLeave(el) {
el.style.height = 0;
}
}
}
</script>
Sortable deck of cards
Cards with collapsed content and sorting between lists - similar behavior can be observed on Trello.
Card title
Some quick example text to build on the card title and make up the bulk of the card's content.
Card title
Some quick example text to build on the card title and make up the bulk of the card's content.
Card title
Some quick example text to build on the card title and make up the bulk of the card's content.
<template>
<mdb-container>
<mdb-sortable class="row">
<mdb-col sm="4" v-for="element in list11" :key="element.id">
<mdb-card>
<mdb-view hover>
<a href="#!">
<mdb-card-image :src="element.image" alt="Card image cap"></mdb-card-image>
<mdb-mask flex-center waves overlay="white-slight"></mdb-mask>
</a>
</mdb-view>
<mdb-card-body>
<mdb-card-title>Card title</mdb-card-title>
<mdb-card-text>Some quick example text to build on the card title and make up the bulk of the card's
content.</mdb-card-text>
<mdb-btn color="primary">Read more</mdb-btn>
</mdb-card-body>
</mdb-card>
</mdb-col>
</mdb-sortable>
</mdb-container>
</template>
<script>
import mdbSortable from 'mdb-sortable'
import {
mdbContainer,
mdbRow,
mdbCol,
mdbCard,
mdbView,
mdbCardImage,
mdbMask,
mdbCardBody,
mdbCardTitle,
mdbCardText
} from 'mdbvue'
export default {
name: 'app',
components: {
mdbSortable,
mdbContainer,
mdbRow,
mdbCol,
mdbCard,
mdbView,
mdbCardImage,
mdbMask,
mdbCardBody,
mdbCardTitle,
mdbCardText
},
data() {
return {
list11: [{
image: 'https://mdbootstrap.com/img/Photos/Others/images/14.webp',
id: 0
},
{
image: 'https://mdbootstrap.com/img/Photos/Others/images/15.webp',
id: 1
},
{
image: 'https://mdbootstrap.com/img/Photos/Others/images/16.webp',
id: 2
}
]
}
}
}
</script>
Sortable masonry panels
Sortable panels in masonry style. Similar behavior is used in Pinterest.
Panel title that wraps to a new line
This is a longer panel with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.
Panel title
This panel has supporting text below as a natural lead-in to additional content.
Last updated 3 mins ago
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat.
Panel title
This panel has supporting text below as a natural lead-in to additional content.
Last updated 3 mins ago
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.
Panel title
This is a wider panel with supporting text below as a natural lead-in to additional content. This panel has even longer content than the first to show that equal height action.
Last updated 3 mins ago
<template>
<mdb-container>
<mdb-row>
<div class="card-columns">
<mdb-sortable>
<mdb-card>
<mdb-card-body>
<mdb-card-title tag="h5">Panel title that wraps to a new line</mdb-card-title>
<mdb-card-text>This is a longer panel with supporting text below as a natural lead-in to additional
content. This content is a little bit longer.</mdb-card-text>
</mdb-card-body>
</mdb-card>
<mdb-card class="p-3">
<blockquote class="blockquote mb-0 card-body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
<footer class="blockquote-footer">
<small class="text-muted">
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</mdb-card>
<mdb-card>
<mdb-card-body>
<mdb-card-title tag="h5">Panel title</mdb-card-title>
<mdb-card-text>This is a longer panel with supporting text below as a natural lead-in to additional
content.</mdb-card-text>
<mdb-card-text><small class="text-muted">Last updated 3 mins ago</small></mdb-card-text>
</mdb-card-body>
</mdb-card>
<mdb-card class="bg-primary text-white text-center p-3">
<blockquote class="blockquote mb-0">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat.</p>
<footer class="blockquote-footer">
<small>
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</mdb-card>
<mdb-card class="text-center">
<mdb-card-body>
<mdb-card-title tag="h5">Panel title</mdb-card-title>
<mdb-card-text>This is a longer panel with supporting text below as a natural lead-in to additional
content.</mdb-card-text>
<mdb-card-text><small class="text-muted">Last updated 3 mins ago</small></mdb-card-text>
</mdb-card-body>
</mdb-card>
<mdb-card class="text-right p-3">
<blockquote class="blockquote mb-0">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat.</p>
<footer class="blockquote-footer">
<small>
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</mdb-card>
<mdb-card>
<mdb-card-body>
<mdb-card-title tag="h5">Panel title</mdb-card-title>
<mdb-card-text>This is a longer panel with supporting text below as a natural lead-in to additional
content. This panel has even longer content than the first to show that equal height action.
</mdb-card-text>
<mdb-card-text><small class="text-muted">Last updated 3 mins ago</small></mdb-card-text>
</mdb-card-body>
</mdb-card>
</mdb-sortable>
</div>
</mdb-row>
</mdb-container>
</template>
<script>
import mdbSortable from 'mdb-sortable'
import {
mdbContainer,
mdbRow,
mdbCol,
mdbCard,
mdbView,
mdbCardImage,
mdbMask,
mdbCardBody,
mdbCardTitle,
mdbCardText
} from 'mdbvue'
export default {
name: 'app',
components: {
mdbSortable,
mdbContainer,
mdbRow,
mdbCol,
mdbCard,
mdbView,
mdbCardImage,
mdbMask,
mdbCardBody,
mdbCardTitle,
mdbCardText
}
}
</script>
<style>
.card-columns {
-webkit-column-count: 3;
-moz-column-count: 3;
column-count: 3;
-webkit-column-gap: 1.25rem;
-moz-column-gap: 1.25rem;
column-gap: 1.25rem;
orphans: 1;
widows: 1;
}
</style>
Vue Sortable - getting started : download & setup
Download
This plugin requires a purchase.
Buy Vue Sortable Plugin