jQuery UI Sortable of multiple

Reference: http://stackoverflow.com/questions/3390786/jquery-ui-sortable-selectable http://stackoverflow.com/questions/23077146/jquery-sortable-drag-and-drop-multiple-items

by Twisty

HTML

<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
<table>
  <thead>
    <tr>
      <th>&nbsp;</th>
      <th>T1</th>
      <th>T1</th>
      <th>T1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan="2"><span data-group="1" class="handle ui-icon ui-icon-grip-dotted-vertical"></span></td>
      <td>G1</td>
      <td>G1</td>
      <td>G1</td>
    </tr>
    <tr>
      <td>G1</td>
      <td>G1</td>
      <td>G1</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <td rowspan="2"><span data-group="3" class="handle ui-icon ui-icon-grip-dotted-vertical"></span></td>
      <td>G2</td>
      <td>G2</td>
      <td>G2</td>
    </tr>
    <tr>
      <td>G2</td>
      <td>G2</td>
      <td>G2</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <td rowspan="2"><span data-group="5" class="handle ui-icon ui-icon-grip-dotted-vertical"></span></td>
      <td>G3</td>
      <td>G3</td>
      <td>G3</td>
    </tr>
    <tr>
      <td>G3</td>
      <td>G3</td>
      <td>G3</td>
    </tr>
  </tbody>
</table>

CSS

table {
  border-collapse: collapse;
  width: 100px;
  max-width: 100px;
}

table tbody tr {
  border: 1px solid #ccc;
}

table tbody tr td {
  text-align: center;
}

table tr td:first-child,
table tr th:first-child {
  width: 8px;
  text-align: left;
  overflow: hidden;
}

table tr td[rowspan='2'] {
  background: #ccc;
}

tr.ui-selecting {
  background: #FECA40;
}

tr.ui-selected {
  background: #F39814;
  color: white;
}

.handle {
  display: inline-block;
  margin: 0 -4px;
}

.hidden {
  display: none;
}

.two-place {
  display: block;
  visibility: visible;
  height: 2.5em;
  width: 0;
}

.two-place::after {
  content: "";
  border: 1px dashed #ccc;
  float: left;
  background-color: #eee;
  height: 2.5em;
  width: 100px;
}

JavaScript

function assignSortAttach() {
  $("table").sortable({
    axis: "y",
    cursor: "grabbing",
    handle: ".handle",
    cancel: "thead",
    opacity: 0.6,
    placeholder: "two-place",
    helper: function(e, item) {
      if (!item.hasClass("selected")) {
        item.addClass("selected");
      }
      console.log("Selected: ", $(".selected"));
      var elements = $(".selected").not(".ui-sortable-placeholder").clone();
      console.log("Making helper from: ", elements);
      // Hide selected Elements
      $(".selected").not(".ui-sortable-placeholder").addClass("hidden");
      var helper = $("<table />");
      helper.append(elements);
      console.log("Helper: ", helper);
      return helper;
    },
    start: function(e, ui) {
      var elements = $(".selected.hidden").not('.ui-sortable-placeholder');
      console.log("Start: ", elements);
      ui.item.data("items", elements);
    },
    update: function(e, ui) {
      console.log("Receiving: ", ui.item.data("items"));
      ui.item.before(ui.item.data("items")[1], ui.item.data("items")[0]);
    },
    stop: function(e, ui) {
      $('.selected.hidden').not('.ui-sortable-placeholder').removeClass('hidden');
      $('.selected').removeClass('selected');
    }
  });
}

$(function() {
  assignSortAttach();
  $(".handle").attr("title", "Use me to drag and sort.");
});