Search code examples
jqueryhtmljquery-ui-droppable

Position of element changes after changing left and top value from pixel to percentage


I am using jQuery Droppable and want to save the coordinates in percentage value. So I have written the code to covert the Pixel value to percentage.

But I marked while its in (0,0) position percentage value comes perfect but as I move the element to Downward of the parent element percentage value of TOP decreasing and percentage value of Left Increasing. So at the bottom left corner element has around 12% of increased left percentage and 8% decreased top percentage.

Update : The percentage value what I get after drag and drop, when I put that percentage value to the elements style it shifts the element towards top and right. That means top percentage value decreasing and left percentage value increasing.

I cant find the reason why percentage value varies while the calculation remains same. Here is the code,

jQuery("#editor").droppable({
    drop: function( event, ui ) {

        var pos = ui.draggable.offset();
        var dPos = $(this).offset();

        // Pixxel value of positions
        var elementTopPosition = pos.top - dPos.top;
        var elementLeftPosition = pos.left - dPos.left;

        // Getting parent element height and width
        var parentWidth = jQuery("#editor").width();
        var ParentHeight = jQuery("#editor").height();

        // Coverting to percentage
        var topInPercentage = ( 100 * elementTopPosition ) / ParentHeight;
        var leftInPercentage = ( 100 * elementLeftPosition ) / parentWidth;

    }
});

While I save an element position with percentage value : http://www.awesomescreenshot.com/image/436490/b1b1c6c910b0f68a4199c8f67684ac56

When I output that element position with saved percentage value : http://www.awesomescreenshot.com/image/436526/12d4b0778240646285c6fdd10e61bd2f

Live Example (fiddle if you prefer):

$("#draggable").draggable();

jQuery("#droppable").droppable({
    drop: function (event, ui) {

        debugger;

        var pos = ui.draggable.offset();
        var dPos = $(this).offset();

        // Pixxel value of positions
        var elementTopPosition = pos.top - dPos.top;
        var elementLeftPosition = pos.left - dPos.left;

        // Getting parent element height and width
        var parentWidth = jQuery("#droppable").width();
        var ParentHeight = jQuery("#droppable").height();

        // Coverting to percentage
        var topInPercentage = (100 * elementTopPosition) / ParentHeight;
        var leftInPercentage = (100 * elementLeftPosition) / parentWidth;
        
        $("#draggable").css({top: topInPercentage + '%', left: leftInPercentage + '%'});

    }
});
#draggable {
    width: 100px;
    padding: 2px 5px;
    cursor: pointer;
    color: #fff;
    position: absolute;
}
#droppable {
    position: relative;
    width: 200px;
    height: 200px;
    background: #999;
    color: #fff;
    padding: 10px;
}
<div id="droppable">
    <div id="draggable">Element</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>

So, try moving the element in between its parent, in each move I am capturing the left top pixel value and convert it to Percentage and then apply that percentage value gain to that element. But it differs from the original postion value.


Solution

  • You want outerWidth/outerHeight rather than width/height:

    $("#draggable").draggable();
    
    jQuery("#droppable").droppable({
        drop: function (event, ui) {
    
            debugger;
    
            var pos = ui.draggable.offset();
            var dPos = $(this).offset();
    
            // Pixxel value of positions
            var elementTopPosition = pos.top - dPos.top;
            var elementLeftPosition = pos.left - dPos.left;
    
            // Getting parent element height and width
            var parentWidth = jQuery("#droppable").outerWidth();   // <=== Here
            var ParentHeight = jQuery("#droppable").outerHeight(); // <===
    
            // Coverting to percentage
            var topInPercentage = (100 * elementTopPosition) / ParentHeight;
            var leftInPercentage = (100 * elementLeftPosition) / parentWidth;
            
            $("#draggable").css({top: topInPercentage + '%', left: leftInPercentage + '%'});
    
        }
    });
    #draggable {
        width: 100px;
        padding: 2px 5px;
        cursor: pointer;
        color: #fff;
        position: absolute;
    }
    #droppable {
        position: relative;
        width: 200px;
        height: 200px;
        background: #999;
        color: #fff;
        padding: 10px;
    }
    <div id="droppable">
        <div id="draggable">Element</div>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>