aedos
29 Dec 2009, 2:40 PM
Encountered this bug during upgrade from 3.0 to 3.1. Reproducible with IE and FF.
The DOM presentation of a Toolbar typically looks like:
<DIV class="x-toolbar x-small-editor x-column x-toolbar-layout-ct" id="tabBarTabs" style="WIDTH: 889px">
<TABLE class="x-toolbar-ct" cellSpacing="0">...</TABLE>
</DIV>
After calling
myToolbar.remove(<some-item>)
myToolbar.doLayout()
The toolbar HTML becomes
<DIV class="x-toolbar x-small-editor x-column x-toolbar-layout-ct" id="tabBarTabs" style="WIDTH: 889px">
<TABLE class="x-toolbar-ct" cellSpacing="0">...</TABLE>
<TABLE class="x-toolbar-ct" cellSpacing="0">...</TABLE>
</DIV>
Notice the 2nd HTML Table inserted into the top DIV. If remove() and doLayout() are called for N times, N Tables will be inserted to the DOM, and it will take visible space in IE.
Looks like a bug in 3.1 Ext.layout.ToolbarLayout:
onLayout : function(ct, target){
if(!this.leftTr){
target.addClass('x-toolbar-layout-ct');
target.insertHtml('beforeEnd',
'<table cellspacing="0" class="x-toolbar-ct"><tbody><tr><td class="x-toolbar-left" align="left"><table cellspacing="0"><tbody><tr class="x-toolbar-left-row"></tr></tbody></table></td><td class="x-toolbar-right" align="right"><table cellspacing="0" class="x-toolbar-right-ct"><tbody><tr><td><table cellspacing="0"><tbody><tr class="x-toolbar-right-row"></tr></tbody></table></td><td><table cellspacing="0"><tbody><tr class="x-toolbar-extras-row"></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table>');
this.leftTr = target.child('tr.x-toolbar-left-row', true);
this.rightTr = target.child('tr.x-toolbar-right-row', true);
this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
}
...
}
onRemove : function(c){
delete this.leftTr;
delete this.rightTr;
delete this.extrasTr;
Ext.layout.ToolbarLayout.superclass.onRemove.call(this, c);
}
If I understand it correctly that onRemove() is called after any child item is removed from the layout, it should not cause regenerating the entire layout from scratch during next doLayout(). I'm working around this issue by overriding onRemove() to only invoke super.
MORE BACKGROUND:
I need to dynamically add/remove buttons inside a Toolbar, so I'm calling add()/remove() then doLayout() on the Toolbar. Is there any other (or better) way to dynamically update content of a Toolbar (or other Container)?
The DOM presentation of a Toolbar typically looks like:
<DIV class="x-toolbar x-small-editor x-column x-toolbar-layout-ct" id="tabBarTabs" style="WIDTH: 889px">
<TABLE class="x-toolbar-ct" cellSpacing="0">...</TABLE>
</DIV>
After calling
myToolbar.remove(<some-item>)
myToolbar.doLayout()
The toolbar HTML becomes
<DIV class="x-toolbar x-small-editor x-column x-toolbar-layout-ct" id="tabBarTabs" style="WIDTH: 889px">
<TABLE class="x-toolbar-ct" cellSpacing="0">...</TABLE>
<TABLE class="x-toolbar-ct" cellSpacing="0">...</TABLE>
</DIV>
Notice the 2nd HTML Table inserted into the top DIV. If remove() and doLayout() are called for N times, N Tables will be inserted to the DOM, and it will take visible space in IE.
Looks like a bug in 3.1 Ext.layout.ToolbarLayout:
onLayout : function(ct, target){
if(!this.leftTr){
target.addClass('x-toolbar-layout-ct');
target.insertHtml('beforeEnd',
'<table cellspacing="0" class="x-toolbar-ct"><tbody><tr><td class="x-toolbar-left" align="left"><table cellspacing="0"><tbody><tr class="x-toolbar-left-row"></tr></tbody></table></td><td class="x-toolbar-right" align="right"><table cellspacing="0" class="x-toolbar-right-ct"><tbody><tr><td><table cellspacing="0"><tbody><tr class="x-toolbar-right-row"></tr></tbody></table></td><td><table cellspacing="0"><tbody><tr class="x-toolbar-extras-row"></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table>');
this.leftTr = target.child('tr.x-toolbar-left-row', true);
this.rightTr = target.child('tr.x-toolbar-right-row', true);
this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
}
...
}
onRemove : function(c){
delete this.leftTr;
delete this.rightTr;
delete this.extrasTr;
Ext.layout.ToolbarLayout.superclass.onRemove.call(this, c);
}
If I understand it correctly that onRemove() is called after any child item is removed from the layout, it should not cause regenerating the entire layout from scratch during next doLayout(). I'm working around this issue by overriding onRemove() to only invoke super.
MORE BACKGROUND:
I need to dynamically add/remove buttons inside a Toolbar, so I'm calling add()/remove() then doLayout() on the Toolbar. Is there any other (or better) way to dynamically update content of a Toolbar (or other Container)?