Nancy76 Nancy76 - 1 month ago 5
Javascript Question

Limit number of droppable dragged items inside a container

I found this code, and the fiddle that was linked.

This is close to what I am looking for, however I would like to add a counter because I would like list 2 and list 3 to only accept 3 draggable items.

I intend to add more lists to this code for my purposes and they also need to only accept 3 items.

List 1 needs to be able to accept all of the draggable items.

I think I need to create an array with a counter to keep track of all of this, but I don't know how to do that. I don't really understand or know javascript.

Any help with this would be appreciated.

$(document).ready(function(){
$(".droppable").droppable({
drop: function(event, ui) {
var $list = $(this);
$helper = ui.helper;
$($helper).removeClass("selected");
var $selected = $(".selected");
if($selected.length > 1){
moveSelected($list,$selected);
}else{
moveItem(ui.draggable,$list);
}
}, tolerance: "touch"
});

$(".draggable").draggable({
revert: "invalid",
helper: "clone",
cursor: "move",
drag: function(event,ui){
var $helper = ui.helper;
$($helper).removeClass("selected");
var $selected = $(".selected");
if($selected.length > 1){
$($helper).html($selected.length + " items");
}
}
});

function moveSelected($list,$selected){
$($selected).each(function(){
$(this).fadeOut(function(){
$(this).appendTo($list).removeClass("selected").fadeIn();
});
});
}

function moveItem( $item,$list ) {
$item.fadeOut(function() {
$item.find(".item").remove();
$item.appendTo( $list ).fadeIn();
});
}

$(".item").click(function(){
$(this).toggleClass("selected");
});

});


The HTML...

<div id="list1" class="droppable list"><!-- I want this to accept many. -->
<div class="item draggable">1</div>
<div class="item draggable">2</div>
<div class="item draggable">3</div>
<div class="item draggable">4</div>
</div>
<div id="list2" class="droppable list"><!-- I want this to accept only 3. -->
<div class="item draggable">5</div>
<div class="item draggable">6</div>
</div>
<div id="list3" class="droppable list"><!-- I want this to accept only 3. -->
<div class="item draggable">7</div>
</div>

Answer

Added a data-max attribute for each droppable list and inside the drop function you can check if the number of elements inside that list reached the max (limit), and if so - just return false.

Here is the change to your code:

$(document).ready(function(){
  $(".droppable").droppable({
    drop: function(event, ui) {
      var $list = $(this);
      $helper = ui.helper;
      
      // Check if we reached the maximum number of children. 
      if ($(this).children().length == $(this).data('max')) {
        return false;
      }
      
      $($helper).removeClass("selected");
      var $selected = $(".selected");                 
      if($selected.length > 1){                       
        moveSelected($list,$selected);
      }else{
        moveItem(ui.draggable,$list);
      }                                       
    }, tolerance: "touch"
  });

  $(".draggable").draggable({
    revert: "invalid",
    helper: "clone",
    cursor: "move",
    drag: function(event,ui){
      var $helper = ui.helper;
      $($helper).removeClass("selected");
      var $selected = $(".selected"); 
      if($selected.length > 1){   
        $($helper).html($selected.length + " items");
      }                                       
    }
  });

  function moveSelected($list,$selected){
    $($selected).each(function(){
      $(this).fadeOut(function(){
        $(this).appendTo($list).removeClass("selected").fadeIn();
      });                 
    });             
  }

  function moveItem( $item,$list ) {
    $item.fadeOut(function() {
      $item.find(".item").remove();
      $item.appendTo( $list ).fadeIn();
    });
  }

  $(".item").click(function(){
    $(this).toggleClass("selected");
  });

});
div.list {
  border: 1px solid red;
  margin: 5px;
  min-height: 20px;
}
div.list div {
  background: gray;
  margin: 4px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div id="list1" class="droppable list" data-max="-1"><!-- I want this to accept many. -->
  <div class="item draggable">1</div>
  <div class="item draggable">2</div>
  <div class="item draggable">3</div>
  <div class="item draggable">4</div>
</div>
<div id="list2" class="droppable list" data-max="3"><!-- I want this to accept only 3. -->
  <div class="item draggable">5</div>
  <div class="item draggable">6</div>
</div>
<div id="list3" class="droppable list" data-max="3"><!-- I want this to accept only 3. -->
  <div class="item draggable">7</div>
</div>