Draggable + REVERT BY POSITION OF DRAGGABLE

by bizamajig

HTML

<div class="parent">
    <div class="child"></div>
</div>
<div class="drag"></div>

CSS

.parent {
    border: 1px solid black;
    overflow: visible;
    width: 100px;
    height: 100px;
    position: absolute;
    left: 100px;
}
.child {
    width: 200px;
    height: 100px;
    background-color: red;
    float: right;
    opacity: .5;
}
.drag {
    width: 50px;
    height: 50px;
    background-color: blue;
    position: absolute;
    left: 250px;
}

.ui-draggable-dragging {
    opacity: 0.5;
}

JavaScript

$(".drag").draggable({
    helper: "clone",
    revert: function () {
        /*
         * Check if draggable is inside the parent. This is a bit brute force, if
         * the parent itself is also a droppable it can also be checked by
         * listening for the 'over' event and setting a flag.
         */
        
        // The parent container's position
        var pPos = $(".parent").offset();
        
        // The current draggable helper's position
        var dDraggable = this.data().draggable;
        var helper = dDraggable.helper;
        var dPos = helper.offset();

        /*
         * Can also add top and right/bottom contraints
         * if we only want to allow dragging onto droppable!
         * Will have to calculate right = left + width,
         * bottom = top + height. Also take into account possible
         * borders/padding/margin with jQuery outerWidth!
         */
        var withinParent = dPos.left > pPos.left;
        
        if (!withinParent) {
            return true;
        }
        else {
            // Move the draggable to the helper's position
            // NOTE: We're using offset here, so you may want to test this under various condition, e.g. relative/absolute parents!
            this.css(helper.offset());
            return false;
        }
    }
});
$(".child").droppable();