Xahed Kamal Xahed Kamal - 3 years ago 157
jQuery Question

jQueryUI Draggable element's position not correct inside container is scaled using css

I have a

div
with id
box-parent
which scales up/down based on Viewport. Inside are many boxes that each have the
sq-box
class. When I try to drag those boxes, their positions are not getting set correctly. I'm trying to swap between boxes. Is there any way to get the correct positions while moving the boxes?

CSS

#box-parent{
border:1px solid black;
width:300px;
margin:40px auto;
font-size:0;
transform:scale(1.2);
}

.sq-box{
display:inline-block;
font-size:20px;
height:50px;
width:50px;
border:1px solid green;
background-color:rgba(0,0,0,0.5);
}


JavaScript

$(".sq-box").draggable({
appendTo: "#box-parent",
helper: "clone",
cursor: "move",
revert: "invalid"
});


HTML

<div id="box-parent">
<div class="sq-box">1</div>
<div class="sq-box">2</div>
<div class="sq-box">3</div>
<div class="sq-box">4</div>
<div class="sq-box">5</div>
<div class="sq-box">6</div>
<div class="sq-box">1</div>
<div class="sq-box">2</div>
<div class="sq-box">3</div>
<div class="sq-box">4</div>
<div class="sq-box">5</div>
<div class="sq-box">6</div>
<div class="sq-box">1</div>
<div class="sq-box">2</div>
<div class="sq-box">3</div>
<div class="sq-box">4</div>
<div class="sq-box">5</div>
<div class="sq-box">6</div>
<div class="sq-box">1</div>
<div class="sq-box">2</div>
<div class="sq-box">3</div>
<div class="sq-box">4</div>
<div class="sq-box">5</div>
<div class="sq-box">6</div>
</div>


Here is a JSFiddle of the issue - https://jsfiddle.net/mhb35rnr/

Answer Source

Hopefully this is closer to what you're hoping for. In order to do what you want you need to use a draggable with a droppable. Note the addition of transform-origin and position: absolute to workaround a jQuery draggable visual artifact when dragging and scaling is applied.

Working JSFiddle

CSS

#box-parent{
  border:1px solid black;
  width:300px;
  font-size:0;
  position: absolute;
  transform-origin:top left;
  transform:scale(1.2);
}

.sq-box{
  display:inline-block;
  font-size:20px;
  height:50px;
  width:50px;
  border:1px solid green;
  background-color:rgba(0,0,0,0.5);
}

.ui-state-hover {
  background: lightyellow;   
}

.ui-state-active {
  background: lightgray;
}

JavaScript

jQuery.fn.swap = function(b){ 
    // method from: http://blog.pengoworks.com/index.cfm/2008/9/24/A-quick-and-dirty-swap-method-for-jQuery
    b = jQuery(b)[0]; 
    var a = this[0]; 
    var t = a.parentNode.insertBefore(document.createTextNode(''), a); 
    b.parentNode.insertBefore(a, b); 
    t.parentNode.insertBefore(b, t); 
    t.parentNode.removeChild(t); 
    return this; 
};

$(".sq-box").draggable({
     connectToSortable: "#box-parent",
     cursor: "move",
     revert: "invalid",
     helper: "clone"
});

$(".sq-box").droppable({
    accept: ".sq-box",
    activeClass: "ui-state-hover",
    hoverClass: "ui-state-active",
    drop: function( event, ui ) {

        var draggable = ui.draggable, droppable = $(this),
            dragPos = draggable.position(), dropPos = droppable.position();

        draggable.css({
            left: dropPos.left+'px',
            top: dropPos.top+'px'
        });

        droppable.css({
            left: dragPos.left+'px',
            top: dragPos.top+'px'
        });
        draggable.swap(droppable);
    }
});

HTML

<div id="box-parent">
  <div class="sq-box">1</div>
  <div class="sq-box">2</div>
  <div class="sq-box">3</div>
  <div class="sq-box">4</div>
  <div class="sq-box">5</div>
  <div class="sq-box">6</div>
  <div class="sq-box">1</div>
  <div class="sq-box">2</div>
  <div class="sq-box">3</div>
  <div class="sq-box">4</div>
  <div class="sq-box">5</div>
  <div class="sq-box">6</div>
  <div class="sq-box">1</div>
  <div class="sq-box">2</div>
  <div class="sq-box">3</div>
  <div class="sq-box">4</div>
  <div class="sq-box">5</div>
  <div class="sq-box">6</div>
  <div class="sq-box">1</div>
  <div class="sq-box">2</div>
  <div class="sq-box">3</div>
  <div class="sq-box">4</div>
  <div class="sq-box">5</div>
  <div class="sq-box">6</div>
</div>

I borrowed some of this from this existing SO answer.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download