Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a div nested in a jQuery UI dialog resize with the dialog?

Tags:

css

jquery-ui

My jQuery UI dialog contains two div elements. One has a fixed height and should be aligned at the bottom of the dialog at all times. The other one should take up the remaining space.

enter image description here

Basically I’d like all the dimensions highlighted in blue to remain unchanged on resize. Or, in other words, the red div resizes in both dimensions but the green div keeps its height.

What’s the easiest way to do this in jQuery UI or even just plain CSS?

like image 880
Roman Starkov Avatar asked Mar 02 '12 16:03

Roman Starkov


2 Answers

I’ve found a way to do this that doesn’t use any JavaScript. It doesn’t even involve any hacks; just plain normal CSS3. Fiddle here: http://jsfiddle.net/nty5K/16/

Basically, both divs are position: absolute, and each of the sides is anchored individually using the top, bottom, left and right properties. The top div has all four positions specified, making it resize with the container while preserving the exact distance to each edge of the container. The bottom div has three of the positions fixed, whereas the top is defined only indirectly, via a fixed height.

In practice, the divs will need to be placed into a wrapper div that has position: relative, otherwise the top/bottom divs will be positioned relative to the body element.

Not sure about browser compatibility yet, but this worked fine in Firefox 10, IE9 and Chrome 17. Didn’t test this in earlier versions.

like image 53
Roman Starkov Avatar answered Nov 16 '22 01:11

Roman Starkov


Corporate firewall is blocking images, so I am guessing what you are after based on other comments.

EDIT: Now that I can see what you are after, I have updated my fiddle accordingly. Including the code below for completeness.

I would write a function to calculate the size of the dialog, subtract the height of the fixed div and set the height of the dynamic div to this calculated value. I would then bind a call to this function to the resize event of the dialog. Here is a fiddle, may need some tweaking for your exact layout but should be close.

One gotcha worth noting is that some browsers may not calculate correctly while they are in the middle of a scroll/resize event, queing the calculations to occur after the resize event completes with setTimeout resolves the issues, though it does make the change a bit jumpy while the resize is in progress. See this question and answer for details.

function SetDivHeight() {
    var $DynamicDiv = $('div.dynamic');
    var $FixedDiv = $('div.fixed');
    var $Container = $(window); //Update for containing element

/*Calculate the adjustment needed to account for the margin and 
border of the dynamic div.*/
    var HeightAdjustment = $DynamicDiv.outerHeight(true) - $DynamicDiv.height();

/*Get the values of the top and bottom margins which overlap 
between the two divs.*/
    var DynamicBottomMargin = parseInt($DynamicDiv.css('marginBottom'));
    var FixedTopMargin = parseInt($FixedDiv.css('marginTop'));

/*Adjust for the overlapping top/bottom margin by subtracting 
which ever is smaller from the adjustment value.*/
    if (DynamicBottomMargin >= FixedTopMargin) {
        HeightAdjustment -= FixedTopMargin;
    } else {
        HeightAdjustment -= DynamicBottomMargin;
    }


/*subtract the height of the fixed div from the height of the 
container, subtract the calculated height adjustment from that 
value, and set the result as the height of the dynamic div.*/
    $DynamicDiv.height(($Container.height() - $FixedDiv.outerHeight(true)) - 
HeightAdjustment);
/*May need to use $Container.innerHeight instead, if container 
is not a window element.*/
}

var t;

function QueueSetDivHeight() {
    if (t) {
        clearTimeout(t);
    }
    t = setTimeout(function() {
        SetDivHeight();
    }, 0);
}

$(document).ready(function() {
    SetDivHeight();
    $(window).resize(QueueSetDivHeight);
    //Bind to resize of container element instead/as well
});
like image 30
Rozwel Avatar answered Nov 16 '22 02:11

Rozwel