PDA

View Full Version : [4.0.2a] Window positioning when rendered to somewhere other than body.



westy
27 Jun 2011, 6:02 AM
REQUIRED INFORMATION


Ext version tested:

Ext 4.0.2a


Browser versions tested against:

IE9
FF4
Safari 5
Chrome 12


Description:

When the renderTo target is set for a window it starts up in the wrong location, and when moved and dropped the panel is positioned wrong.
The offset appears to be the location of the renderTo target, e.g. size of header taken into account.


Steps to reproduce the problem:

Load the attached test html file (after updating ext path if required), and move the window.


The result that was expected:

When released the window is positioned in the same place as the ghost.


The result that occurs instead:

The window is lower than expected, I'm guessing by 40 pixels (the size of the header).


Test Case:



<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Ghost Testing</title>

<!-- Ext includes -->
<script type="text/javascript" src="/lib/Ext/ext-4.0.2a/bootstrap.js"></script>

<!-- CSS -->
<link rel="stylesheet" href="/lib/Ext/ext-4.0.2a/resources/css/ext-all.css" type="text/css">

<script type="text/javascript">
Ext.onReady(function() {

// Viewport
Ext.define('Altus.view.Viewport', {
extend: 'Ext.Viewport',

requires: [
'Ext.Toolbar'
],

layout: 'border',

initComponent: function() {
Ext.apply(this, {
items: [{
region: 'north',
height: 40,
html: 'Header'
},{
region: 'center',
hiddenId: 'contentPanel',
html: 'Content - window renderTo target'
}]
});

this.callParent(arguments);
},

getContentPanel: function() {
return this.down('panel[hiddenId="contentPanel"]');
}

});

var vp = Ext.create('Altus.view.Viewport');

Ext.create('Ext.window.Window', {
renderTo: vp.getContentPanel().getEl(),
width: 400,
height: 400,
html: 'Move me about'
}).show();

});
</script>

</head>
<body>
</body>
</html>




HELPFUL INFORMATION


Debugging already done:

Issue is at line 38255 of ext-all-debug.js, or 1492 of Ext.panel.Panel:


me.setPosition(me.ghostPanel.getPosition());

getPosition appears to be relative to the document body, not the renderTo target.


Possible fix:

Played around with matching the renderTo on the ghost, setting floatParent for the window, but no useful fix yet.


Operating System:

Win7 x64 Pro


Cheers,
Westy

westy
27 Jun 2011, 6:08 AM
If add a west region the issue is even more pronounced, and backs up my guess.



Ext.apply(this, {
items: [{
region: 'north',
height: 40,
html: 'Header'
},{
region: 'west',
html: 'West'
},{
region: 'center',
hiddenId: 'contentPanel',
html: 'Content - window renderTo target'
}]
});

mitchellsimoens
27 Jun 2011, 7:38 AM
I already beat you to getting this bug since 6/4 ;)

I found it out when I tried to maximize the window that was constrained into my center region and it still maximized over the entire browser viewport.

Looks like this is slated for 4.0.5 which is 2 releases away :(( Hoping for sooner but there are more important things like performance :)

Thank you for the report and using the template!

Adding link to this thread to the existing bug report internally.

westy
27 Jun 2011, 7:52 AM
Two releases away! Arrgghhh...
That's disappointing. If anyone has a hotfix for this I'd be grateful.

I may see what I can come up with in the meantime since it looks very poor.
Looks like it's quite tied up with Element though, so guess the knock-on effects could be large.

Cheers,
Westy

mitchellsimoens
27 Jun 2011, 7:56 AM
Yeah, I started to look into it myself and got a little scared on if I change something... what else would I break /:)

westy
27 Jun 2011, 9:02 AM
Got the beginnings of a fix, although not convinced myself yet, since still have issues when moving tooltips...

In a nutshell:


When setting your Window's renderTo, also set it's floatParent (to the parent of the renderTo El),
e.g.


var vpPanel = Altus.view.Viewport.getActivePanel();

Ext.applyIf(config, {
renderTo: vpPanel.getEl(),
floatParent: vpPanel
});

In Ext.panel.Panel.ghost change ghostPanel.floatParent = me.floatParent to be ghostPanel.floatParent = me.initialConfig.floatParent;
(No idea why floatParent doesn't stick correctly at the moment).
In Ext.Component.adjustPosition comment out the floatParent xy adjustment bit.


As I say, it's not there yet, but think I'm getting somewhere (just not sure where).

Giving up for now, and have a day off tomorrow. Hopefully someone can run with this, and try and get a fix in sooner :)

Cheers,
Westy

mitchellsimoens
27 Jun 2011, 9:03 AM
Since you are giving it a bunch of effort, tonight if I leave the client location at a decent time I will pick up where you left off as well :)

westy
27 Jun 2011, 9:53 AM
Nice one Mitchell, thanks bud :)

westy
4 Jul 2011, 4:54 AM
Hmm, changing from using renderTo to ownerCt seems to correct the positioning issue.

Now lose any open windows when changing my viewport card, as I need, but they used to still be there if I changed back to the original page but aren't anymore, and it's not clear where they have gone...

Still, certainly an easier workaround.
Will try and figure out if the windows are still in the DOM...

westy
4 Jul 2011, 4:57 AM
Hmm, they are still in the DOM; they get set to hidden, but aren't shown again.

