Results 1 to 10 of 10

Thread: FormPanel with TabPanel and multiple HTMLEditors

  1. #1
    Ext User
    Join Date
    Jun 2007
    Location
    Gainesville, VA
    Posts
    32

    Default FormPanel with TabPanel and multiple HTMLEditors

    I have a form panel that has one tab panel with two tabs (this form is stripped down for demonstration purposes)
    PHP Code:
            this.formPanel = new Ext.FormPanel({
                
    url:aurl,
                
    labelAlign'top',
                
    baseParams:{resp:'json',single:true},
                
    labelWidth125
                
    borderfalse,
                
    bodyStyle:'padding:10px;',
                
                
    items: [{
                            
    xtype:'tabpanel',
                            
    id:'atabpanel',
                            
    plain:true,
                            
    activeTab0,
                            
    height:250,
                            
    defaults:{layout:'fit',hideLabel:true,anchor:'98%'},
                            
    items:
                                [{
                                    
    title:'HTMLEditor 1',
                                    
    items:[{
                                        
    id:'editor1',
                                        
    xtype:'htmleditor',
                                        
    fieldLabel'Editor One',
                                        
    name'editor1.value',
                                    }]
                                },{
                                    
    title:'Editor2',
                                    
    items:[{
                                        
    id:'editor2',
                                        
    xtype:'htmleditor',
                                        
    fieldLabel'Editor Two',
                                        
    name'editor2.value',
                                    }]
                                }]
                        }]
            }); 
    I use this form for both creating new records and editing existing records. If I do a form.load(..) and edit a record with a value in Editor Two, any subsequent form.reset() will keep the Editor Two content. Since I create new records with this form, when I show the form again and do a form.reset() the old value is still there.

    I've found that the problem is related to when the Editor Two htmleditor is rendered. It doesn't get rendered until AFTER I activate the Editor2 Tab, which makes sense using lazy rendering. But when it is rendered, the originalValue property is set to whatever the value of the component is.

    I tried doing a deferredRender: false on the TabPanel, but that spit out some crazy error.

    [Exception... "Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMNSHTMLDocument.queryCommandState]" nsresult: "0x80004003 (NS_ERROR_INVALID_POINTER)" location: "JS frame :: http://extjs.com/forum/clientscript/...tedit.js?v=367 :: anonymous :: line 1460" data: no]

    If I set activeTab:2 on the TabPanel config, then the problem just moves over to tab1 (the hidden/non-rendered tab).

    Ideally, what I'd like to do is have all the htmleditor(s) rendered when the form is rendered and not wait for the tab to be active. Any idea on how this can be achieved? Anyone else have any problems similar to the above and solved it differently?

    Thanx,
    Phill

  2. #2
    Sencha User jay@moduscreate.com's Avatar
    Join Date
    Mar 2007
    Location
    DC Area =)
    Posts
    16,364

    Default

    i've had the exact same issues.

    What i did was treat each object individually. i learned that even if you do a setvalues on the form - edit only ONE field, do a getValues - you ONLY get the values for the html editors taht are rendered. the work around was to talk to each object individually, setting and getting values. :-\


    Hope this helps:
    PHP Code:
        doFormWindow : function (recordrowIndexreadonly) {
        
            if (! 
    this.appDescEditorWindow) {
            
                
                if (
    Ext.isIE6) {
                    var 
    width 450;    
                }
                else if (
    Ext.isGecko) {
                    var 
    width 470;
                }
                else {
                    var 
    width 480;
                }
                
                
    this.appFormPanel this.doTabForm();

                
    this.appDescEditorWindow = new Ext.Window({
                    
    animateTarget this.grid.body.id,                                 
                    
    layout        'fit',
                    
    width        600,
                    
    height        375,
                    
    closeAction 'hide',
                    
    plain        true,
                    
    modal        true,
                    
    items         : [ this.appFormPanel ],
                    
    buttons        : [{
                        
    text'Save',
                        
    cls:"x-btn-text-icon",
                        
    icon'img/toolbar/silk_icons/icons/disk.png',
                        
    scope this,
                        
    handler: function () {
                            if (
    this.appFormPanel.form.isValid()) {
                                var 
    formItems this.appFormPanel.form.items.items;

                                var 
    appDetailsAppID        formItems[0].getValue();
                                var 
    appBRS                 formItems[1].getValue();    
                                var 
    appDescription        formItems[2].getValue();    
                                var 
    appScopeImpact         formItems[3].getValue();    
                                var 
    appAKA                 formItems[4].getValue();    
                                var 
    appSvcsContact         formItems[5].getValue();    
                                var 
    appOutageWindows     formItems[6].getValue();
                                
                                if (
    appDescription.length 1000) {
                                    
    Ext.MessageBox.alert('Error''The description field is too long.  Please reduce it\'s size to 1,024 characters or less.');
                                    return(
    false);
                                }
                                if (
    appScopeImpact.length 1000) {
                                    
    Ext.MessageBox.alert('Error''The Scope/Impact field is too long.  Please reduce it\'s size to 1,024 characters or less.');
                                    return(
    false);
                                }
                                if (
    appAKA.length 1000) {
                                    
    Ext.MessageBox.alert('Error''The AKA field is too long.  Please reduce it\'s size to 1,024 characters or less.');
                                    return(
    false);
                                }
                                if (
    appSvcsContact.length 1000) {
                                    
    Ext.MessageBox.alert('Error''The Svcs Contact field is too long.  Please reduce it\'s size to 1,024 characters or less.');
                                    return(
    false);
                                }
                                if (
    appOutageWindows.length 1000) {
                                    
    Ext.MessageBox.alert('Error''The Outage Window(s) field is too long.  Please reduce it\'s size to 1,024 characters or less.');
                                    return(
    false);
                                }
                                
                                var 
    data = {
                                    
    appDetailsAppID        appDetailsAppID,    
                                    
    appBRS                 appBRS,    
                                    
    appDescription        appDescription,    
                                    
    appScopeImpact         appScopeImpact,    
                                    
    appAKA                 appAKA,    
                                    
    appSvcsContact         appSvcsContact,    
                                    
    appOutageWindows     appOutageWindows
                                
    }
                                var 
    urlData Ext.urlEncode(data);

                                
    this.appFormPanel.form.submit({
                                    
    url 'cmdbAppDetails.php?action=modify&' urlData,
                                    
    scope this,
                                    
    success : function () {
                                        var 
    record this.ds.getAt(this.globalRowIndex);
                                        
    record.beginEdit();
                                        
    record.data.APP_DESCRIPTION     data.appDescription;
                                        
    record.data.APP_SCOPE            data.appScopeImpact;
                                        
    record.data.APP_AKA                data.appAKA;
                                        
    record.data.APP_SVCS_LEAD        data.appSvcsContact;
                                        
    record.data.APP_BRS                data.appBRS;
                                        
    record.data.APP_OUTAGE_WINDOW    data.appOutageWindows;
                                        
                                        
    record.json.APP_DESCRIPTION     data.appDescription;
                                        
    record.json.APP_SCOPE            data.appScopeImpact;
                                        
    record.json.APP_AKA                data.appAKA;
                                        
    record.json.APP_SVCS_LEAD        data.appSvcsContact;
                                        
    record.json.APP_BRS                data.appBRS;
                                        
    record.json.APP_OUTAGE_WINDOW    data.appOutageWindows;

                                        
    record.commit();
                                        
    this.ds.commitChanges();
                                        
    this.appDescEditorWindow.hide();
                                    },
                                    
    failure : function () {
                                        
    alert('failed');    
                                    }
                                });
                            }
                
                        }
                        
                    },{
                        
    text'Cancel',
                        
    cls:"x-btn-text-icon",
                        
    icon'img/toolbar/silk_icons/icons/stop.png',
                        
    scope this// IMPORTANT
                        
    handler : function () {
                            
    this.appDescEditorWindow.hide();
                        }
                    }]
                });
            
            }
            
    this.appDescEditorWindow.setTitle('Edit: ' record.json.APPLICATION);

            
    this.appDescEditorWindow.show();
            var 
    record this.ds.getAt(this.globalRowIndex);

            if (
    record) {
                var 
    formItems this.appFormPanel.form.items.items;
                
    formItems[0].setValue(record.json.CMDB_ID);
                
    formItems[1].setValue(record.json.APP_BRS);
                
    formItems[2].setValue(record.json.APP_DESCRIPTION);
                
    formItems[3].setValue(record.json.APP_SCOPE);
                
    formItems[4].setValue(record.json.APP_AKA);
                
    formItems[5].setValue(record.json.APP_SVCS_LEAD);
                
    formItems[6].setValue(record.json.APP_OUTAGE_WINDOW);
            }
            else {
                
    //console.log(this.appFormPanel);
                
    this.appFormPanel.form.reset();
            }

            
    this.appFormPanel.items.items[2].setActiveTab(0);
            
            if (
    readonly) {
                
    this.appFormPanel.form.items.map.appBRS.disable();
                
    this.appDescEditorWindow.buttons[0].disable();
            }
            else {
                
    //this.appFormPanel.form.items.map.appAKA.enable();                    
                //this.appDescEditorWindow.buttons[0].enable();                    
            
    }
        
        }, 

  3. #3
    Ext User
    Join Date
    Jun 2007
    Location
    Gainesville, VA
    Posts
    32

    Default

    OK, I found a way to render the darn thing before showing it while still doing it 'lazily'...
    I have a 'dialogManager' that returns an Ext.Window object. In that function, I lazily load the window and render it. Then I cycle through the tabs in the tab panel and for each of them, call activate(). Calling activate() will force the items within it to be rendered. See the code below:

    PHP Code:
           if(!this.formWindow){ // only instantiate the window once
                
    this.formWindow = new formWindow();  // formWindow extends Ext.Window
                
    this.formWindow.render(Ext.getBody());//  force it to render to the body 
                
    var panel Ext.getCmp('tabpanel');      // get the tab panel
                
    var tabs panel.items.items;              // convenience - get the array of items
                
    Ext.each(tabs,function(){                  // for each tab in the panel
                    
    this.ownerCt.activate(this);           // call the activate() method
                
    })
    //            panel.activate(tabs[0]);                  // reset the active tab to the first one
            

    Now, there are no issues pre-populating or submitting the form.
    PHP Code:
    formSave: function() {
            
            var 
    form this.formPanel.getForm(); 

            
    // using struts dispatch actions, so tell it to call the 'save' method and output the results as json
            
    form.submit({params:{resp:'json',dispatch:'save'}}); 

            
    this.hide();  
            
    // tell any listeners that the save event was fired.
            
    this.fireEvent('save');  
        } 
    -Phill

  4. #4

    Default

    I don't want to use "deferredRender:false" or programmatically activate all tab.
    Is there any way else to render form elements in other tab which not been rendered?

  5. #5

    Default

    PHP Code:
    Ext.getCmp("mainTabPanel").doLayout(); 
    It couldn't work what i expected.
    Any idea?

    Thanks in advance.

  6. #6
    Sencha User krycek's Avatar
    Join Date
    Jun 2007
    Posts
    96

    Default

    I have the same issue, but using "deferredRender:false" besides showing that exception ([Exception... "Component returned failure code: 0x80004003 (NS_ERROR_IN ... ) solved the problem.

    But those exceptions are not good to see ;|

  7. #7
    Ext User
    Join Date
    Jun 2007
    Location
    Gainesville, VA
    Posts
    32

    Default

    *bluethinking*

    If you want the htmleditor to be rendered, you must activate the tab/card that is holding it (the htmleditor's container). mainTabPanel.doLayout() is going to render the active tab/card and its contents. If the htmleditor is in that tab, then fine, it gets rendered. If it's in another tab/card, you must activate() it before the htmleditor is rendered. How you do that is up to you, but I've outlined one method above. djliquidice has outlined his fix for the problem as well.

    -Phill

  8. #8

    Default

    Thanks for the reply, guys.
    the "doLayout()" function of form element's parent panel is still broken.

    PHP Code:
    Ext.onReady(function(){

        
    Ext.QuickTips.init();
        
    Ext.form.Field.prototype.msgTarget 'side';

        var 
    formPanel = new Ext.FormPanel({
            
    url'',
            
    title'HTMLEdit Form',
            
    labelAlign'top',
            
    baseParams:{resp:'json',single:true},
            
    labelWidth125
            
    bordertrue,
            
    frametrue,
            
    bodyStyle:'padding:10px;',
            
            
    items: [
                {
    xtype:'tabpanel',
                
    id:'atabpanel',
                
    plain:true,
                
    activeTab0,
                
    height:250,
                
    defaults:{layout:'fit',hideLabel:true,anchor:'98%'},
                
    items: [
                    {
                        
    title:'HTMLEditor 1',
                        
    id'editor1Panel',
                        
    items:[
                            {
                                
    id:'editor1',
                                
    xtype:'htmleditor',
                                
    fieldLabel'Editor One',
                                
    name'editor1.value'
                            
    }
                    ]},{
                        
    title:'Editor2',
                        
    id'editor1Pane2',
                        
    items:[
                            {
                                
    id:'editor2',
                                
    xtype:'htmleditor',
                                
    fieldLabel'Editor Two',
                                
    name'editor2.value'
                            
    }
                    ]}
    //Editor2
                
    ]}//atabpanel
            
    ]// formPanel's items
        
    });//formPanel
        
    formPanel.render(document.body);
        
        
    Ext.getCmp("editor1Pane2").doLayout();
        
    alert(Ext.getCmp("editor2").rendered); //false
        
        /** 
         * FireBug Error:    
         * document.getElementById("editor2") has no properties
         * [Break on this error] document.getElementById("editor2").value = "My editor2."; 
        */
        
    document.getElementById("editor2").value "My editor2.";
        
    alert(document.getElementById("editor2").value);
    }); 

  9. #9

    Default

    ERROR:document.getElementById("editor2") has no properties

    so it means that doLayout() can not render all of its items.

  10. #10
    Sencha User GraemeBryce's Avatar
    Join Date
    Sep 2007
    Location
    Scotland
    Posts
    89

    Default

    I have found that setting:-

    Code:
    layoutOnTabChange:true,
    on the TabPanel(s) will cause the html editors to render correctly although I still get the "component..." error in firefox (but not in any other browser)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •