I am trying to return the new TOP and BOTTOM values for a DIV after it has been resized, but after I resize the values returned are the same as what they were before the resize. Am I missing something obvious here?
<div style="position:absolute; width:50px; top:100px; bottom:300px; left:100px; background-color:yellow; border:solid 1px silver;" e:behavior="b:resize" resizeConstraint=".." resizeEdges="top bottom" resizeGripSize="5" xmlns="http://www.w3.org/1999/xhtml" xmlns:e="http://www.backbase.com/2006/xel" xmlns:b="http://www.backbase.com/2006/btl">
<e:handler event="resizeStart" type="application/javascript">
startTop = this.viewNode.style.top;
startBottom = this.viewNode.style.bottom;
</e:handler>
<e:handler event="resizeEnd" type="application/javascript">
<![CDATA[
alert('startTop='+startTop);
alert('after resizeEnd top='+this.viewNode.style.top);
alert('startBottom='+startBottom);
alert('after resizeEnd bottom='+this.viewNode.style.bottom);
// are we resizing the top or bottom?
if (startTop != this.viewNode.style.top) {
alert('top');
} else if (startBottom != this.viewNode.style.bottom) {
alert('bottom');
} else {
alert('neither');
}
]]>
</e:handler>
</div>
<e:handler event="resizeStart" type="application/javascript">
startTop = this.viewNode.style.top;
startBottom = this.viewNode.style.bottom;
</e:handler>
<e:handler event="resizeEnd" type="application/javascript">
<![CDATA[
alert('startTop='+startTop);
alert('after resizeEnd top='+this.viewNode.style.top);
alert('startBottom='+startBottom);
alert('after resizeEnd bottom='+this.viewNode.style.bottom);
// are we resizing the top or bottom?
if (startTop != this.viewNode.style.top) {
alert('top');
} else if (startBottom != this.viewNode.style.bottom) {
alert('bottom');
} else {
alert('neither');
}
]]>
</e:handler>
</div>
Thanks,
Chris

element positioning
18 July, 2008 - 09:34 — nick@backbaseYou should use either the 'top' or 'bottom' attributes when setting the vertical position of an element, but not both. So, in the example above, I'd suggest removing bottom="300px" and replacing it with height="200px".
To get the height of the div (in pixels) you can use the offsetHeight property e.g. this.viewNode.offsetHeight.
Try again
18 July, 2008 - 14:07 — casadUnfortunately that didn't help. I have simplified the example. To start out TOP=100px ... and when you resize the DIV by pulling the top it returns TOP=100px again even though it has obviously moved.
<e:handler event="resizeEnd" type="application/javascript">
alert("top BEFORE resize = 100px\ntop AFTER resize =" + this.viewNode.style.top);
</e:handler>
</div>
--Chris
Looks like a bug
18 July, 2008 - 15:54 — nick@backbaseHi Chris,
Thanks for the simplified test case. It looks like the resizeEnd event fires before the effects of the resize are actually applied to the element (e.g. when you increase the height of the div in the test case and release the mouse button, the gray 'overlay' is still visible behind the alert).
This seems like a bug to me.
As a workaround, you could try using a setTimeout within the resizeEnd handler.
<e:handler event="resizeEnd" type="application/javascript">
var oDiv = this;
var oMyFunc = function() {
alert("before = 100px\nafter =" + oDiv.viewNode.style.top);
}
setTimeout(oMyFunc, 0);
</e:handler>
</div>
The setTimeout function will not execute until the resize code has completely finished, by which time the 'top' property of the div will have been set.
Note that you cannot use 'this' inside a setTimeout to refer to the div, hence the oDiv variable.
Re: Looks like a bug
18 July, 2008 - 16:01 — casadOk ... thanks for the work around ... that seems to do the trick.
<e:handler event="resizeEnd" type="application/javascript">
var self = this;
setTimeout(function() {
alert("before = 100px\nafter =" + self.viewNode.style.top);
}, 0);
</e:handler>
</div>
--Chris
Re: Looks like a bug
18 July, 2008 - 18:12 — casadWell the simple example works but the bit more complex example doesn't ... hopefully it is something small that I am missing. I am trying to do exactly what the simple example is doing, but dynamically creating the DIV via javascript ... is there something I am missing? It doesn't even fire the alert message.
<![CDATA[
function AddDiv() {
var sHTML = '<div style="position:absolute; width:50px; top:100px; height:200px; left:100px; background-color:red; " e:behavior="b:resize" resizeConstraint=".." resizeEdges="top" resizeGripSize="5" xmlns="http://www.w3.org/1999/xhtml" xmlns:e="http://www.backbase.com/2006/xel" xmlns:b="http://www.backbase.com/2006/btl">' +
' <e:handler event="resizeEnd" type="application/javascript">' +
' alert("here"); ' +
' var self = this; ' +
' setTimeout(function() { ' +
' alert("before = 100px\nafter =" + self.viewNode.style.top); ' +
' //}, 0); ' +
' </e:handler>' +
'</div>';
var oXml = bb.xml.parse(sHTML).documentElement;
bb.command.create(oXml, bb.document.getElementById('container'));
}
]]>
</e:script>
<div id="container" style="position:relative; width:300px; height:400px; background-color:tan;"></div>
<b:button>
Add DIV
<e:handler event="click" type="application/javascript">
AddDiv();
</e:handler>
</b:button>
--Chris
Try this
21 July, 2008 - 16:05 — nick@backbaseWith a couple of small changes to the string concatenation your example seems to work okay. I replaced the "\n" with ", " and removed the "//" from "//}, 0); ' +".
' alert("here"); ' +
' var self = this; ' +
' setTimeout(function() { ' +
' alert("before = 100px, after =" + self.viewNode.style.top); ' +
' }, 0); ' +
' </e:handler>' +
That Did It
21 July, 2008 - 17:26 — casadThat worked ... thanks Nick
Actually using setTimeout is
22 July, 2008 - 09:09 — SjoerdActually using
setTimeoutis not a proper solution. It makes the code asynchronous and possible also inconsistent.Proper solution here is to use the properties exposed on the resizeEnd event object. The resizeEnd fires before the actual resize happens because then you can prevent the default resize action and do your own calculations / actions to set the width / height / left / top.
Unfortunately those properties are not yet documented (but next release they will).
Example:
<e:handler event="resizeEnd" type="application/javascript">
alert("top BEFORE resize = "+(event.originalTop - event.offsetTop)+"\ntop AFTER resize =" + (event.newTop - event.offsetTop));
</e:handler>
</div>