-
28 Nov 2007 7:24 PM #1
[2.0rc1] Combo Fields in a hidden tab render incorrectly with deferredRender: false
[2.0rc1] Combo Fields in a hidden tab render incorrectly with deferredRender: false
Hey, all.
I'm having a major problem using combo fields, date fields, time fields, etc., in a tabpanel when deferredRender is set to false.
I MUST use deferredRender: false.
I have one over-arching form that contains the tabpanel, all the tabs, and form fields. All fields on every tab should be submitted at once with the form. Additionally, I use the 'load' action to populate the data from JSON returned by the server.
If I use deferredRender: true, when the load action is called, any fields contained by a tab that has not yet been shown do not get populated because they do not yet exist.
The problem is that the width of the field is not rendered correctly, presumably because the sizing and layout of the panel contained in a tab that has not yet been displayed has not been calculated by the time the form is added to it. That is just my best guess, since I don't know much about the Ext internals.
deferredLayout: false should make the TabPanel set up all the sizing and layout for panels even if they have not yet been displayed.
Additionally, calling doLayout() on the FormPanel container, the TabPanel, or the Panel containing the form in question after it has been rendered and displayed does nothing.
I have posted a simplified example on my website at http://www.codecomposer.net/ext/examples/tabs/tabs.html
I wrote the example javascript to plug into the tabs.html example provided with Ext 2.0rc1.
For now, my fallback is to use traditional, hand-coded HTML forms in the tabpanel.
I've attached two screenshots.
Picture 1.jpg is the result in Safari 3.0.4 beta (Mac)
Picture 2.jpg is the result in Firefox 2.0.0.10 (Mac)
I'm not even going to bother targeting Firefox on mac --- there are WAY too many problems with Ext running in Firefox 2 for mac. Most all of them are Mozilla's fault and I've submitted some bug reports there, but I doubt anything will be done about them with FF3's imminent release. Firefox 2 on Linux is worse still -- pretty much completely unusable with a heavy Ext app due to slow-as-molasses speeds.
Here is the code:
Code:Ext.onReady(function(){ /* ========================================= First Tab Set uses deferredRender: true This works correctly. ========================================= */ var tabs1 = new Ext.FormPanel({ renderTo: document.body, title: 'Form Test', url: '/', width: 350, height: 180, layout: 'fit', items: [ { xtype: 'tabpanel', activeTab: 0, height: 153, // Why do I have to specify the height here? // Shouldn't its container's 'fit' layout take // care of that? border: false, deferredRender: true, // This works defaults: {autoScroll: true}, items: [ { title: 'Basic Tab One', bodyStyle: 'padding 10px;', html: "This is just some text..." }, { layout: 'form', title: 'Form Tab One', labelAlign: 'right', defaults: {width: 175}, items: [ { xtype: 'textfield', name: 'text_field_1', value: 'Foo Bar', fieldLabel: 'Text Field 1' }, { xtype: 'combo', hiddenName: 'combo_field_1', fieldLabel: 'Combo Field 1', store: new Ext.data.SimpleStore({ fields: ['name', 'value'], data: [ ["Option 1","1"], ["Option 2","2"], ["Option 3","3"] ] }), editable: false, allowBlank: true, valueField:'value', displayField:'name', typeAhead: true, mode: 'local', triggerAction: 'all', selectOnFocus:true }, { xtype: 'datefield', name: 'date_field_1', fieldLabel: 'Date Field 1' } ] } ] } ] }); /* ====================================================================== Second Tab Set uses deferredRender: false The forms do not render correctly, presumably because the panel's contents don't know how to size themselves until the layout has been run on their container panel... but I'm not sure, as I don't really know how Ext works under the hood. ====================================================================== */ var tabs2 = new Ext.FormPanel({ renderTo: document.body, title: 'Form Test', url: '/', width: 350, height: 180, layout: 'fit', items: [ { xtype: 'tabpanel', activeTab: 0, height: 153, border: false, deferredRender: false, // This doesn't. defaults: {autoScroll: true}, items: [ { title: 'Basic Tab One', bodyStyle: 'padding 10px;', html: "This is just some text..." }, { layout: 'form', title: 'Form Tab One', labelAlign: 'right', defaults: {width: 175}, items: [ { xtype: 'textfield', name: 'text_field_1', value: 'Foo Bar', fieldLabel: 'Text Field 1' }, { xtype: 'combo', hiddenName: 'combo_field_1', fieldLabel: 'Combo Field 1', store: new Ext.data.SimpleStore({ fields: ['name', 'value'], data: [ ["Option 1","1"], ["Option 2","2"], ["Option 3","3"] ] }), editable: false, allowBlank: true, valueField:'value', displayField:'name', typeAhead: true, mode: 'local', triggerAction: 'all', selectOnFocus:true }, { xtype: 'datefield', name: 'date_field_1', fieldLabel: 'Date Field 1' } ] } ] } ] }); });Last edited by theturtle32; 28 Nov 2007 at 7:32 PM. Reason: Adding details
-
28 Nov 2007 10:05 PM #2
Found a workaround
Found a workaround
Ok, I found a workaround finally... It's a little bit cheezy but it works for now.
Basically, we set deferredRender back to true, and then iterate through the tabs, activating each one of them before re-activating the tab that we want to be the default.
Code:var tabPanel = (initialize tabpanel here) tabPanel.items.each(function(item) { tabPanel.activate(item); // force tabs to render by activating them }); tabPanel.activate('name_of_first_tab'); // return to first tabLast edited by theturtle32; 28 Nov 2007 at 10:06 PM. Reason: more detail.
-
13 Dec 2007 11:26 AM #3
Does anyone have any ideas about this issue? This is kindof a big deal and nobody's commented on it yet.
-
13 Dec 2007 2:36 PM #4
Have you retested this with 2.0 Final? Also, have you tried the layoutOnTabChange:true config?
Tim Ryan
Read BEFORE posting a question / BEFORE posting a Bug
Use Google to Search - API / Forum
API Doc (4.x | 3.x | 2.x | 1.x) / FAQ / 1.x->2.x Migration Guide / 2.x->3.x Migration Guide
-
14 Dec 2007 3:32 AM #5
Hi,
I can confirm this bug in 2.0-final. Here's my testcase:
With "layoutOnTabChange: true", everything works OK, but using "deferredRender: false" is sometimes preferred.Code:Ext.onReady(function() { var win = new Ext.Window({ layout: 'fit', width: 620, height: 300, plain: true, items: { xtype: 'form', border: false, items: { xtype: 'tabpanel', plain: true, deferredRender: false, // layoutOnTabChange: true, activeTab: 0, autoHeight: true, items: [ { title: 'Tab 1', autoHeight: true, items: [ { xtype: 'fieldset', title: 'Fieldset 1.1', style: 'margin: 10px; padding: 10px', autoHeight: true, html: 'This tab (activeTab) renders fine. There is a problem with the other tab(s), when <b>deferredRender</b> is set <b>false</b> on TabPanel. TriggerFields are longer than TextFields. Click the other tab...' }, ] }, { title: 'Tab 2', items: [ { xtype: 'fieldset', title: 'Fieldset 2.1', style: 'margin: 10px; padding: 10px', autoHeight: true, items: [ { xtype: 'combo', fieldLabel: 'ComboBox 2.1.1', width: 150 }, { xtype: 'textfield', fieldLabel: 'Textfield 2.1.1', width: 150 }, { xtype: 'textfield', fieldLabel: 'TextField 2.1.2', width: 150 } ] }, ] } ] } } }); win.show(this); });

Last edited by erki; 3 Jan 2008 at 2:30 AM. Reason: adding testcase
-
18 Dec 2007 6:00 PM #6
I am experiencing this exact same problem. I came across this when trying to load a Record into a form. The data does not load into any inactive tabs in the form when deferredRender is true. The data will load perfectly when deferredRender is false, but comboboxes go crazy. The trigger on the combo is misaligned and when clicked, the list is very narrow. See attached image.
Here's sample code:
theturtle32, thanks for the workaround, i'll give it a shot.HTML Code:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Forms</title> <link rel="stylesheet" type="text/css" href="js/ext2/css/ext-all.css"/> <script type="text/javascript" src="js/ext2/ext-base.js"></script> <script type="text/javascript" src="js/ext2/ext-all.js"></script> <script type="text/javascript"> Ext.onReady(function(){ Ext.QuickTips.init(); // turn on validation errors beside the field globally Ext.form.Field.prototype.msgTarget = 'side'; var bd = Ext.getBody(); /* * ================ Form 1 ======================= */ bd.createChild({tag: 'h2', html: 'Form 1 - deferredRender: true'}); var deferred = new Ext.FormPanel({ labelWidth: 75, border:true, width: 350, items: { xtype:'tabpanel', activeTab: 0, // when set to true, no data is loaded // when set to false, data is loaded but combos get stupid //deferredRender: false, defaults:{autoHeight:true, bodyStyle:'padding:10px'}, items:[{ title:'Personal Details', layout:'form', defaults: {width: 230}, defaultType: 'textfield', items: [{ fieldLabel: 'First Name', name: 'first', allowBlank:false },{ fieldLabel: 'Last Name', name: 'last' },{ fieldLabel: 'Company', name: 'company' }, { fieldLabel: 'Email', name: 'email' }] },{ title:'Phone Numbers', layout:'form', defaults: {width: 230}, defaultType: 'textfield', items: [{ fieldLabel: 'Home', name: 'home' },{ fieldLabel: 'Business', name: 'business' },{ fieldLabel: 'Mobile', name: 'mobile' },{ fieldLabel: 'Fax', name: 'fax' }, new Ext.form.ComboBox({ store: new Ext.data.SimpleStore({ fields: [ 'text', 'value' ], data: [ [ 'Home', 'h' ], [ 'Business', 'b' ], [ 'Mobile', 'm' ], [ 'Fax', 'f' ] ] }), fieldLabel: 'Type', displayField: 'text', valueField: 'value', hiddenName: 'phoneType', mode: 'local', triggerAction: 'all', editable: false, selectOnFocus: true, allowBlank: false, width: 230 })] }] }, buttons: [{ text: 'Save' },{ text: 'Cancel' }] }); deferred.render(document.body); bd.createChild({tag: 'br'}); bd.createChild({tag: 'br'}); /* * ================ Form 2 ======================= */ bd.createChild({tag: 'h2', html: 'Form 2 - deferredRender: false'}); var immediate = new Ext.FormPanel({ labelWidth: 75, border:true, width: 350, items: { xtype:'tabpanel', activeTab: 0, // when set to true, no data is loaded // when set to false, data is loaded but combos get stupid deferredRender: false, defaults:{autoHeight:true, bodyStyle:'padding:10px'}, items:[{ title:'Personal Details', layout:'form', defaults: {width: 230}, defaultType: 'textfield', items: [{ fieldLabel: 'First Name', name: 'first', allowBlank:false },{ fieldLabel: 'Last Name', name: 'last' },{ fieldLabel: 'Company', name: 'company' }, { fieldLabel: 'Email', name: 'email' }] },{ title:'Phone Numbers', layout:'form', defaults: {width: 230}, defaultType: 'textfield', items: [{ fieldLabel: 'Home', name: 'home' },{ fieldLabel: 'Business', name: 'business' },{ fieldLabel: 'Mobile', name: 'mobile' },{ fieldLabel: 'Fax', name: 'fax' }, new Ext.form.ComboBox({ store: new Ext.data.SimpleStore({ fields: [ 'text', 'value' ], data: [ [ 'Home', 'h' ], [ 'Business', 'b' ], [ 'Mobile', 'm' ], [ 'Fax', 'f' ] ] }), fieldLabel: 'Type', displayField: 'text', valueField: 'value', hiddenName: 'phoneType', mode: 'local', triggerAction: 'all', editable: false, selectOnFocus: true, allowBlank: false, width: 230 })] }] }, buttons: [{ text: 'Save' },{ text: 'Cancel' }] }); immediate.render(document.body); var PersonRecord = Ext.data.Record.create([ { name: 'first' }, { name: 'last' }, { name: 'company' }, { name: 'email' }, { name: 'home' }, { name: 'business' }, { name: 'mobile' }, { name: 'fax' }, { name: 'phoneType' } ]); var jack = new PersonRecord({ first: 'Jack', last: 'Slocum', company: 'Ext JS', home: '(888) 555-1212', mobile: '(888) 555-3434', phoneType: 'b' }); deferred.form.loadRecord(jack); immediate.form.loadRecord(jack); }); </script> </head> <body> <br /><br /> </body> </html>
-
4 Jan 2008 4:10 AM #7
Hello.
I found out, that adding "hideMode: 'offsets'" to all child panels resolves the problem. In my case, the working example would be:
Cheers,Code:Ext.onReady(function() { var win = new Ext.Window({ layout: 'fit', width: 620, height: 300, plain: true, items: { xtype: 'form', border: false, items: { xtype: 'tabpanel', plain: true, deferredRender: false, // layoutOnTabChange: true, activeTab: 0, autoHeight: true, items: [ { title: 'Tab 1', autoHeight: true, hideMode: 'offsets', /* NB! Needed with "deferredRender: false" */ items: [ { xtype: 'fieldset', title: 'Fieldset 1.1', style: 'margin: 10px; padding: 10px', autoHeight: true, html: 'This tab (activeTab) renders fine. There is a problem with the other tab(s), when <b>deferredRender</b> is set <b>false</b> on TabPanel. TriggerFields are longer than TextFields. Click the other tab...' }, ] }, { title: 'Tab 2', hideMode: 'offsets', /* NB! Needed with "deferredRender: false" */ items: [ { xtype: 'fieldset', title: 'Fieldset 2.1', style: 'margin: 10px; padding: 10px', autoHeight: true, items: [ { xtype: 'combo', fieldLabel: 'ComboBox 2.1.1', width: 150 }, { xtype: 'textfield', fieldLabel: 'Textfield 2.1.1', width: 150 }, { xtype: 'textfield', fieldLabel: 'TextField 2.1.2', width: 150 } ] }, ] } ] } } }); win.show(this); });
E.
-
4 Jan 2008 11:39 AM #8
Sencha Docs / Ext 3.x - ( Docs | Examples )
Learning Center / Saki's Examples (for 2.x) / HOWTO - ( Report Bugs | Post Proper Code )
-
7 Jan 2008 12:48 PM #9
I'm developing in Adobe AIR, and I'm having the same kind of rendering inconsistencies, and without hidden tabs or form panels... just straight element replacing. Using Ext 2.0 Final:
Produces the following (all on Mac OS 10.5.1):Code:<html> <head> <title>Sample</title> <link rel="stylesheet" type="text/css" href="resources/css/ext-all.css"></link> <script language="JavaScript" type="text/javascript" src="ext-base.js"></script> <script language="JavaScript" type="text/javascript" src="ext-all.js"></script> <script src="../includes/AirAliases.js"></script> <script type="text/javascript"> Ext.onReady(function(){ var sample = new Ext.form.ComboBox({ emptyText:'Select a state...', applyTo: 'sample' }); var sample2 = new Ext.form.ComboBox({ emptyText:'Select another state...', height:35, applyTo: 'sample2' }); }); </script> </head> <body> Sample: <input id="sample"><br/><input id="sample2"> </body> </html>
Firefox 2.0.0.11:

The baseline... results are as they should be.
Netscape 9.0 Beta 3:

Consistent with baseline.
Opera 9.22:

No highlight color.
Adobe AIR Beta 3:

Extra-thick highlight border, vertical field size too small for trigger.
Apple Safari 3.04:

Extra-thick glow, vertical field size too small for trigger.
-
11 Apr 2008 4:03 PM #10
Looks like AIR looks to Safari for its WebKit implementation on the Mac. Any overrides to Safari in CSS will affect AIR also. So to bring the height up on that trigger so that it lines up with the field:
Code:<style type="text/css"> .ext-safari .x-form-field-wrap .x-form-trigger{height:19px;} </style>


Reply With Quote