Bootstrap Card Sortable
bs5 card with sortablejs
by Soya Natsuki
HTML
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/css/all.css">
</head>
<body>
<div class="main overflow-hidden">
<div class="row gx-7">
<div class="col">
<h1>Todos</h1>
<div class="border border-secondary rounded p-2 sortable-list" id="sortable_1">
<div class="card text-dark bg-light mb-3" style="max-width: 18rem;" data-id="1">
<div class="card-header"><i class="fas fa-bars handle"></i> Header #1</div>
<div class="card-body">
<h5 class="card-title">Light card title</h5>
<p class="card-text">Some quick example text to build</p>
</div>
</div>
<div class="card text-dark bg-light mb-3" style="max-width: 18rem;" data-id="2">
<div class="card-header"><i class="fas fa-bars handle"></i> Header #2</div>
<div class="card-body">
<h5 class="card-title">Light card title</h5>
<p class="card-text">Some quick example text to build</p>
</div>
</div>
<div class="card text-dark bg-light mb-3" style="max-width: 18rem;" data-id="3">
<div class="card-header"><i class="fas fa-bars handle"></i> Header #3</div>
<div class="card-body">
<h5 class="card-title">Light card title</h5>
<p class="card-text">Some quick example text to build</p>
</div>
</div>
<div class="card text-dark bg-light mb-3" style="max-width: 18rem;" data-id="4">
<div class="card-header"><i class="fas fa-bars handle"></i> Header #4</div>
<div class="card-body">
<h5 class="card-title">Light card title</h5>
<p class="card-text">Some...
CSS
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
}
.main {
padding: 2rem;
}
.handle {
cursor: grab;
}
.sortable-list .card:last-child {
margin-bottom: 0!important;
}
JavaScript
/*
Serialized Sortable List Data Structure
serializedData = {
list_1: [
{
id: 0,
listId: 0,
title: 'Header #1',
content: '...'
},
{
id: 1,
listId: 1,
title: 'Header #2',
content: '...'
}
],
list_2: [
{
id: 2,
listId: 0,
title: 'Header #3',
content: '...'
},
{
id: 3,
listId: 1,
title: 'Header #4',
content: '...'
}
],
list_3: [
{
id: 4,
listId: 0,
title: 'Header #5',
content: '...'
},
{
id: 5,
listId: 1,
title: 'Header #6',
content: '...'
}
]
}
*/
const list_1 = new Sortable(sortable_1, {
group: {
name: 'workspace'
},
handle: '.handle',
animation: 150,
ghostClass: 'bg-success',
onStart: function({oldIndex}) {
console.log(`#${oldIndex} dragged`);
},
onEnd: function({to, from, oldIndex, newIndex}) {
console.log(`#${oldIndex} moved from #${from.id} to #${to.id} changed into #${newIndex}`);
}
})
const list_2 = new Sortable(sortable_2, {
group: {
name: 'workspace'
},
handle: '.handle',
animation: 150,
ghostClass: 'bg-success',
onStart: function({oldIndex}) {
console.log(`#${oldIndex} dragged`);
},
onEnd: function({to, from, oldIndex, newIndex}) {
console.log(`#${oldIndex} moved from #${from.id} to #${to.id} changed into #${newIndex}`);
}
})
const list_3 = new Sortable(sortable_3, {
group: {
name: 'workspace'
},
handle: '.handle',
animation: 150,
ghostClass: 'bg-success',
onStart: function({oldIndex}) {
console.log(`#${oldIndex} dragged`);
},
onEnd: function({to, from, oldIndex, newIndex}) {
console.log(`#${oldIndex} moved from #${from.id} to #${to.id} changed into #${newIndex}`);
}
})