I'm not sure how reproducible this is going to be, as my code is an exerpt of a much larger application. The description of the bug is:
A tab panel holds a border layout. The east region has another tab panel which contains a form panel. This form panel is rather complex so to keep the code more readable, the form panel has been defined as an extension of Ext.FormPanel. This Form panel is not the active tab upon rendering the Tab panel it is contained in.
THIS IS KEY: The bug is not apparent if the form panel tab is the 'activeTab' upon rendering the tab panel.
When the user clicks on the tab to view the Form panel, the underlying fields do not render properly. Specifically, fieldsets are empty. As soon as I change the window size, the elements appear as this forces a re-render.
Again, I reiterate, if the Form Panel is the 'activeTab' this problem goes away, however that is not an acceptable solution in my case.
I tried to re-render the form panel by extending the 'afterRender' private method as below
Code:
afterRender : function(){
webparts.UserPanel.privsForm.superclass.afterRender.apply(this, arguments);
this.doLayout();
},
but Firebug was giving me the following error
"this.layout.layout is not a function"
I eventually solved the issue in my case by extending afterRender as such
Code:
afterRender : function(){
webparts.UserPanel.privsForm.superclass.afterRender.apply(this, arguments);
if(this.layout){
if(typeof this.layout == 'string'){
this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
}
this.setLayout(this.layout);
if(this.activeItem !== undefined){
var item = this.activeItem;
delete this.activeItem;
this.layout.setActiveItem(item);
return;
}
}
this.ownerCt.doLayout();
},
this code is copied out of Ext.container.render ... essentially I am manually re-rendering. This is a hack, I know, but I am not skilled enought yet to come up with a more elegant solution
Below is my complete code:
Code:
Ext.ns('webparts.UserPanel.privsForm');
webparts.UserPanel.privsForm = function(config) {
//Overrideable configs
this.parent_id = null
//Perform override for configs
Ext.apply(this, config);
this.formfields = {}; //create the base object
this.formfields.user_id = new Ext.form.Hidden({
name: 'user_id'
});
this.formfields.superuser = new Ext.form.Checkbox({
id: this.id+'-superuser',
fieldLabel: 'Superuser',
name: 'superuser',
disabled:true,
listeners: {
change: function(field){
this.onFormChange();
},
scope: this
}
});
this.formfields.eco = {};
this.formfields.eco.create = new Ext.form.Checkbox({
id: this.id+'-eco-create',
fieldLabel: 'Create',
name: 'eco-create',
disabled:true,
listeners: {
change: function(field){
this.onFormChange();
},
scope: this
}
});
webparts.UserPanel.privsForm.superclass.constructor.call(this, {
title: 'User Privs',
border: false,
labelWidth: 110,
bodyStyle: 'padding:10px; background: #DFE8F6; border-bottom:1px solid #98C0F4',
style: 'background: #D2E0F2',
items:[
this.formfields.superuser,
{
xtype:'fieldset',
layout:'form',
title: 'Individual Checkboxes',
autoHeight: true,
defaultType: 'checkbox', // each item will be a checkbox
items: [
this.formfields.eco.create
]
}
],
buttons: [
{
text: Ext.util.Format.capitalize(this.mode) //Modify existing record
},{
text: 'Cancel' //Cancel creating new record
}]
});
};
Ext.extend(webparts.UserPanel.privsForm, Ext.FormPanel, {
afterRender : function(){
webparts.UserPanel.privsForm.superclass.afterRender.apply(this, arguments);
if(this.layout){
if(typeof this.layout == 'string'){
this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
}
this.setLayout(this.layout);
if(this.activeItem !== undefined){
var item = this.activeItem;
delete this.activeItem;
this.layout.setActiveItem(item);
return;
}
}
this.ownerCt.doLayout();
},
/*
* Recursive function traverses form and disables all form elements skipping
* UI elements
*/
disableForm : function (){
for (var i in this.formfields){
this.formfields[i].disable();
}
this.enableMode();
},
/*
* Recursive function traverses form and enables all form elements skipping
* UI elements
*/
enableForm : function (){
for (var i in this.formfields){
this.formfields[i].enable();
}
this.enableMode();
},
});
Ext.reg('userprivsform', webparts.UserPanel.privsForm);
To see the bug, the following should work if you drop it in an onReady with a div set
Code:
var bugFormPanel = new webparts.UserPanel.privsForm();
var testPanel= new Ext.TabPanel({
width: 500,
renderTo: <enter your div here>
activeTab: 0,
items: [
{
xtype: 'panel',
title:'dummy panel'
},
this.bugFormPanel
]
});