pbz
pbz

Reputation: 9085

jQuery UI Resizable stop resizing in the resize event

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.

Upvotes: 10

Views: 32239

Answers (9)

Alaeddin Hussein
Alaeddin Hussein

Reputation: 756

I guess you could do something like that:

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

Upvotes: 1

Will
Will

Reputation: 782

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
        });
    }
};

Upvotes: 0

LSerni
LSerni

Reputation: 57388

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.

Upvotes: 0

codenamezero
codenamezero

Reputation: 3079

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;
}

Upvotes: 1

Radu Simionescu
Radu Simionescu

Reputation: 4677

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
  }
});

Upvotes: 1

Roy Shoa
Roy Shoa

Reputation: 3195

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;
        }
    }
});

Upvotes: 12

David Twist
David Twist

Reputation: 71

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/

Upvotes: 7

Alexey
Alexey

Reputation: 231

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());
            }
        });

Upvotes: 20

pbz
pbz

Reputation: 9085

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

Upvotes: 0

Related Questions