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}`);
  }
})