jQuery droppable - allow only one item to be dropp

2020-02-13 06:37发布

with jQuery droppable, I have multiple draggables and droppable as well. Only one draggable should be allowed to be dropped on an element at a time. However, after dropping, the draggable should be given the dragging capability again. The problem I am facing is that multiple draggable can be dropped on one element. My code follows:

<div id="draggable_all" style="float: left;  width: 300px;">
<div class="draggable">drag1111</div>
<div class="draggable">drag2222</div>
<div class="draggable">drag3333</div>
</div>

<div id="droppable_all" style="float: left; width:300px; ">



<div class="droppable"></div>
<div class="droppable"></div>
<div class="droppable"></div>
</div>

CSS:

 <style type="text/css">
        .droppable {
            width: 120px;
            height: 120px;
            background: red;
            margin-bottom: 30px;
            /*position: absolute;*/
            /*right: 0;*/
            /*bottom: 0;*/
        }
        .draggable {
            /*position: absolute;*/
            z-index: 9;
            /*top: 25px;*/
            /*left: 20px;*/
            width: 120px;
            height: 120px;
            background-color: green;
            margin-bottom: 30px;
        }
    </style>

and JS:

$(document).ready(function () {

    $(".draggable").draggable({
        revert: handleRevert
    });

    $(".draggable").data("orDraggable",$(".draggable").offset());

    $(".droppable").droppable({
        drop: handleDropEvent
        //,
        // out: function(event, ui){
        //     $(this).droppable('option', 'accept', '.drag-item');
        // }
    });

    function handleRevert(e) {
        if (e === false) {
            $(this).data("uiDraggable").originalPosition = $(this).data("orDraggable");
            return true
        }
    }

    function handleDropEvent(event, ui) {
        ui.draggable.position({
            of: $(this),
            my: 'left top',
            at: 'left top'
        });

        //$(this).droppable('option', 'accept', ui.draggable);
       // $(this).droppable('disable');


    }

});

How to achieve that ?

PS: SO has similar questions but none solves my problem well. For example , this question tries to solve it. But the problem here is : the dropped element does not have the same alignment against the element on which it is dropped.

EDIT: I made a jsfiddle here with a bit change in CSS.

1条回答
2楼-- · 2020-02-13 07:24

As I mentioned in my comment, you can disable or destroy Droppable when the item is dropped. This will prevent further drops. You can also change the accept option so that it will not accept any more if you like.

Here is an example of the first solutions: https://jsfiddle.net/Twisty/upfy74tw/12/

JavaScript

$(function() {
  function handleRevert(e) {
    var $t = $(this);
    if (e === false) {
      $t.data("uiDraggable").originalPosition = $t.data("orDraggable");
      return true
    }
  }

  function handleDropEvent(event, ui) {
    var $self = $(this);
    var $item = ui.draggable;
    $item.position({
      my: 'left top',
      at: 'left top',
      of: $self
    });
    $self.droppable("destroy");
    $item.appendTo($self).attr("style", "");
    $item.draggable("destroy");
    $item.draggable({
      start: function() {
        $self.droppable({
          drop: handleDropEvent
        });
      }
    })
  }

  $(".draggable").draggable({
    revert: handleRevert
  });

  $(".draggable").data("orDraggable", $(".draggable").offset());

  $(".droppable").droppable({
    drop: handleDropEvent
  });
});

There are a few things going on in your drop event.

  1. Destroy droppable
  2. Align the draggable and then append it to the container
  3. Destroy draggable
  4. Assign Draggable and re-assign Droppable at start of drag event

Hope that helps.

查看更多
登录 后发表回答