skip to Main Content

i work with dragable object, and i have problem with final destination, when i press Add Item in Dropbox create element, this element i wanna to drag Final Destination box, for some reason it’s droped not in box but out side, i think problems is with first "TOP, LEFT" positions i see when i drop in new box previus left and top position are not changing, after droping positions are update and i can work, but for me it’s not good.

How i can some how delete prev position "TOP, LEFT" or some how to minus from "TOP, LEFT" to drop inside box but not out side.

Here u can see example how it’s drop out the box:
Here u can see example how it's drop out the box

I create jsFiddle with code.

JS:

 $(document).ready(function () {
    $("#addBtn").click(function () {
        var $div = $("<div>", { "class": "alert alert-info draggable alwaysTop", text: "Say-Da-Tay!" }).draggable();

        $("#dropbox").prepend($div);
    });

    $(".droppable").droppable({
        accept: ".draggable", drop: function (event, ui) {
            var dropped = ui.draggable;
            var droppedOn = $(this);
            $(dropped).detach().appendTo(droppedOn);
        }
    });
   
});

One solution i found setup the positions:

$(dropped).detach().css({left: 0, top: 0}).appendTo(droppedOn);

But it this case it’s no possible to drag element where i want, it’s allways connect to left corner. I stuck with this and i cant solve this issues 🙁

2

Answers


  1. Adding more options to the draggable can solve the problem where it can be dragged anywhere and also leave you more room for the fix of placement in droppable:

    $(document).ready(function () {
        $("#addBtn").click(function () {
            var $div = $("<div>", { "class": "alert alert-info draggable alwaysTop", text: "Say-Da-Tay!" }).draggable({       
          revert: "invalid",
          containment: "document",
          helper: "clone",
          cursor: "move"});
            $("#dropbox").prepend($div);
        });
    

    Also, to solve the final destination box from hiding the draggable while being dragged, i suggest adding zIndex to it in the css like so:

    .alwaysTop {
     width: 40%;
     z-index: 1500; 
    }
    
    Login or Signup to reply.
  2. I’ve been trying to make it work with your code, but it is not really easy to do this way.

    The issue is, that you have relative positioning, and these elements, once you take them out of context, keep the relative parent so all the offsets are still based on the previous parent, which is dropbox. So you have to re-calculate the position offsets.

    Older solution

    This is not the perfect solution, but you can tweak it as you like.

    $(document).ready(function() {
      $("#addBtn").click(function() {
        const $div = $("<div>", {
          class: "alert alert-info draggable alwaysTop",
          text: "Say-Da-Tay!"
        }).draggable({
            revert: 'invalid',
            cursor: 'move',
        });
        $("#dropbox").prepend($div);
      });
    
      $(".droppable").droppable({
        accept: ".draggable",
        drop: function(event, ui) {
          const draggable = ui.draggable;
          const $droppable = $(this);
          // this part here could be improved - works only roughly
          const draggableHalfWidth = draggable.outerWidth() / 2;
          const draggableHalfHeight = draggable.outerHeight() / 2;
          // --
          $(draggable).detach().css({
            position: 'absolute',
            left: event.pageX - $droppable.offset().left - draggableHalfWidth,
            top: event.pageY - $droppable.offset().top + draggableHalfHeight,
          }).appendTo($droppable);
        }
      });
    });
    

    I’ve also added a move-cursor and a reset function that will bounce the items back if you don’t drop it on a .droppable.

    I’ve manually increased the height of the dropzone, too, because now, the size must be hardcoded, since it contains only static content that does not affect the height / width of the container.

    For the z-index: You have 3 sibling elements and one child of one of the siblings wants to draw the element on top of the other elements. Z-index works down the DOM. So you either can set a high z-index to fix this, or you can create the element on a higher level in the DOM.

    https://jsfiddle.net/r6hk74zs/

    Updated solution:

    I’ve experimented a bit more. You can use:

          $(draggable).detach().css({
            position: 'absolute',
            left: ui.offset.left - $droppable.offset().left + 15 + 1,
            top: ui.offset.top,
          }).appendTo($droppable);
    

    Instead. The 15 in the equation is the padding and the 1 there is the border that we have to include (because padding does not apply and borders neither, since we use static positioning).

    The idea is that if you click somewhere on the right container, the click offset will be more to the right than the offset of the dropzone (the top-left corner of the dropzone). Since our new positioning is now relative to the new parent (dropzone), we have to account for the padding and border size (looking from the left side). The top offset for the .draggable stays the same since the container is still on the same vertical line.

    https://jsfiddle.net/osmp76j5/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search