22

I have a div element which is made jquery Resizable. It has alsoResize option set, so other elements resize simultaneously.

What I want to do, is to set size of this Resizable div element programmatically in such way, that all Resizable logic is triggered (especially this alsoResize option is taken into account).

How can I achieve that?

Dawid Ohia
  • 16,129
  • 24
  • 81
  • 95

5 Answers5

28

Update: It looks like the internals of jQuery UI have changed dramatically since I answered this and firing the event no longer works.

There's no direct way to fire the event anymore because the resizable plugin has been fundamentally changed. It resizes as the mouse is dragged rather than syncing items up at the end. This happens by it listening for the internal resize propagation event for resizable plugins which is now fired by the _mouseDrag handler. But it depends on variables set along the way, so just firing that even internally won't help.

This means even overriding it is messy at best. I'd recommend just manually resizing the alsoResize elements directly, independent of the UI widget altogether if that's possible.

But for fun let's say it isn't. The problem is that the internals of the plugin set various properties relating to previous and current mouse position in order to know how much to resize by. We can abuse use that to add a method to the widget, like this:

$.widget("ui.resizable", $.ui.resizable, {
    resizeTo: function(newSize) {
        var start = new $.Event("mousedown", { pageX: 0, pageY: 0 });
        this._mouseStart(start);
        this.axis = 'se';
        var end = new $.Event("mouseup", {
            pageX: newSize.width - this.originalSize.width,
            pageY: newSize.height - this.originalSize.height
        });
        this._mouseDrag(end);
        this._mouseStop(end);
    }
});

This is just creating the mouse events that the resizable widget is looking for and firing those. If you wanted to do something like resizeBy it'd be an even simpler end since all we care about is the delta:

var end = $.Event("mouseup", { pageX: newSize.width, pageY: newSize.height });

You'd call the $.widget() method after jQuery UI and before creating your .resizable() instances and they'll all have a resizeTo method. That part doesn't change, it's just:

$(".selector").resizable({ alsoResize: ".other-selector" });

Then to resize, you'd call that new resizeTo method like this:

$(".selector").resizable("resizeTo", { height: 100, width: 200 });

This would act as if you instantly dragged it to that size. There are of course a few gotchas here:

  • The "se" axis is assuming you want resize by the bottom right - I picked this because it's by far the most common scenario, but you could just make it a parameter.
  • We're hooking into the internal events a bit, but I'm intentionally using as few internal implementation details as possible, so that this is less likely to break in the future.
  • It could absolutely break in future versions of jQuery UI, I've only tried to minimize the chances of that.

You can play with it in action with a fiddle here and the resizeBy version here.


Original answer:

You can do this:

$(".selector").trigger("resize");

alsoResize internally rigs up a handler to the resize event, so you just need to invoke that :)

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 8
    I don't see any size or distance parameters specified there, may I ask how you did that? – Luke Stanley Aug 03 '11 at 04:19
  • wow a great method to know. you can also fire any other event types, like "dialogresizestop" . – alfred May 25 '11 at 10:16
  • 5
    It doesn't work. The question was "How to trigger Resizable resize", but your variant triggers standard javascript resize event. – Arsen K. Jan 27 '13 at 14:53
  • 1
    @Webars - that's the event it's listening to, triggering the event triggers the handlers rigged up to that event. – Nick Craver Jan 27 '13 at 18:40
  • 1
    $(window).trigger('resize') didn't work for me in chrome - is that supposed to work, as different selectors, like $('body') work .. – rémy Mar 19 '13 at 17:02
  • @NickCraver Is it possible to use this syntax with options for the resizable plugin? I need to resize to a specific size when the event happens. – emersonthis Jun 19 '13 at 15:45
  • Unless I missed something, this solution doesn't work for me. [Here is a JSFiddle](http://jsfiddle.net/jwa107/qobp9boc/2/) – Hanna Aug 07 '14 at 22:09
  • @Johannes it looks like recent versions behave in a different way, resizing alongside the same event on move rather than at the end - there's no way to tap into it that I can see besides some *really* bad mousedown/move/up hackery. I'll see if there's a way to do what the question here is asking then update. – Nick Craver Aug 07 '14 at 22:23
  • @NickCraver, thanks for looking into that. I figured that was the case, and it's unfortunate that they'd made it behave differently. – Hanna Aug 07 '14 at 22:52
  • @Johannes Pinging for a heads up: I dug in a little bit last night out of morbid curiosity wondering how jQuery UI currently works, hope the updated answer helps a bit. – Nick Craver Aug 08 '14 at 11:17
  • @NickCraver, thanks for the update, excellent detailed answer! – Hanna Aug 08 '14 at 15:30
