jQuery UI Resizable stop resizing in the resize event

31.9k Views Asked by At

Using jQuery UI Resizable I'm trying to prevent resizing based on various rules. The built-in containment feature doesn't seem to work properly with absolutely positioned elements, and I would need something more flexible than that anyway.

Having something like this:

$( ".selector" ).resizable({ resize : function(event, ui) { /* ??? */ } });

How can I tell the "ui" object to prevent resizing?

Thanks.

9

There are 9 best solutions below

0
On BEST ANSWER

Doesn't seem to be possible with the current version.

0
On

I guess you could do something like that:

$(Selector).css("min-hight", Size);
$(Selector).css("max-hight", Size);
0
On

Its been long time, but there is a solution to this problem in case somebody read this.

You just need to set the maxWidth or minWidth (depends on what you want to do) inside the resize to stop it from resizing.

You can do something like the following:

minWidth: 300,
start: function(event, ui) {
    // get it once so we don't get it hundreds of time inside resize
    this.enforcedMinWidth = $(this).resizable("option", "minWidth");
},
resize: function(event, ui) {
    // use whatever conditions you want to stop here
    // in my original case, i was checking its width vs neighbor and
    // stops the resizing accordingly, so change it to fit your case
    if (ui.element.next().width() <= this.enforcedMinWidth) {
        $(this).resizable("option", "maxWidth", ui.size.width); 
    }
},
stop: function(event, ui) {
    // reset
    $(this).resizable("option", "maxWidth", null);
    // cleanup
    delete this.enforcedMinWidth;
}
2
On

It's very simple, take a look at this code for resizeable floating 'left' div columns with width fixing and limits for each other.

var maxWidthOffset, total2Width;
        $('#'+this.id).find('ul:not(:last)').resizable({
            handles: 'e',
            ghost: true,
            delay: 200,
            helper: "overmoused",
            minWidth: 20,
            start: function(e, ui) {
                maxWidthOffset = ui.element.next().width()-20;
                total2Width = ui.element.width()+maxWidthOffset+20;
            },
            resize: function(e, ui) {
                if (ui.size.width > (ui.originalSize.width + maxWidthOffset)) {
                    $(this).resizable('widget').trigger('mouseup');
                }
            },
            stop: function(e, ui) {
                var w;
                if (ui.originalSize.width > ui.size.width) {
                    w = ui.element.next().width()+ui.originalSize.width - ui.size.width;
                    ui.element.next().width(w>20 ? w : 20);
                } else {
                    w = ui.element.next().width()-(ui.size.width - ui.originalSize.width);
                    ui.element.next().width(w>20 ? w : 20);
                }
                ui.element.width(total2Width-ui.element.next().width());
            }
        });
0
On

If you don't need to continue the mousedown state you could just trigger mouseup:

var resizableSettings = {
    start: function(event, element) {
        if (a > b) {
            $(this).trigger('mouseup');
        }
    }
};

But you may need to continue the mousedown state, such as the user dragging a div.

Below is an example using some of the ideas mentioned already.

var resizableSettings = {
    start: function(event, element) {
        if (a > b) {
            $(this).resizable('option', {
                'maxWidth': element.size.width,
                'minWidth': element.size.width,
                'maxHeight': element.size.height,
                'minHeight': element.size.height
            });
            return;
        }
        $(this).resizable('option', {
            'maxWidth': false,
            'minWidth': false,
            'maxHeight': false,
            'minHeight': false
        });
    }
};
2
On

There is no standart option to stop the resizing at this version. You can disable the resizable but it will continue resizing and will stop the option to resize only in the next time you try.

$(".selector").resizable("disable");

Anyway i found that you can limit the resizing using the maxWidth and maxHeight property directly from the Resize Event.

$(".selector").resizable({
    aspectRatio: true,
    handles: 'all',
    resize: function( event, ui ){
        if(x > y){
            (".selector").resizable("option","maxWidth",ui.size.width);
            return;
        }
    }
});
0
On

There is one awkward way by intercepting both start and resize:

resize: function(event, ui) {
    if (RULE) {
        $(this).resizable('widget').trigger('mouseup');
        var save = window.savePosition;
        save.width  += 4;
        save.height += 4;
        $(ui.helper).css(save);
        return;
    }
},
start: function(event, ui) {
    if (RULE) {
        window.savePosition = $.extend({ }, ui.size, ui.position);
    }
}

Unfortunately there is a 4 pixel "border" on the resize handle, so you have to apply a slight correction to avoid the resizable area "skipping" when you abort the resize operation.

This solution reverts the save to the initial position assuming the same RULE applies at all times. You can of course adapt this by not saving the initial position and size, but recalculating it on the fly during resize. In that case, you needn't intercept start at all.

1
On

Just set the UI properties directy within the resize event. (You could also do this on the stop event if you prefer):

$(".selector").resizable({
    resize: function(event, ui) {
        // set directly
        ui.size.height = 150;
        ui.size.width = 150;
    }
});

$(".selector2").resizable({
    resize: function(event, ui) {
        // return value from another function
        restrictSize(ui);
    }
});

function restrictSize(ui) {
    maxheight = 250;
    maxwidth = 300;

    ui.size.height = ui.size.height > maxheight ? maxheight : ui.size.height;
    ui.size.width = ui.size.width > maxwidth ? maxwidth : ui.size.width;
}

You can do the same with positioning too, of course.

See this fiddle: http://jsfiddle.net/dtwist/PrEfd/

0
On

The answered you picked as correct is not entirely correct. This is achievable:

Use a useless helper to stop the resizing occur on the resize event:

$( ".selector" ).resizable({
  resize: function(event, ui) { 
    // resize $(this) as you wish
  },
  helper: $("</div>")
});

In the resize event alter the resizable dimensions and position as you desire. You still have a problem with the stop event. Right before the stop event gets triggered, jquery resizes your element - which you don't want. All you can do is to reset the object state as it was the last time the resize event triggered. So, in the stop event you can reset your resizable dimensions and position as they were set by you in the last 'resize' event which triggered. For this you will need to declare some variables in a higher context, or use jquery's element.data() method - your choice (you can even create an invisible clone of the entire object if that seems more comfortable to you). Here's an overview of the final code structure:

$( ".selector" ).resizable({
  resize: function(event, ui) { 
    // resize $(this) as you wish and then save the dimensions and positions to some variables declared in a higher context
  },
  helper: $("</div>"),
  stop: function(){
    // restore $(this) position and location as it was last set in the resize event
  }
});