1. #1
    Sencha User
    Join Date
    Aug 2008
    Posts
    65
    Vote Rating
    0
    smudgeface is on a distinguished road

      0  

    Default [2.??] form panel added to tab panel

    [2.??] form panel added to tab panel


    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 
            ]
        });

  2. #2
    Sencha User
    Join Date
    Aug 2008
    Posts
    65
    Vote Rating
    0
    smudgeface is on a distinguished road

      0  

    Default


    Just an update:

    another way of fixing the problem is to add the following into the extension

    Code:
    this.on({
            activate: function(){
                this.ownerCt.doLayout();
            },
            scope: this
    })
    However this shouldn't be required as all elements in the panel are defined in the config.

  3. #3
    Sencha - Community Support Team mystix's Avatar
    Join Date
    Mar 2007
    Location
    Singapore
    Posts
    6,236
    Vote Rating
    5
    mystix will become famous soon enough

      0  

    Default


    try it with the layoutOnTabChange config on the TabPanel:
    http://extjs.com/docs/?class=Ext.Tab...outOnTabChange

  4. #4
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,505
    Vote Rating
    52
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Configure the FormPanel with hideMode: 'offsets' so that the items within the Fieldset have layout, and therefore a measurable size.

Thread Participants: 2