We are using SortableJS for drag and drop. SortableJS is a JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices.
Read the official SortableJS Documentation for a full list of instructions and other options.
In order to use SortableJS on your page, It is required to include the following vendors script in the "Vendors JS" area from the page's footer:
<script src="assets/vendor/libs/sortablejs/sortable.js" />
Cards
You can make any element draggable with sortableJS. All you have to do is Sortable.create(El);
Please Note: For RTL version, if you're using display: flex;
style as a wrapper for your draggables, you'll
have to add flex-direction: row-reverse;
style and you may optionally need to add justify-content: flex-end;
style.
<div class="row" id="sortable-cards">
<div class="col-lg-3 col-md-6 col-sm-12">
<div class="card drag-item cursor-move mb-lg-0 mb-6">
<div class="card-body text-center">
<h2>
<i class="ti ti-shopping-cart text-success display-6"></i>
</h2>
<h4>Monthly Sales</h4>
<h5>2362</h5>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 col-sm-12">
<div class="card drag-item cursor-move mb-lg-0 mb-6">
<div class="card-body text-center">
<h2>
<i class="ti ti-world text-info display-6"></i>
</h2>
<h4>Monthly Visits</h4>
<h5>687,123</h5>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 col-sm-12">
<div class="card drag-item cursor-move mb-lg-0 mb-6">
<div class="card-body text-center">
<h2>
<i class="ti ti-gift text-danger display-6"></i>
</h2>
<h4>Products</h4>
<h5>985</h5>
</div>
</div>
</div>
<div class="col-lg-3 col-md-6 col-sm-12">
<div class="card drag-item cursor-move mb-lg-0 mb-6">
<div class="card-body text-center">
<h2>
<i class="ti ti-user text-primary display-6"></i>
</h2>
<h4>Users</h4>
<h5>105,652</h5>
</div>
</div>
</div>
</div>
const cardEl = document.getElementById('sortable-cards');
Sortable.create(cardEl);
Images
You can also use images as items for drag and drop.
<div class="dnd-images">
<div class="d-flex flex-wrap mb-4 gap-2" id="image-list-1">
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-1" height="48" width="48" />
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-2" height="48" width="48" />
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-3" height="48" width="48" />
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-4" height="48" width="48" />
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-5" height="48" width="48" />
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-6" height="48" width="48" />
</div>
<div class="d-flex flex-wrap gap-2" id="image-list-2">
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-7" height="48" width="48" />
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-8" height="48" width="48" />
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-9" height="48" width="48" />
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-10" height="48" width="48" />
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-11" height="48" width="48" />
<img class="rounded-circle drag-item cursor-move" src="..." alt="avatar-12" height="48" width="48" />
</div>
</div>
const imageList1 = document.getElementById('image-list-1');
const imageList2 = document.getElementById('image-list-2');
Sortable.create(imageList1, {
animation: 150,
group: 'imgList'
});
Sortable.create(imageList2, {
animation: 150,
group: 'imgList'
});
Multiple Lists
Use group
parameter to create multiple drag and drop list.
<div class="row">
<div class="col-md-6 col-12 mb-md-0 mb-6">
<h5>Pending Tasks</h5>
<ul class="list-group list-group-flush" id="pending-tasks">
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Buy products.</span>
<img class="rounded-circle" src="..." alt="avatar-1" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Reply to emails.</span>
<img class="rounded-circle" src="..." alt="avatar-2" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Write blog post.</span>
<img class="rounded-circle" src="..." alt="avatar-3" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Update packages.</span>
<img class="rounded-circle" src="..." alt="avatar-4" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>New blog layout.</span>
<img class="rounded-circle" src="..." alt="avatar-5" height="32" width="32" />
</li>
</ul>
</div>
<div class="col-md-6 col-12 mb-md-0 mb-6">
<h5>Completed Tasks</h5>
<ul class="list-group list-group-flush" id="completed-tasks">
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>New icons set for an iOS app.</span>
<img class="rounded-circle" src="..." alt="avatar-1" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span> Fix validation bugs and commit.</span>
<img class="rounded-circle" src="..." alt="avatar-2" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span> Help Web developers with HTML integration.</span>
<img class="rounded-circle" src="..." alt="avatar-3" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Buy antivirus.</span>
<img class="rounded-circle" src="..." alt="avatar-4" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Answer support tickets.</span>
<img class="rounded-circle" src="..." alt="avatar-5" height="32" width="32" />
</li>
</ul>
</div>
</div>
const pendingTasks = document.getElementById('pending-tasks');
const completedTasks = document.getElementById('completed-tasks');
Sortable.create(pendingTasks, {
animation: 150,
group: 'taskList'
});
Sortable.create(completedTasks, {
animation: 150,
group: 'taskList'
});
Cloning
Use pull:"clone"
parameter to make a cloning list.
<div class="row">
<div class="col-md-6 col-12 mb-md-0 mb-6">
<h5>Pending Tasks</h5>
<ul class="list-group list-group-flush" id="clone-source-1">
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Buy products.</span>
<img class="rounded-circle" src="..." alt="avatar-1" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Reply to emails.</span>
<img class="rounded-circle" src="..." alt="avatar-2" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Write blog post.</span>
<img class="rounded-circle" src="..." alt="avatar-3" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Update packages.</span>
<img class="rounded-circle" src="..." alt="avatar-4" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>New blog layout.</span>
<img class="rounded-circle" src="..." alt="avatar-5" height="32" width="32" />
</li>
</ul>
</div>
<div class="col-md-6 col-12 mb-md-0 mb-6">
<h5>Completed Tasks</h5>
<ul class="list-group list-group-flush" id="clone-source-2">
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>New icons set for an iOS app.</span>
<img class="rounded-circle" src="..." alt="avatar-1" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span> Fix validation bugs and commit.</span>
<img class="rounded-circle" src="..." alt="avatar-2" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span> Help Web developers with HTML integration.</span>
<img class="rounded-circle" src="..." alt="avatar-3" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Buy antivirus.</span>
<img class="rounded-circle" src="..." alt="avatar-4" height="32" width="32" />
</li>
<li class="list-group-item drag-item cursor-move d-flex justify-content-between align-items-center">
<span>Answer support tickets.</span>
<img class="rounded-circle" src="..." alt="avatar-5" height="32" width="32" />
</li>
</ul>
</div>
</div>
const cloneSource1 = document.getElementById('clone-source-1');
const cloneSource2 = document.getElementById('clone-source-2');
Sortable.create(cloneSource1, {
animation: 150,
group: {
name: 'cloneList',
pull: 'clone',
revertClone: true
}
});
Sortable.create(cloneSource2, {
animation: 150,
group: {
name: 'cloneList',
pull: 'clone',
revertClone: true
}
});
Handle
Use handle
parameter to create a list which can only be moved
with handle.
Pending Tasks
Completed Tasks
<div class="row">
<div class="col-md-6 col-12 mb-md-0 mb-6">
<p>Pending Tasks</p>
<ul class="list-group list-group-flush" id="handle-list-1">
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="d-flex justify-content-between align-items-center">
<i class="drag-handle cursor-move ti ti-menu-2 align-text-bottom me-2"></i>
<span>Buy products</span>
</span>
<img class="rounded-circle" src="assets/img/avatars/1.png" alt="avatar" height="32" width="32" />
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="d-flex justify-content-between align-items-center">
<i class="drag-handle cursor-move ti ti-menu-2 align-text-bottom me-2"></i>
<span>Reply to emails</span>
</span>
<img class="rounded-circle" src="assets/img/avatars/2.png" alt="avatar" height="32" width="32" />
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="d-flex justify-content-between align-items-center">
<i class="drag-handle cursor-move ti ti-menu-2 align-text-bottom me-2"></i>
<span>Write blog post</span>
</span>
<img class="rounded-circle" src="assets/img/avatars/3.png" alt="avatar" height="32" width="32" />
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="d-flex justify-content-between align-items-center">
<i class="drag-handle cursor-move ti ti-menu-2 align-text-bottom me-2"></i>
<span>Update packages</span>
</span>
<img class="rounded-circle" src="assets/img/avatars/4.png" alt="avatar" height="32" width="32" />
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="d-flex justify-content-between align-items-center">
<i class="drag-handle cursor-move ti ti-menu-2 align-text-bottom me-2"></i>
<span>New blog layout</span>
</span>
<img class="rounded-circle" src="assets/img/avatars/5.png" alt="avatar" height="32" width="32" />
</li>
</ul>
</div>
<div class="col-md-6 col-12 mb-md-0 mb-6">
<p>Completed Tasks</p>
<ul class="list-group list-group-flush" id="handle-list-2">
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="d-flex justify-content-between align-items-center">
<i class="drag-handle cursor-move ti ti-menu-2 align-text-bottom me-2"></i>
<span>New icons set for an iOS app</span>
</span>
<img class="rounded-circle" src="assets/img/avatars/1.png" alt="avatar" height="32" width="32" />
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="d-flex justify-content-between align-items-center">
<i class="drag-handle cursor-move ti ti-menu-2 align-text-bottom me-2"></i>
<span>Fix validation bugs and commit</span>
</span>
<img class="rounded-circle" src="assets/img/avatars/2.png" alt="avatar" height="32" width="32" />
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="d-flex justify-content-between align-items-center">
<i class="drag-handle cursor-move ti ti-menu-2 align-text-bottom me-2"></i>
<span>Help Web developers with HTML integration</span>
</span>
<img class="rounded-circle" src="assets/img/avatars/3.png" alt="avatar" height="32" width="32" />
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="d-flex justify-content-between align-items-center">
<i class="drag-handle cursor-move ti ti-menu-2 align-text-bottom me-2"></i>
<span>Buy antivirus</span>
</span>
<img class="rounded-circle" src="assets/img/avatars/4.png" alt="avatar" height="32" width="32" />
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="d-flex justify-content-between align-items-center">
<i class="drag-handle cursor-move ti ti-menu-2 align-text-bottom me-2"></i>
<span>Answer support tickets</span>
</span>
<img class="rounded-circle" src="assets/img/avatars/5.png" alt="avatar" height="32" width="32" />
</li>
</ul>
</div>
</div>
const handleList1 = document.getElementById('handle-list-1');
const handleList2 = document.getElementById('handle-list-2');
Sortable.create(handleList1, {
animation: 150,
group: 'handleList',
handle: '.drag-handle'
});
Sortable.create(handleList2, {
animation: 150,
group: 'handleList',
handle: '.drag-handle'
});