1. #1
    Sencha User
    Join Date
    Jun 2012
    Posts
    3
    Vote Rating
    0
    hokhengyee is on a distinguished road

      0  

    Default formPanel in a tabPanel not working after tabPanel is activated again.

    formPanel in a tabPanel not working after tabPanel is activated again.


    * Using "Ext JS Library 3.1.1"

    The following steps are the working testcase for my tabPanel Form:

    1) Click on a link on an item in my treePanel, a sidemenu appears.
    2) Click on an option in the sidemenu, a new tabPanel appears with a formPanel in it.
    3) Fill up form on tabPanel and submit, form saves successfully.

    The form would fail with "Uncaught TypeError: Cannot read property 'dom' of undefined" when i perform the following actions:

    1) Click on a link on an item in my treePanel, a sidemenu appears.
    2) Click on an option in the sidemenu, a new tabPanel appears with a formPanel in it.
    3) Repeat steps 1 and 2 again, using the same selected option in the sidemenu, existing tabPanel (same id as the one found in step 2) is activated instead. Keep in mind, that the tabPanel from previous Step 2 is the set as the activePanel when step 3 is completed.
    4) Submit form with details, failed with the error msg in red at top.

    Any advice or solution is greatly appreciated.

    Criteria: I have tried to destroy and recreate the new tabPanel (seems to work), but this is not suitable since it will always do a new GET request each time a user clicks on the "edit" link to create this new tabPanel

    Code:
    /*
    * Basic userForm used for the newly created tabPanel
    */
    function userForm(user_id, user_name, type, user_group){
        function buildUser(user_id){
    
           var thefields = new Ext.form.FieldSet({
                id              : user_group + "-edit-user-" + user_id,
                title           : 'User Details',
                collapsible     : true,
                width           : '90%',
                autoWidth       : true,
                autoHeight      : true,
                bodyStyle       : 'margin:0px auto',
                forceLayout     : true,
                items           : [{
                    fieldLabel  : 'User Login ID',
                    id          : 'user-login-id-edit-'+user_id,
                    xtype       : 'textfield',
                    vtype       : 'username',
                    allowBlank  : false,
                    name        : 'user_login',
                    listeners   : {
                        change    : function(){
    
                            Ext.Ajax.request({
                                url: 'ui/user_update.php',
                                params: {
                                    task        : 'validation',
                                    login_id    : this.getValue()
                                },
                                success: function (resp, opt) {
                                    var ans = Ext.decode(resp.responseText);
                                    // success is set to true IF any result is returned.
                                    if(ans['success'] == true){
                                        Ext.Msg.alert("Error", "Login ID is already taken. Please choose another one.");
                                        Ext.getCmp('user-login-id-edit-'+user_id).reset();
                                    }
                                },
                                failure: function () {
                                    Ext.Msg.alert("Error", "Something went wrong. Please consult admin.");
                                }
                            });
                        }
                    }
                },{
                    fieldLabel  : 'User Name',
                    id          : 'user-name-edit-'+user_id,
                    xtype       : 'textfield',
                    allowBlank  : false,
                    name        : 'user_name'
                }]
            });
    
            return thefields;
        }
    
       var theform = new Ext.FormPanel({
            labelWidth      : 200,
            type            : type,
            buttonAlign     : 'left',
            id              : formid,
            closable        : true,
            setVisible      : false,
            labelAlign      : 'left',
            fieldsAlign     : 'right',
            frame           : true,
            title           : title,
            defaults        : {defaultType : 'textfield', allowBlank: false},
            bodyStyle       : 'padding:5px 5px 0',
            defaultType     : 'textfield',
            deferredRender  : true,
            buttons         : [{
                text           : 'Save',
                tooltip        : 'Save this User',
                iconCls        : 'icon-save-table',
                scale          : 'medium',
                iconAlign      : 'top',
                handler        : function(){
    
                    if (!Ext.getCmp(formid).getForm().isValid()) {
                        Ext.MessageBox.alert('Error', "Form is invalid. Please enter all details as in the fields.");
                    }
                    else
                    {
                        if (Ext.getCmp('assign-to-edit-'+user_id)) {
                            var arr = Ext.getCmp('assign-to-edit-'+user_id).getValue();
                            arr = arr.split(",");
                            var opts = Ext.encode(arr);
                        }
                        //var params = getNonRenderedFields(formid);
                        if(!obj_opts){
                            alert("no items");
                        }
    
                        Ext.getCmp(formid).getForm().submit({
                            url     : 'ui/user_update.php',
                            method  : 'POST',
                            waitMsg : 'Saving...',
                            params  :  {
                                task            : type+'Form',
                                type            : type,
                                opts            : opts,
                                user_id         : user_id,
                                object_types    : obj_opts
                            },
                            listeners   : {
                                submit    : function(a, b){
                                    if (b.inputValue==1){
                                        Ext.getCmp("textfield").enable();
                                        Ext.getCmp("textfield").show();
                                    }else{
                                        Ext.getCmp("textfield").disable(); // set disable to prevent send empty data
                                        Ext.getCmp("textfield").hide();
                                    }
                                }
                            },
                            success : function (form, ans) {
                                var resp = Ext.decode(ans.response.responseText);
                                if (resp.success==true) {
                                    // if this is an update form.
                                    if (theform.type == 'update') {
                                        for (var i = 0; i < object_type.length; i++) {
                                            var type = object_type[i];
                                            if (Ext.getCmp(type + '-user-edit-' + user_id)) {
                                                Ext.getCmp(type + '-grid-' + user_id).getStore().reload();
                                                Ext.getCmp(type + '-user-edit-' + user_id).remove(Ext.getCmp(user_group + '-'+type+'-ind-edit-'+user_id));
                                                //Ext.getCmp(user_group + '-user-' + type + '-user-edit-' + user_id).add(buildInd(type, user_id, 'user'));
                                                Ext.getCmp('user-' + type + '-user-edit-' + user_id).doLayout();
                                            }
                                        }
    
                                        // clear and disable the password fields.
                                        if (Ext.getCmp('user-password-') && Ext.getCmp('user-password-n-') && Ext.getCmp('user-password-c-')) {
                          ......
                                        }
    
                                        // send a success alert.
                                        Ext.MessageBox.alert('Success', "Details Saved.");
                                    } else if (theform.type == 'profile') {
                                        theform.destroy();
                                        Ext.MessageBox.alert('Success', "Details Saved.");
                                    } else {
                                        Ext.getCmp('centraltabs').remove(Ext.getCmp(formid));
                                        Ext.MessageBox.alert("Success", "New user was successfully created.");
                                    }
                                }else{
                                    Ext.MessageBox.alert("Error", resp.error);
                                }
                            },
                            failure: function (form, action) {
                                Ext.MessageBox.alert('Error', action.result.error);
                            }
                        });
                    }
                }
            },{
                text            : 'Cancel',
                iconCls         : 'icon-cross',
                tooltip         : 'Cancel and close the panel',
                scale           : 'medium',
                iconAlign       : 'top',
                handler         : function() {
                    Ext.getCmp('centraltabs').remove(theform);
                }
            }]
        });
    
        theform.add(buildUser(user_id));
        theform.add(buildPermissions(user_id, user_group));
    
        return theform;
    }
    
    
    /*
    * section that creates the new tab with form, or activate it if the tab exists already.
    */
    function updateForm(objarr)
    {
        //generate update form
        var object_type = objarr[0];
        var object_id = objarr[1];
        var object_text = objarr[2];
    
    
        var view = userForm(object_id, object_text, 'update').id;
        var mainPanel = Ext.getCmp('centraltabs');
        var tab = mainPanel.findById(view.id);
        // create new if does not exist
        if (!tab) {
    
    
            Ext.Ajax.request({
                url     : 'crud/credentials.php',
                method  : 'POST',
                params  :
                {
                    task        : 'check_permission',
                    object_id   : object_id,
                    object_type : object_type,
                    perm        : 'update'
                },
                success :function(resp)
                {
                    var ans = Ext.decode(resp.responseText);
                    var view;
                    if(ans.success==true){
                        switch(object_type)
                        {
                            case('user')    :
                                view = userForm(object_id, object_text, 'update');
                                break;
                        }
    
    
                        Ext.getCmp('centraltabs').add(view).show();
                        Ext.getCmp('centraltabs').setActiveTab(view);
    
    
                    }
    
    
                },
                failure :function()
                {
                    Ext.Msg.alert('Status', 'Server not responding');
                }
          });
    
    
        } else {
            mainPanel.setActiveTab(view);
        }
    
    
    }
    
    
    /*
    * menu link click action from a treepanel column on left
    */
    function objectMenu(object_text, object_type, object_id, menuType, perms)
    {
        //objarr: todo: use the id and type, not a composite array.
        var objarr = [object_type, object_id, object_text];
        var tools=[];
    
    
        // link from menu that will supposingly create/activate the new tabPanel
        if(perms<=2){
            tools.push({
                id          : menuType+'-Edit',
                tooltip     : menuType+'-Edit',
                scale       : 'large',
                iconAlign   : 'top',
                icon        : 'icons/edit_large.png',
                text        : 'Edit',
                listeners   : {
                    click :function(){
                        updateForm(objarr);
                    }
                }
            });
        }
    
    
        return tools;
    }
    
    
    function baseFrame(user_id) {
    
    
            // disable context menu by default.
            //Ext.getBody().on("contextmenu", Ext.emptyFn, null, {preventDefault: true});
    
    
            //this file will contain all the basic framework setup functions
            //create JUST the blank framework in the background
    
    
            //Central Tab Area, where the majority of views are taking place
            var tabs = new Ext.TabPanel({
                region                  : 'center',
                margins                 : '3 3 3 0',
                activeTab               : 0,
                id                      : "centraltabs",
                layoutOnTabChange       : true,
                enableTabScroll         : true,
                defaults                : {autoScroll:true},
                listeners               : {
                    // as user changes the between active tab, the toolbar should change too.
                    tabchange  : function () {
                        var t = tabs.getActiveTab();
                        // id of tabpanel should be in this form: object_type-object_id-object_name-function_name
                        var tab_id = t.getId().split('-');
                        var l = tab_id.length;
                        var text = "";
                        // ignore the last element in tab_id[]. it contains the function name.
                        l = l - 1;
                        // first two element is object_type and object_id.
                        for(var i=2; i < l; i++){
                            if(i > 2){
                                // text might have more than 1 '-'.
                                text = text + '-';
                            }
                            text = text + tab_id[i];
                        }
                        // first 2 param is null because they are not nodes from tree.
                        buildToolbar(null, null, tab_id[1], tab_id[0], text);
                        
                        // get help text based on active tab
                        if(Ext.getCmp('help_text')){
                            getHelpText(t);
                        }
                    },
                    // context menu in the tab strip
                    contextmenu : function(tabs, item, e){
                        // create a menu for the contextmenu.
                        var contextMenu = new Ext.menu.Menu();
                        // add first menu item: close this particular panel.
                        contextMenu.add({
                            text    : "Close Panel",
                            handler : function(){
                                item.destroy();
                            }
                        });
                        // show the contextmenu.
                        e.stopEvent();
                        contextMenu.showAt(e.xy);                  
                    }
                }
            });
    
    
            //Toolbar - Main user interaction point, will contain the option buttons
            // that change dynamically based on item that is selected.
    
    
            var menubar = new Ext.Toolbar({
                                region      : 'north',
                                width       : '800',
                                height      : '50',
                                id          : 'menubar',
                                items       :[],
                                allowOtherMenus     : true
                          });
    
    
            //create an outer wrapper to hold the toolbar and the tab panel, since
            //the tabpanel does not support toolbars on top.
            var main_panel = new Ext.Panel({
                                layout  :'border',
                                region  :'center',
                                items   :[menubar, tabs]
                            });
    
    
            // Left hand side nav panel, has an accordion layout
            var nav = new Ext.Panel({
                title           : 'Navigation',
                layout          : 'accordion',
                animCollapse    : true,
                region          : 'west',
                width           : 400,
                collapsible     : true,
                id              : 'nav',
                defaults        : {animCollapse:true}
            });
    
    
            //Place all these elements into a viewport, so that it takes the entire screen real estate.
            var myapp = new Ext.Viewport({
                    layout  :'border',
                            Title   : "My Navigator",
                            items   :[nav, main_panel],
                            id      :'myapp',
                            defaults:{animate:true},
                            user_id : user_id
            });
    }
    Last edited by hokhengyee; 17 Jun 2012 at 5:28 PM. Reason: Updating with code sample

  2. #2
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    9,011
    Vote Rating
    460
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    Please provide a small working test case so we can proceed.

    Regards,
    Scott.

  3. #3
    Sencha User
    Join Date
    Jun 2012
    Posts
    3
    Vote Rating
    0
    hokhengyee is on a distinguished road

      0  

    Default Sample code

    Sample code


    Hi Scott,

    Thanks for the reply.

    Criteria: I have tried to destroy and recreate the new tabPanel (seems to work), but this is not suitable since it will always do a new GET request each time a user clicks on the "edit" link to create this new tabPanel

    Code:
    /*
    * Basic userForm used for the newly created tabPanel
    */
    
    
    function userForm(user_id, user_name, type, user_group){
    
    
        function buildUser(user_id){
    
    
           var thefields = new Ext.form.FieldSet({
                id              : user_group + "-edit-user-" + user_id,
                title           : 'User Details',
                collapsible     : true,
                width           : '90%',
                autoWidth       : true,
                autoHeight      : true,
                bodyStyle       : 'margin:0px auto',
                forceLayout     : true,
                items           : [{
                    fieldLabel  : 'User Login ID',
                    id          : 'user-login-id-edit-'+user_id,
                    xtype       : 'textfield',
                    vtype       : 'username',
                    allowBlank  : false,
                    name        : 'user_login',
                    listeners   : {
                        change    : function(){
    
    
                            Ext.Ajax.request({
                                url: 'ui/user_update.php',
                                params: {
                                    task        : 'validation',
                                    login_id    : this.getValue()
                                },
                                success: function (resp, opt) {
                                    var ans = Ext.decode(resp.responseText);
                                    // success is set to true IF any result is returned.
                                    if(ans['success'] == true){
                                        Ext.Msg.alert("Error", "Login ID is already taken. Please choose another one.");
                                        Ext.getCmp('user-login-id-edit-'+user_id).reset();
                                    }
                                },
                                failure: function () {
                                    Ext.Msg.alert("Error", "Something went wrong. Please consult admin.");
                                }
                            });
                        }
                    }
                },{
                    fieldLabel  : 'User Name',
                    id          : 'user-name-edit-'+user_id,
                    xtype       : 'textfield',
                    allowBlank  : false,
                    name        : 'user_name'
                }]
            });
    
    
            return thefields;
    
    
        }
    
    
       var theform = new Ext.FormPanel({
            labelWidth      : 200,
            type            : type,
            buttonAlign     : 'left',
            id              : formid,
            closable        : true,
            setVisible      : false,
            labelAlign      : 'left',
            fieldsAlign     : 'right',
            frame           : true,
            title           : title,
            defaults        : {defaultType : 'textfield', allowBlank: false},
            bodyStyle       : 'padding:5px 5px 0',
            defaultType     : 'textfield',
            deferredRender  : true,
            buttons         : [{
                text           : 'Save',
                tooltip        : 'Save this User',
                iconCls        : 'icon-save-table',
                scale          : 'medium',
                iconAlign      : 'top',
                handler        : function(){
    
    
                    if (!Ext.getCmp(formid).getForm().isValid()) {
                        Ext.MessageBox.alert('Error', "Form is invalid. Please enter all details as in the fields.");
                    }
                    else
                    {
                        if (Ext.getCmp('assign-to-edit-'+user_id)) {
                            var arr = Ext.getCmp('assign-to-edit-'+user_id).getValue();
                            arr = arr.split(",");
                            var opts = Ext.encode(arr);
                        }
                        //var params = getNonRenderedFields(formid);
                        if(!obj_opts){
                            alert("no items");
                        }
    
    
                        Ext.getCmp(formid).getForm().submit({
                            url     : 'ui/user_update.php',
                            method  : 'POST',
                            waitMsg : 'Saving...',
                            params  :  {
                                task            : type+'Form',
                                type            : type,
                                opts            : opts,
                                user_id         : user_id,
                                object_types    : obj_opts
                            },
                            listeners   : {
                                submit    : function(a, b){
                                    if (b.inputValue==1){
                                        Ext.getCmp("textfield").enable();
                                        Ext.getCmp("textfield").show();
                                    }else{
                                        Ext.getCmp("textfield").disable(); // set disable to prevent send empty data
                                        Ext.getCmp("textfield").hide();
                                    }
                                }
                            },
                            success : function (form, ans) {
                                var resp = Ext.decode(ans.response.responseText);
                                if (resp.success==true) {
                                    // if this is an update form.
                                    if (theform.type == 'update') {
                                        for (var i = 0; i < object_type.length; i++) {
                                            var type = object_type[i];
                                            if (Ext.getCmp(type + '-user-edit-' + user_id)) {
                                                Ext.getCmp(type + '-grid-' + user_id).getStore().reload();
                                                Ext.getCmp(type + '-user-edit-' + user_id).remove(Ext.getCmp(user_group + '-'+type+'-ind-edit-'+user_id));
                                                //Ext.getCmp(user_group + '-user-' + type + '-user-edit-' + user_id).add(buildInd(type, user_id, 'user'));
                                                Ext.getCmp('user-' + type + '-user-edit-' + user_id).doLayout();
                                            }
                                        }
    
    
                                        // clear and disable the password fields.
                                        if (Ext.getCmp('user-password-') && Ext.getCmp('user-password-n-') && Ext.getCmp('user-password-c-')) {
                          ......
                                        }
    
    
                                        // send a success alert.
                                        Ext.MessageBox.alert('Success', "Details Saved.");
                                    } else if (theform.type == 'profile') {
                                        theform.destroy();
                                        Ext.MessageBox.alert('Success', "Details Saved.");
                                    } else {
                                        Ext.getCmp('centraltabs').remove(Ext.getCmp(formid));
                                        Ext.MessageBox.alert("Success", "New user was successfully created.");
                                    }
                                }else{
                                    Ext.MessageBox.alert("Error", resp.error);
                                }
                            },
                            failure: function (form, action) {
                                Ext.MessageBox.alert('Error', action.result.error);
                            }
                        });
                    }
                }
            },{
                text            : 'Cancel',
                iconCls         : 'icon-cross',
                tooltip         : 'Cancel and close the panel',
                scale           : 'medium',
                iconAlign       : 'top',
                handler         : function() {
                    Ext.getCmp('centraltabs').remove(theform);
                }
            }]
        });
    
    
        theform.add(buildUser(user_id));
        theform.add(buildPermissions(user_id, user_group));
    
    
        return theform;
    
    
    }
    
    
    /*
    * section that creates the new tab with form, or activate it if the tab exists already.
    */
    function updateForm(objarr)
    {
        //generate update form
        var object_type = objarr[0];
        var object_id = objarr[1];
        var object_text = objarr[2];
    
    
        var view = userForm(object_id, object_text, 'update').id;
        var mainPanel = Ext.getCmp('centraltabs');
        var tab = mainPanel.findById(view.id);
        // create new if does not exist
        if (!tab) {
    
    
            Ext.Ajax.request({
                url     : 'crud/credentials.php',
                method  : 'POST',
                params  :
                {
                    task        : 'check_permission',
                    object_id   : object_id,
                    object_type : object_type,
                    perm        : 'update'
                },
                success :function(resp)
                {
                    var ans = Ext.decode(resp.responseText);
                    var view;
                    if(ans.success==true){
                        switch(object_type)
                        {
                            case('user')    :
                                view = userForm(object_id, object_text, 'update');
                                break;
                        }
    
    
                        Ext.getCmp('centraltabs').add(view).show();
                        Ext.getCmp('centraltabs').setActiveTab(view);
    
    
                    }
    
    
                },
                failure :function()
                {
                    Ext.Msg.alert('Status', 'Server not responding');
                }
          });
    
    
        } else {
            mainPanel.setActiveTab(view);
        }
    
    
    }
    
    
    /*
    * menu link click action from a treepanel column on left
    */
    function objectMenu(object_text, object_type, object_id, menuType, perms)
    {
        //objarr: todo: use the id and type, not a composite array.
        var objarr = [object_type, object_id, object_text];
        var tools=[];
    
    
        // link from menu that will supposingly create/activate the new tabPanel
        if(perms<=2){
            tools.push({
                id          : menuType+'-Edit',
                tooltip     : menuType+'-Edit',
                scale       : 'large',
                iconAlign   : 'top',
                icon        : 'icons/edit_large.png',
                text        : 'Edit',
                listeners   : {
                    click :function(){
                        updateForm(objarr);
                    }
                }
            });
        }
    
    
        return tools;
    }
    
    
    function baseFrame(user_id) {
    
    
            // disable context menu by default.
            //Ext.getBody().on("contextmenu", Ext.emptyFn, null, {preventDefault: true});
    
    
            //this file will contain all the basic framework setup functions
            //create JUST the blank framework in the background
    
    
            //Central Tab Area, where the majority of views are taking place
            var tabs = new Ext.TabPanel({
                region                  : 'center',
                margins                 : '3 3 3 0',
                activeTab               : 0,
                id                      : "centraltabs",
                layoutOnTabChange       : true,
                enableTabScroll         : true,
                defaults                : {autoScroll:true},
                listeners               : {
                    // as user changes the between active tab, the toolbar should change too.
                    tabchange  : function () {
                        var t = tabs.getActiveTab();
                        // id of tabpanel should be in this form: object_type-object_id-object_name-function_name
                        var tab_id = t.getId().split('-');
                        var l = tab_id.length;
                        var text = "";
                        // ignore the last element in tab_id[]. it contains the function name.
                        l = l - 1;
                        // first two element is object_type and object_id.
                        for(var i=2; i < l; i++){
                            if(i > 2){
                                // text might have more than 1 '-'.
                                text = text + '-';
                            }
                            text = text + tab_id[i];
                        }
                        // first 2 param is null because they are not nodes from tree.
                        buildToolbar(null, null, tab_id[1], tab_id[0], text);
                        
                        // get help text based on active tab
                        if(Ext.getCmp('help_text')){
                            getHelpText(t);
                        }
                    },
                    // context menu in the tab strip
                    contextmenu : function(tabs, item, e){
                        // create a menu for the contextmenu.
                        var contextMenu = new Ext.menu.Menu();
                        // add first menu item: close this particular panel.
                        contextMenu.add({
                            text    : "Close Panel",
                            handler : function(){
                                item.destroy();
                            }
                        });
                        // show the contextmenu.
                        e.stopEvent();
                        contextMenu.showAt(e.xy);                  
                    }
                }
            });
    
    
            //Toolbar - Main user interaction point, will contain the option buttons
            // that change dynamically based on item that is selected.
    
    
            var menubar = new Ext.Toolbar({
                                region      : 'north',
                                width       : '800',
                                height      : '50',
                                id          : 'menubar',
                                items       :[],
                                allowOtherMenus     : true
                          });
    
    
            //create an outer wrapper to hold the toolbar and the tab panel, since
            //the tabpanel does not support toolbars on top.
            var main_panel = new Ext.Panel({
                                layout  :'border',
                                region  :'center',
                                items   :[menubar, tabs]
                            });
    
    
            // Left hand side nav panel, has an accordion layout
            var nav = new Ext.Panel({
                title           : 'Navigation',
                layout          : 'accordion',
                animCollapse    : true,
                region          : 'west',
                width           : 400,
                collapsible     : true,
                id              : 'nav',
                defaults        : {animCollapse:true}
            });
    
    
            //Place all these elements into a viewport, so that it takes the entire screen real estate.
            var myapp = new Ext.Viewport({
                    layout  :'border',
                            Title   : "My Navigator",
                            items   :[nav, main_panel],
                            id      :'myapp',
                            defaults:{animate:true},
                            user_id : user_id
            });
    }

  4. #4
    Sencha User
    Join Date
    Jun 2012
    Posts
    3
    Vote Rating
    0
    hokhengyee is on a distinguished road

      0  

    Default


    Hi,

    I have found the solution.

    for the "switch(object_type)" section, for each case I will need to check if there is an existing "view" and use it, or create a new one (".add(view)")when there is none.

    After choosing the appropriate "view", then only I return this into the "Ext.getCmp('centraltabs').setActiveTab(view)" section.

Thread Participants: 1

Tags for this Thread