7

You can trigger the bars programmatically. For example, to trigger the east-west resize event:

var elem =... // Your ui-resizable element
var eastbar = elem.find(".ui-resizable-handle.ui-resizable-e").first();
var pageX = eastbar.offset().left;
var pageY = eastbar.offset().top;

(eastbar.trigger("mouseover")
        .trigger({ type: "mousedown", which: 1, pageX: pageX, pageY: pageY })
        .trigger({ type: "mousemove", which: 1, pageX: pageX - 1, pageY: pageY })
        .trigger({ type: "mousemove", which: 1, pageX: pageX, pageY: pageY })
        .trigger({ type: "mouseup", which: 1, pageX: pageX, pageY: pageY }));

I am doing a 1px left followed by 1px right movement on the east bar handle. To perform a full size, you can target .ui-resizable-handle.ui-resizable-se if you have east and south resize bars.

Mikaël Mayer
  • 10,425
  • 6
  • 64
  • 101
1

I needed the same thing for tests. Similar questions have only one promising answer https://stackoverflow.com/a/17099382/1235394, but it requires additional setup, so I ended with my own solution.

I have an element with resizable right edge

$nameHeader.resizable({handles: 'e', ... });

and I needed to trigger all callbacks during the test in order to resize all elements properly. The key part of test code:

var $nameHeader = $list.find('.list-header .name'),
    $nameCell = $list.find('.list-body .name');
ok($nameHeader.hasClass('ui-resizable'), 'Name header should be resizable');
equal($nameCell.outerWidth(), 300, 'Initial width of Name column');

// retrieve instance of resizable widget
var instance = $nameHeader.data('ui-resizable'),
    position = $nameHeader.position(),
    width = $nameHeader.outerWidth();
ok(instance, 'Instance of resizable widget should exist');

// mouseover initializes instance.axis to 'e'
instance._handles.trigger('mouseover');
// start dragging, fires `start` callback
instance._mouseStart({pageX: position.left + width, pageY: position.top});
// drag 50px to the right, fires `resize` callback
instance._mouseDrag({pageX: position.left + width + 50, pageY: position.top});
// stop dragging, fires `stop` callback
instance._mouseStop({pageX: position.left + width + 50, pageY: position.top});

// ensure width of linked element is changed after resizing
equal($nameCell.outerWidth(), 350, 'Name column width should change');

Of course this code is brittle and may break when widget implementation changes.

Community
  • 1
  • 1
Victor
  • 3,669
  • 3
  • 37
  • 42
0

Hack Disclaimer (tested on jQuery 1.12.4):

This basically waits for the dialog to be opened and then increments by 1px (which forces the resize() event) and then decrements by 1px (to regain original size)

just say this in the dialog open event handler:

 $(this)
.dialog("option","width",$(this).dialog("option","width")+1)
.dialog("option","width",$(this).dialog("option","width")-1);

note:

This may not work with show effects (like fadeIn,slideDown etc) as the "resizer" code executes before the dialog is fully rendered.

Sajjan Sarkar
  • 3,900
  • 5
  • 40
  • 51
-6
$(".yourWindow").each(function(e) {
    $(this).height($(this).find(".yourContent").height());
});

And the same with the width.