Search code examples
jqueryjquery-uidrag-and-dropjquery-eventsjquery-droppable

How to be sure every draggable elements have been dropped with jQuery droppable


I'm making a webpage with a drag & drop system in it.

  • I have a list of 3 buttons, each one is draggable, and can be dropped into an array.
  • In this array, the TDS are droppable and can receive the buttons coming from the previous list, or buttons already placed in array (to switch between columns).
  • The list is droppable too, to reset the position of the buttons, so only available for already placed buttons coming from array.

Everything is working fine, now I want to know if these 3 buttons have been dropped into the array to enable the use to go to the next step.
I have the strong impression that the dragged element is cloned when it is dropped and passing into the drop event. The dropped element is still present in the initial list (from the DOM PoV), but already present too in the array (from the DOM PoV)

Here is the code to test it, console.log to see the element number :

$(document).ready(function() {

  $('.item-draggable').draggable({
    revert: "invalid",
    containment: "document",
    helper: "clone",
    cursor: "move"
  });


  $('.area-droppable').droppable({
    accept: ".item-draggable",
    activeClass: "ui-state-highlight",
    drop: function(event, ui) {
      $(this).html(ui.draggable);

      console.log('nb element still to be dropped : ' + $('#items-draggable div').length);
      console.log('nb element already dropped placed : ' + $('.area-droppable div').length);

      /*if($('#items-draggable div').length === 0)
				$('#validate-step').removeAttr('disabled');
			else
				$('#validate-step').attr('disabled','disabled');*/

    }
  });
  
  $('#items-draggable').droppable({
			accept: ".area-droppable div.item-draggable",
			activeClass: "ui-state-highlight",
			drop: function( event, ui ) {
				$(this).append(ui.draggable);
				$('#validate-step').attr('disabled','disabled');
			}
		});

});
#items-draggable {
  border: 1px dashed black;
  border-radius: 4px;
  padding: 5px;
  margin-bottom: 10px;
  min-height: 57px;
}
.item-draggable {
  margin: 0 2px;
  cursor: move;
}
.table-csv {
  width: 100%;
}
.table-csv tr {
  border: 1px solid blue !important;
}
.table-csv td {
  border: 1px solid blue !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

<div id="items-draggable">
  <div class="btn btn-default item-draggable" id="btn1">BTN1</div>
  <div class="btn btn-default item-draggable" id="btn2">BTN2</div>
  <div class="btn btn-default item-draggable" id="btn3">BTN3</div>
</div>

<div id="table-csv-container">
  <div class="table-responsive">
    <table class="table table-csv" id="table-csv">
      <tbody>
        <tr>
          <td class="area-droppable td td-1" id="td-droppable-1">&nbsp;</td>
          <td class="area-droppable td td-2" id="td-droppable-2">&nbsp;</td>
          <td class="area-droppable td td-3" id="td-droppable-3">&nbsp;</td>
          <td class="area-droppable td td-4" id="td-droppable-4">&nbsp;</td>
          <td class="area-droppable td td-5" id="td-droppable-5">&nbsp;</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

<input type="button" class="btn btn-success" disabled="disabled" id="validate-step" value="Validate">

From my tests :

  • When I move a button from list to array, at the end of the drop event, the DOM is still seeing 3 buttons remaining in the list, but already seeing 1 button dropped in array --> Counting remaining buttons is then not a solution to be sure there is 0 element remaining

  • When I switch a button between two columns, it makes the DOM think there is one more button in drop event (cloning the button into new position before removing the one from the original place) --> Not a good solution there neither

So what can I do to be sure all my draggable elements are in fact dropped in my array ?

Thanks in advance !

Julien Q.


Solution

  • Moving my comment to an answer. You have helper: "clone", so the dragged item is a clone. Removing this can address the issue.