Germano Plebani
Germano Plebani

Reputation: 3625

Jquery UI sorting multiple table row at once

I have a problem with jqueryui sorting.

Now i have a table with sorting on tr and it's all working, but now i have to sort 2 row at once. In the example below i have to sort together row with G1 or G2 or G3.

Now after having beaten my head against the wall for hours i'm here to ask for help.

Queryui sort have the option item, i try to use it but can't make itwork in table.

There is a way to do that? Anyone can help me?

I try here https://jsfiddle.net/n29ekt42/

    <table>
    <thead>
        <tr>
            <th>T1</th>
            <th>T1</th>
            <th>T1</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>G1</td>
            <td>G1</td>
            <td>G1</td>
        </tr>
        <tr>
            <td>G1</td>
            <td>G1</td>
            <td>G1</td>
        </tr>
        <tr>
            <td>G2</td>
            <td>G2</td>
            <td>G2</td>
        </tr>
        <tr>
            <td>G2</td>
            <td>G2</td>
            <td>G2</td>
        </tr>
        <tr>
            <td>G3</td>
            <td>G3</td>
            <td>G3</td>
        </tr>
        <tr>
            <td>G3</td>
            <td>G3</td>
            <td>G3</td>
        </tr>
    </tbody>
    </table>

   function assignSortAttach() {

    $("table tbody").sortable({
        start: function( event, ui ) {
            var aa = $this.attr('data-row');
        }
    })
}

// TR sortable
$(function () {
    assignSortAttach()
});

Upvotes: 2

Views: 5202

Answers (1)

Twisty
Twisty

Reputation: 30883

I found that this was more difficult than I anticipated, so I took a stab at it. I forked your fiddle and made some updates.

Working Example: https://jsfiddle.net/Twisty/n29ekt42/13/

I added a handle column.

HTML

<table>
  <thead>
    <tr>
      <th></th>
      <th>T1</th>
      <th>T1</th>
      <th>T1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><span class="handle ui-icon ui-icon-grip-dotted-vertical"></span></td>
      <td>G1</td>
      <td>G1</td>
      <td>G1</td>
    </tr>
...

Lots of CSS, if you like.

CSS

table {
  border-collapse: collapse;
}

table thead tr {
  margin-left: 20px;
}

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

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

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

.hidden {
  display: none;
}

jQuery

function assignSortAttach() {
  $("table tbody").sortable({
      axis: "y",
      cursor: "grabbing",
      handle: ".handle",
      opacity: 0.6,
      helper: function(e, item) {
        console.log("Parent-Helper: ", item);
        if (!item.hasClass("ui-selected")) {
          item.addClass("ui-selected");
        }
        // Clone selected elements
        var elements = $(".ui-selected").not('.ui-sortable-placeholder').clone();
        console.log("Making helper: ", elements);
        // Hide selected Elements
        item.siblings(".ui-selected").addClass("hidden");
        var helper = $("<table />");
        helper.append(elements);
        console.log("Helper: ", helper);
        return helper;
      },
      start: function(e, ui) {
        var elements = ui.item.siblings(".ui-selected.hidden").not('.ui-sortable-placeholder');
        ui.item.data("items", elements);
      },
      update: function(e, ui) {
        console.log("Receiving: ", ui.item.data("items"));
        $.each(ui.item.data("items"), function(k, v) {
          console.log("Appending ", v, " before ", ui.item);
          ui.item.before(v);
        });
      },
      stop: function(e, ui) {
        ui.item.siblings(".ui-selected").removeClass("hidden");
        $("tr.ui-selected").removeClass("ui-selected");
      }
    })
    .selectable({
      filter: "tr",
      cancel: ".handle"
    })
}

$(function() {
  assignSortAttach();
});

This is adapted from the code here: jQuery Sortable - drag and drop multiple items and here: jQuery UI sortable & selectable

Credit for using Sort and Select together goes to mhu. This works really well, since you can drag-select or CTRL+Click to select the Rows as you like. You can drag and select a group or click unqiue items that will group ion the drag. Then using the drag handle, the user can sort the selected rows.

TJ gives us the ability to sort multiple items. His Demo is designed to move elements between separate lists, so I switched events receive with update.

From flippant comment to an answer, I hope that helps.

Updates after Comments


Working example: https://jsfiddle.net/Twisty/Lbu7ytbj/

I change the HTML to group the rows:

<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>

Now all I had to do was adjust the sortable to use the table and not use the thead.

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.");
});

I also added CSS for the placeholder:

.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;
}

Upvotes: 5

Related Questions