jQuery: make a dynamic div droppable

67 views Asked by At

I have draggable divs and a table which has a droppable div in the last td of each row. The table can have a new row added. After the new row is added, the droppable div in the last td is not allowing the draggable divs to be dropped.

My code is a mess, apologies, and I am new to the jQuery UI stuff, but I have a codepen you can see here - https://codepen.io/TeeHill/pen/YzvqgRG

<form>
  <input type="text" id="add" placeholder="Add a seafarer..." autocomplete="off">
  <button type="button" value="Submit" id="add-btn" onclick="addSeafarer()"><i class="fa-solid fa-plus"></i></button>
</form>

1 <div class="red draggable"></div>
2 <div class="blue draggable"></div>
3 <div class="green draggable"></div>

<table class="tables_ui" id="t_draggable1">
  <caption>
    <label for="vessel">
      Seafarers
    </label>
  </caption>
  <tr>
    <td colspan="4">
      <input type="text" id="search" onkeyup="nameSearch()" placeholder="Search by name..." autocomplete="off">
    </td>
  </tr>
  <tbody class="t_sortable">
    <tr>
      <th class="no-border"></th>
      <th>Rank</th>
      <th>Name</th>
      <th><i class="fa-solid fa-circle"></i></th>
    </tr>
    <tr>
      <td class="drag-handle"><i class="fa-solid fa-up-down-left-right"></i></td>
      <td>
        <select class="standby"></select>
      </td>
      <td class="name">John Wilson</td>
      <td>
        <div class="droppable"></div>
      </td>
    </tr>
    <tr>
      <td class="drag-handle"><i class="fa-solid fa-up-down-left-right"></i></td>
      <td>
        <select class="standby"></select>
      </td>
      <td class="name">Carl Jobs</td>
      <td>
        <div class="droppable"></div>
      </td>
    </tr>
    <tr>
      <td class="drag-handle"><i class="fa-solid fa-up-down-left-right"></i></td>
      <td>
        <select class="standby"></select>
      </td>
      <td class="name">Aaron Johnson</td>
      <td>
        <div class="droppable"></div>
      </td>
    </tr>
  </tbody>
</table>

<table class="tables_ui" id="t_draggable2">
  <caption>
    <label for="vessel">
      Pride
    </label>
  </caption>
  <tbody class="t_sortable">
    <tr>
      <th class="no-border"></th>
      <th>Rank</th>
      <th>Name</th>
      <th><i class="fa-solid fa-circle"></i></th>
    </tr>
  </tbody>
</table>

<table class="tables_ui" id="t_draggable3">
  <caption>
    <label for="vessel">
      Jaguar
    </label>
  </caption>
  <tbody class="t_sortable">
    <tr>
      <th class="no-border"></th>
      <th>Rank</th>
      <th>Name</th>
      <th><i class="fa-solid fa-circle"></i></th>
    </tr>
  </tbody>
</table>

<!-- copy drag dots -->
<script>
  $('.draggable').draggable({
    revert: "invalid",
    stack: ".draggable",
    helper: 'clone'
  });
</script>
<!-- drop dots -->
<script>
  $('.droppable').droppable({
    accept: ".draggable",
    drop: function(event, ui) {
      var droppable = $(this);
      var draggable = ui.draggable;
      // Move draggable into droppable
      var drag = $('.droppable').has(ui.draggable).length ? draggable : draggable.clone().draggable({
        revert: "invalid",
        stack: ".draggable",
        helper: 'clone'
      });
      drag.appendTo(droppable).addClass("dot").draggable("destroy");
    }
  });
</script>
<!-- add a seafarer -->
<script>
  function addSeafarer() {
    var $name = $('#add').val();
    $('#t_draggable1 tr:last').after('<tr><td class="drag-handle ui-sortable-handle"><i class="fa-solid fa-up-down-left-right"></i></td><td><select class="standby"><option value="0">-</option><option value="1">MASTER</option><option value="2">C/MATE</option><option value="3">2/MATE</option><option value="4">C/ENG</option><option value="5">2/ENG</option><option value="6">BOSUN</option><option value="7">DC/COX</option><option value="8">COX</option><option value="9">COOK</option><option value="10">CADET</option></select></td><td class="name">' + $name + '<td></td></tr>');
    var $newDiv = $("<div class='droppable'></div>").droppable().appendTo("#t_draggable1 td:last");
  };
</script>

I thought by adding the class "ui-droppable" to the dynamic div would make it work but it doesn't. I called the droppable() function on the dynamic div after it is added and it puts the "ui-droppable" class but it still not working.

I believe the code to make the div droppable needs to be called after the new table row is added but I don't know where logically to put this so it works in my case. I also read about "options" but again, I have been unsure about how to use it properly.

Thanks in advance for taking a look and for any advice given. Cheers, T

1

There are 1 answers

0
TomBPOS On

I figured out what to do... I cleaned my code and put the code to make divs droppable into its own function which I call on document ready and then call it again when adding a new row to the table.

https://codepen.io/TeeHill/pen/MWXJvPP

function makeDrag() {
  $(".draggable").draggable({
    revert: "invalid",
    helper: "clone"
  });
}
function makeDrop() {
  $(".droppable").droppable({
    accept: ".draggable",
    drop: function (event, ui) {
      var droppable = $(this);
      var draggable = ui.draggable;
      // Move draggable into droppable
      var drag = $(".droppable").has(ui.draggable).length
        ? draggable
        : draggable.clone().draggable({
            revert: "invalid",
            stack: ".draggable",
            helper: "clone"
          });
      drag.appendTo(droppable).addClass("dot").draggable("destroy");
    }
  });
}
function addRow() {
  var $name = $("#add").val();
  $("#seafarers-table tr:last").after(
    '<tr><td class="drag-handle"><i class="fa-solid fa-up-down-left-right"></i></td><td><select class="standby"><option value="0">-</option><option value="1">MASTER</option><option value="2">C/MATE</option><option value="3">2/MATE</option><option value="4">C/ENG</option><option value="5">2/ENG</option><option value="6">BOSUN</option><option value="7">DC/COX</option><option value="8">COX</option><option value="9">COOK</option><option value="10">CADET</option></select></td><td class="name">' +
      $name +
      '</td><td><div class="droppable"></div></td></tr>'
  );
  makeDrop();
}
$(document).ready(function () {
  makeDrag();
  makeDrop();  
});