Search code examples
javascriptextjsextjs3

ExtJS 3.2 Can only add a panel once


I've extremely new to ExtJS. I'm trying to add a remove panels during a script and I can only add a panel once. The moment I try to add it again it receive an error

TypeError: b.getPositionEl(...).dom is undefined
Ext.layout.ContainerLayout<.isValidParent()
 ext-all.js:7
Ext.layout.ContainerLayout<.renderAll()
 ext-all.js:7
Ext.layout.ContainerLayout<.onLayout()
 ext-all.js:7
Ext.layout.AutoLayout<.onLayout()
 ext-all.js:7
Ext.layout.ContainerLayout<.layout()
 ext-all.js:7
Ext.Container<.doLayout()
 ext-all.js:7
Ext.Container<.doLayout()
 ext-all.js:7
restart()
 RunScript:138
h.Event.prototype.fire()
 ext-all.js:7
h.Observable.prototype.fireEvent()
 ext-all.js:7
.onClick()
 keyscript-all.js:4
I()

I basically just remove and add the panels in case the cancel button is pressed. Everything displays fine when I press the continue button, the new panel displays and renders the data as it's collected and no errors are displayed. But once I press the cancel button, the panel I want to remove is gone but once it tries to add the optionPanel the error mentioned above shows. I can however, add a completely different panel and it will not display an error.

var workPanel = new CR.FormPanel({
    id: 'workPanel',
    title: 'Bad Address Workflow',
    region: 'center',
    frame: true,
    labelWidth: 300,
    autoScroll: true,
    bodyStyle: {
      padding: '5px',
      font: '12px arial,tahoma,helvetica,sans-serif'
    },
    buttons:[
        {
            text: 'Post',
            listeners: {
                click: doPost
            }
        },
        {
            text: 'Cancel',
            listeners: {
                click: restart
            }
        }
    ],
    buttonAlign: 'left'
});

var optionPanel = new CR.FormPanel({
    id: 'optionPanel',
    title: 'Bad Address Workflow',
    region: 'center',
    frame: true,
    labelWidth: 175,
    bodyStyle:'padding:5px 5px 0',
    defaults: {
      width: 230
    },
    items: [
      {
        xtype: 'crOptionField',
        crColumnDescription: 'Choose Bad Address Workflow',
        crColumnName: 'workflowOptions',
        crOptions: [
          ["",""],
          ["0","Set Bad Address"],
          ["1","Remove Bad Address"]
        ]
      }
    ],
    buttons: [
      {
        text: 'Continue',
        listeners: {
            click: function(button,event){
                var fields = optionPanel.find('crColumnName','workflowOptions');

                if(parseInt(fields[0].crGetNewContents()) === 0){
                    workflow = 0;
                    getMemberData();
                }else if(parseInt(fields[0].crGetNewContents()) === 1){
                    workflow = 1;
                    getMemberData();
                }else{
                    CR.Core.displayExceptions({ items: ['You have not selected an option.'] });
                }
            }
        }
      }
    ],
    buttonAlign: 'left'
});

var container = new Ext.Container({
    id: 'container',
    frame: true,
    region: 'center',
    bodyStyle:'padding:5px 5px 0',
    defaults: {
        xtype: 'container'
    }
});

Ext.onReady(function(){
    
   container.add(optionPanel);         
   CR.Core.viewPort = new Ext.Viewport({
    layout: 'border',
    region: 'center',
    items: [container]
   });   

});

function restart(){    
    container.remove(workPanel);
    container.add(optionPanel);
    CR.Core.viewPort.doLayout();
}

function getMemberData(){
    
    container.remove(optionPanel);
    container.add(workPanel);
    CR.Core.viewPort.doLayout();
    
    //My data collection process
}

Any help is greatly appreciated.


Solution

  • Yes you can add multiple time in container. You getting error

    TypeError: b.getPositionEl(...).dom is undefined

    Reason of this error is when you use remove method to remove the component from view. It will remove the component from dom permanently. When you try again add then it will undefined so it is creating error TypeError: b.getPositionEl(...).dom is undefined.

    For this solution is, You need to always create component and return from function.

    In this FIDDLE, I have created a demo using your code and put some modification. I hope this will guide you or help you to achieve your requirement.

    Code Snippet

    Ext.onReady(function() {
        //ReSet  view set optionPanel
        function restart() {
            container.remove(Ext.getCmp('workPanel'));
            container.add(optionPanel());
            doLayout();
        }
        //Remove optionPanel and add workPanel in container
        function getMemberData() {
            container.remove(Ext.getCmp('optionPanel'));
            container.add(workPanel());
            doLayout();
        }
        //update layout of view
        function doLayout() {
            container.doLayout();
        }
        //create and return work flow panel
        var workPanel = function() {
            return new Ext.FormPanel({
                title: 'Bad Address Workflow',
                id: 'workPanel',
                region: 'center',
                frame: true,
                labelWidth: 300,
                autoScroll: true,
                bodyStyle: {
                    padding: '5px',
                    font: '12px arial,tahoma,helvetica,sans-serif'
                },
                buttons: [{
                    text: 'Post'
                }, {
                    text: 'Cancel',
                    listeners: {
                        click: restart
                    }
                }],
                buttonAlign: 'left'
            });
        }
        //create and return option panel
    
        var optionPanel = function() {
            return new Ext.FormPanel({
                id: 'optionPanel',
                title: 'Bad Address Workflow',
                region: 'center',
                frame: true,
                labelWidth: 175,
                bodyStyle: 'padding:5px 5px 0',
                defaults: {
                    width: 230
                },
                items: [
                    // create the combo instance
                    new Ext.form.ComboBox({
                        typeAhead: true,
                        triggerAction: 'all',
                        lazyRender: true,
                        mode: 'local',
                        name: 'workflowOptions',
                        itemId: 'workflowOptions',
                        store: new Ext.data.ArrayStore({
                            fields: [
                                'myId',
                                'displayText'
                            ],
                            data: [
                                ["", ""],
                                ["0", "Set Bad Address"],
                                ["1", "Remove Bad Address"]
                            ]
                        }),
                        valueField: 'myId',
                        displayField: 'displayText'
                    })
                ],
                buttons: [{
                    text: 'Continue',
                    listeners: {
                        click: function(button, event) {
                            //Get value of seleted value in combotbox 
                            //using get component method
                            var value = Ext.getCmp('optionPanel').getComponent('workflowOptions').getValue();
    
                            if (value === "0") {
                                workflow = 0;
                                getMemberData();
                            } else if (value === "1") {
                                workflow = 1;
                                getMemberData();
                            } else {
                                Ext.Msg.alert('Info', 'You have not selected an option.')
                            }
                        }
                    }
                }],
                buttonAlign: 'left'
            })
        };
        //Main container that contains option and workflow panel.
        var container = new Ext.Container({
            renderTo: Ext.getBody(),
            frame: true,
            region: 'center',
            bodyStyle: 'padding:5px 5px 0',
            defaults: {
                xtype: 'container'
            },
            items: [optionPanel()]
        });
    });