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="ri-shopping-cart-2-line text-success ri-24px"></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="ri-global-line text-info ri-24px"></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="ri-gift-line text-danger ri-24px"></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="ri-user-3-line text-primary ri-24px"></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 ri-menu-line align-text-bottom me-2"></i>
<span>Buy products</span>
</span>
<img class="rounded-circle" src="..." alt="avatar-1" 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 ri-menu-line align-text-bottom me-2"></i>
<span>Reply to emails</span>
</span>
<img class="rounded-circle" src="..." alt="avatar-2" 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 ri-menu-line align-text-bottom me-2"></i>
<span>Write blog post</span>
</span>
<img class="rounded-circle" src="..." alt="avatar-3" 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 ri-menu-line align-text-bottom me-2"></i>
<span>Update packages</span>
</span>
<img class="rounded-circle" src="..." alt="avatar-4" 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 ri-menu-line align-text-bottom me-2"></i>
<span>New blog layout</span>
</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">
<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 ri-menu-line align-text-bottom me-2"></i>
<span>New icons set for an iOS app</span>
</span>
<img class="rounded-circle" src="..." alt="avatar-1" 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 ri-menu-line align-text-bottom me-2"></i>
<span>Fix validation bugs and commit</span>
</span>
<img class="rounded-circle" src="..." alt="avatar-2" 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 ri-menu-line align-text-bottom me-2"></i>
<span>Help Web developers with HTML integration</span>
</span>
<img class="rounded-circle" src="..." alt="avatar-3" 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 ri-menu-line align-text-bottom me-2"></i>
<span>Buy antivirus</span>
</span>
<img class="rounded-circle" src="..." alt="avatar-4" 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 ri-menu-line align-text-bottom me-2"></i>
<span>Answer support tickets</span>
</span>
<img class="rounded-circle" src="..." alt="avatar-5" 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'
});