Cannot move row to the table without row

34 Views Asked by At

I have two tables and can move the table to each other. There is a issue . After all rows remove from table1 to table 2, it cannot move row from table2 to table1. Would someone tell me how to fix it. Thanks in advance.

There is the code:

$(function() {
  $('.draggable_tr').draggable({
    helper: 'clone',
    revert: 'invalid'
  });

  $('.childgrid tbody').droppable({
    drop: function(event, ui) {
      var draggableRow = ui.draggable;
      var draggableTable = draggableRow.closest('.childgrid');
      var droppableTable = $(this).closest('.childgrid');
      var droppableRowIndex = $(this).children().index(ui.helper);
      var draggableRowIndex = draggableTable.children().index(draggableRow);

      if (droppableTable.attr('id') !== draggableTable.attr('id')) {
        draggableRow.remove();
        if (droppableRowIndex === 0) {
          $(this).prepend(draggableRow);
        } else if (droppableRowIndex === droppableTable.children().length - 1) {
          $(this).append(draggableRow);
        } else {
          $(this).children().eq(droppableRowIndex).before(draggableRow);
        }

      } else if (droppableRowIndex !== draggableRowIndex) {
        if (droppableRowIndex === 0) {
          $(this).prepend(draggableRow);
        } else if (droppableRowIndex === droppableTable.children().length - 1) {
          $(this).append(draggableRow);
        } else if (droppableRowIndex > draggableRowIndex) {
          $(this).children().eq(droppableRowIndex).after(draggableRow);
        } else {
          $(this).children().eq(droppableRowIndex).before(draggableRow);
        }

      }
      re
    }
  });
<div id="table1" class="bitacoratable">
  <table id="table1" class="childgrid">
    <tbody>
      <tr class="draggable_tr">
        <td>1</td>
        <td>Student 1</td>
      </tr>
      <tr class="draggable_tr">
        <td>2</td>
        <td>Student 2</td>
      </tr>
      <tr class="draggable_tr">
        <td>3</td>
        <td>Student 3</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="table2" class="bitacoratable">
  <table id="table2" class="childgrid">
    <tbody>
      <tr class="draggable_tr">
        <td>6</td>
        <td>Student 6</td>
      </tr>
      <tr class="draggable_tr">
        <td>7</td>
        <td>Student 7</td>
      </tr>
      <tr class="draggable_tr">
        <td>8</td>
        <td>Student 8</td>
      </tr>
      </<tbody>
  </table>

</div>

1

There are 1 best solutions below

0
Twisty On

First, consider the following.

$(function() {
  $('.draggable_tr').draggable({
    helper: 'clone',
    revert: 'invalid'
  });

  $('.childgrid tbody').droppable({
    drop: function(event, ui) {
      var draggableRow = ui.draggable;
      var draggableTable = draggableRow.closest('.childgrid');
      var droppableTable = $(this).closest('.childgrid');
      var droppableRowIndex = $(this).children().index(ui.helper);
      var draggableRowIndex = draggableTable.children().index(draggableRow);

      if (droppableTable.attr('id') !== draggableTable.attr('id')) {
        draggableRow.remove();
        if (droppableRowIndex === 0) {
          $(this).prepend(draggableRow);
        } else if (droppableRowIndex === droppableTable.children().length - 1) {
          $(this).append(draggableRow);
        } else {
          $(this).children().eq(droppableRowIndex).before(draggableRow);
        }

      } else if (droppableRowIndex !== draggableRowIndex) {
        if (droppableRowIndex === 0) {
          $(this).prepend(draggableRow);
        } else if (droppableRowIndex === droppableTable.children().length - 1) {
          $(this).append(draggableRow);
        } else if (droppableRowIndex > draggableRowIndex) {
          $(this).children().eq(droppableRowIndex).after(draggableRow);
        } else {
          $(this).children().eq(droppableRowIndex).before(draggableRow);
        }

      }
    }
  });
});
table {
  background: #eee;
  margin: 1px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<div id="table1" class="bitacoratable">
  <table id="table1" class="childgrid">
    <tbody>
      <tr class="draggable_tr">
        <td>1</td>
        <td>Student 1</td>
      </tr>
      <tr class="draggable_tr">
        <td>2</td>
        <td>Student 2</td>
      </tr>
      <tr class="draggable_tr">
        <td>3</td>
        <td>Student 3</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="table2" class="bitacoratable">
  <table id="table2" class="childgrid">
    <tbody>
      <tr class="draggable_tr">
        <td>6</td>
        <td>Student 6</td>
      </tr>
      <tr class="draggable_tr">
        <td>7</td>
        <td>Student 7</td>
      </tr>
      <tr class="draggable_tr">
        <td>8</td>
        <td>Student 8</td>
      </tr>
    </tbody>
  </table>
</div>

When all rows are removed from the table body, there is nothing to render. The table and body essentially have a height of 0 and cannot be targeted for Drop.

As suggested, you need to allow it to be rendered in some way.

$(function() {

  function makeDragItem(el) {
    $(el).draggable({
      helper: 'clone',
      revert: 'invalid'
    });
  }

  makeDragItem($('.draggable_tr'));

  $('.childgrid tbody').droppable({
    drop: function(event, ui) {
      var draggableRow = ui.draggable;
      var draggableTable = draggableRow.closest('.childgrid');
      var droppableTable = $(this).closest('.childgrid');
      var droppableRowIndex = $(this).children().index(ui.helper);
      var draggableRowIndex = draggableTable.children().index(draggableRow);

      if (droppableTable.attr('id') !== draggableTable.attr('id')) {
        draggableRow.detach();
        if (droppableRowIndex === 0) {
          $(this).prepend(draggableRow);
        } else if (droppableRowIndex === droppableTable.children().length - 1) {
          $(this).append(draggableRow);
        } else {
          $(this).children().eq(droppableRowIndex).before(draggableRow);
        }
      } else if (droppableRowIndex !== draggableRowIndex) {
        if (droppableRowIndex === 0) {
          $(this).prepend(draggableRow);
        } else if (droppableRowIndex === droppableTable.children().length - 1) {
          $(this).append(draggableRow);
        } else if (droppableRowIndex > draggableRowIndex) {
          $(this).children().eq(droppableRowIndex).after(draggableRow);
        } else {
          $(this).children().eq(droppableRowIndex).before(draggableRow);
        }
      }

      makeDragItem(draggableRow);

      // If Target is Empty, clear placeholder
      if ($("tr.empty", this).length != 0) {
        $("tr.empty", this).remove();
      }

      // If source is empty, add placeholder
      if (draggableTable.find("tr").length == 1) {
        $("<tr>", {
          class: "empty"
        }).appendTo(draggableTable.find("tbody"));
        $("<td>").html("&nbsp;").appendTo(draggableTable.find("tr"));
        $("<td>").html("&nbsp;").appendTo(draggableTable.find("tr"));
      }
    }
  });
});
table {
  background: #eee;
  margin: 1px;
  width: 150px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<div id="table1" class="bitacoratable">
  <table id="table1" class="childgrid">
    <tbody>
      <tr class="draggable_tr">
        <td>1</td>
        <td>Student 1</td>
      </tr>
      <tr class="draggable_tr">
        <td>2</td>
        <td>Student 2</td>
      </tr>
      <tr class="draggable_tr">
        <td>3</td>
        <td>Student 3</td>
      </tr>
    </tbody>
  </table>
</div>
<div id="table2" class="bitacoratable">
  <table id="table2" class="childgrid">
    <tbody>
      <tr class="draggable_tr">
        <td>6</td>
        <td>Student 6</td>
      </tr>
      <tr class="draggable_tr">
        <td>7</td>
        <td>Student 7</td>
      </tr>
      <tr class="draggable_tr">
        <td>8</td>
        <td>Student 8</td>
      </tr>
    </tbody>
  </table>
</div>

Here you can see a Placeholder is created and items are re-initialized so they can be dragged after being dropped.