medBouzid
medBouzid

Reputation: 8442

jQuery ui resizable can't expand elements to the left or the top

I am trying to add resizable event to some elements, but I noticed a weird thing while I was trying to expand an element to the left or top.

I have a div with class .limit which is the containment for my resizable elements.

my resizable elements are wrapped inside a div.content

If you try to expand an element to the left or top you will notice that it won't allows you, but it's possible to expand it to the right and bottom until you get to the containment (div.limit)

This is my jsfiddle : http://jsfiddle.net/mody5/s0yo16ek/5/

and this is the code :

HTML :

<div class="limit">
    <div class="content">
      <h1 class="resizable">Navbar example</h1>
      <p class="resizable">This example is a quick exercise to illustrate how the default, static navbar and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.</p>
    </div>
</div>

CSS :

.limit{
    width: 600px;
    background: yellow;
    border: 1px solid gray;
}
.content{
    width:500px;
    margin: 18px;
    padding:10px;
    background: orange;
}
.resizable{
    width: 300px;
    border: 1px solid red;
}

JAVASCRIPT :

 $(".resizable").resizable({
        containment: '.limit',
        handles: "n, e, s, w"       
 });

Upvotes: 3

Views: 1959

Answers (1)

Julien Gr&#233;goire
Julien Gr&#233;goire

Reputation: 17144

Looks to me like a bug. Looking at jquery source code, you can see as soon as coordinates of element goes in negative left, it resets left to 0, not taking care of the offset. Since your element is relative, position is 0, but it doesn't mean it can't go in negative if you want. You can modify jquery-ui for your needs. For example, rewriting resizable part that deals with containment takes care of the left issue. Now maybe there's another way, and this is not really a proper solution, but still:

$.ui.plugin.add("resizable", "containment", {

    start: function(event, ui) {
        var that = $(this).data("resizable"), o = that.options, el = that.element;
        var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
        eoffset=that.element.offset()//at start get offset of the element
        if (!ce) return;

        that.containerElement = $(ce);

        if (/document/.test(oc) || oc == document) {
            that.containerOffset = { left: 0, top: 0 };
            that.containerPosition = { left: 0, top: 0 };

            that.parentData = {
                element: $(document), left: 0, top: 0,
                width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
            };
        }


        else {
            var element = $(ce), p = [];
            $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });

            that.containerOffset = element.offset();
            that.containerPosition = element.position();
            that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };

            var co = that.containerOffset, ch = that.containerSize.height,  cw = that.containerSize.width,
                        width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);

            that.parentData = {
                element: ce, left: co.left, top: co.top, width: width, height: height
            };
        }
    },

    resize: function(event, ui) {

        var that = $(this).data("resizable"), o = that.options,
                ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
                pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, eo = that.element.offset(), ce = that.containerElement;//add eo variable to get offset while resizing

        if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;

        if (cp.left < (that._helper ? co.left : co.left-eoffset.left+that.originalPosition.left)) {//instead of validating if position is lower than 0, checks that offset of left is lower than containment offset
            console.log('hey')
            that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
            if (pRatio) that.size.height = that.size.width / that.aspectRatio;
            that.position.left = o.helper ? co.left : co.left-eoffset.left+that.originalPosition.left;//if it's lower than containment offset, set it to containment offset minus start position offset plus original position offset.

        }

        if (cp.top < (that._helper ? co.top : 0)) {
            that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
            if (pRatio) that.size.width = that.size.height * that.aspectRatio;
            that.position.top = that._helper ? co.top : 0;
        }

        that.offset.left = 50;
        that.offset.top = that.parentData.top+that.position.top;

        var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
                    hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );

        var isParent = that.containerElement.get(0) == that.element.parent().get(0),
            isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));

        if(isParent && isOffsetRelative) woset -= that.parentData.left;

        if (woset + that.size.width >= that.parentData.width) {
            that.size.width = that.parentData.width - woset;
            if (pRatio) that.size.height = that.size.width / that.aspectRatio;
        }

        if (hoset + that.size.height >= that.parentData.height) {
            that.size.height = that.parentData.height - hoset;
            if (pRatio) that.size.width = that.size.height * that.aspectRatio;
        }
    },

    stop: function(event, ui){

        var that = $(this).data("resizable"), o = that.options, cp = that.position,
                co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;

        var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;

        if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
            $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });

        if (that._helper && !o.animate && (/static/).test(ce.css('position')))
            $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });

    }
});

Very heavy jsfiddle: http://jsfiddle.net/hmm3p1be/1/

Upvotes: 1

Related Questions