A bit of a leak there then...

Animal
4 Jul 2011, 6:08 AM
Insert the window as a child. It Just Works.

westy
4 Jul 2011, 6:50 AM
Heh, a nice elaborate post as always Animal :D

"It Just Works" in exactly the same way as setting ownerCt.
Changing card and back leaks the object into the DOM.

renderTo does exactly what's needed, but the positioning is wrong.
I maintain it's a real issue...

Cheers,
Westy

Animal
4 Jul 2011, 10:57 AM
Hmm.. If it doesn't Just Work, then it should and there's a bug.

When a floating Component is a child of a Container, it is rendered to document.body. This is because it may have to appear outside the bounds of that parent Container if constrainHeader is true.

What goes wrong when you add a Window as a child item of your Container.

westy
5 Jul 2011, 1:48 AM
Try this:


<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Ghost Testing</title>

<!-- Ext includes -->
<script type="text/javascript" src="/lib/Ext/ext-4.0.2a/bootstrap.js"></script>

<!-- CSS -->
<link rel="stylesheet" href="/lib/Ext/ext-4.0.2a/resources/css/ext-all.css" type="text/css">

<script type="text/javascript">
Ext.onReady(function() {

// Viewport
Ext.define('Altus.view.Viewport', {
extend: 'Ext.Viewport',

requires: [
'Ext.Toolbar'
],

layout: 'border',

initComponent: function() {
Ext.apply(this, {
items: [{
region: 'north',
height: 40,
layout: 'fit',
items: {
xtype: 'toolbar',
border: false,
frame: false,
layout: {
type: 'hbox',
align: 'stretch'
},
items: [
{
xtype: 'label',
text: 'Header'
},
'->',
{
xtype: 'button',
text: 'Card 0',
handler: function(button, e) {
var panel = button.up('viewport').down('panel[hiddenId="contentPanel"]');
if (panel) {
panel.getLayout().setActiveItem(0);
}
}
},
{
xtype: 'button',
text: 'Card 1',
handler: function(button, e) {
var panel = button.up('viewport').down('panel[hiddenId="contentPanel"]');
if (panel) {
panel.getLayout().setActiveItem(1);
}
}
},
{
xtype: 'button',
text: 'Card 2',
handler: function(button, e) {
var panel = button.up('viewport').down('panel[hiddenId="contentPanel"]');
if (panel) {
panel.getLayout().setActiveItem(2);
}
}
}
]
}
},{
region: 'west',
html: 'West'
},{
region: 'center',
hiddenId: 'contentPanel',
layout: 'card',
items: [{
html: 'Card 0'
},{
html: 'Card 1'
},{
html: 'Card 2'
}]
}]
});

this.callParent(arguments);
},

getContentPanel: function() {
return this.down('panel[hiddenId="contentPanel"]');
}

});

var vp = Ext.create('Altus.view.Viewport');

Ext.create('Ext.window.Window', {
renderTo: vp.getContentPanel().getLayout().getActiveItem().getEl(),
width: 400,
height: 400,
html: 'Window, rendered to card...<br/><br/>Move me about and try switching card...'
}).show();

var childWin = Ext.create('Ext.window.Window', {
width: 300,
height: 300,
html: 'Window, added as child to card...<br/><br/>Move me about, inspect me, then try switching card...'
});

vp.getContentPanel().getLayout().getActiveItem().add(childWin);
childWin.show();
});
</script>

</head>
<body>
</body>
</html>


If you inspect the child window, then change card you'll see that it's still in the DOM but hidden (which is fine). It does not get shown again when you switch back, so cannot be closed (which is not)...

I much prefer the renderTo method personally, and believe it should work, although the ability of a child to render outside of its container is nice in some circumstances I guess...

Cheers,
Westy

sritter
6 Jul 2011, 2:01 AM
ld work, although the ability of a child to render outside of its container is nice in some circumstances I guess...


Hey, I would need that too... any progress or ideas how to use renderTo correctly?

stevil
6 Jul 2011, 3:34 AM
Hmm.. If it doesn't Just Work, then it should and there's a bug.

When a floating Component is a child of a Container, it is rendered to document.body. This is because it may have to appear outside the bounds of that parent Container if constrainHeader is true.

What goes wrong when you add a Window as a child item of your Container.

My first thought was the same, that adding it as a child item would work. Curious to know why that wouldn't work...

But then the constrain config doc on Window says:


True to constrain the window within its containing element, false to allow it to fall outside of its containing element. By default the window will be rendered to document.body. To render and constrain the window within another element specify renderTo. (defaults to false). Optionally the header only can be constrained using constrainHeader.

Seems like a bug to me, too, and a weird one in that the vertical travel on the window increases when you add a WEST region...

stevil

sritter
14 Jul 2011, 8:31 AM
Found an solution:
renderTo works fine... just overwrite getPosition to ensure that it is looking locally and not to body



getPosition: function() {
return this.callParent([true]);
}

eurobax
3 Jan 2012, 5:26 AM
ExtJS 4.1.0 b1: bug still exists when rendering window to "Central" region (applying "renderTo" option like region.getEl())
When you try to drag or resize window, it become offsetted in Y by the size of north panel height. Each time you try again - each time it become offsetted more and more.
By the way, ExtJS 4.0.7 seems all ok.