PDA

View Full Version : [INFOREQ] [4.0.2a] Total fieldDefaults and defaults confusion!



mberrie
20 Jul 2011, 10:35 PM
While trying to pinpoint a possible bug related to the 'defaults' and 'fieldDefaults' config properties I found myself stepping from one WTF? into the next.

At the moment I am not sure what are bugs, errors in the documentation, and what just misunderstandings from my side.

So sorry if I skip the official bug report format. I assume that some of the problems below are already known (and maybe even fixed in >4.0.2a). If somebody can confirm my observations, I will happily (?) take the time to file complete bug reports, but TBH I already spent significant time to track the problems down and writeup this post.


What I found out so far:


Ext.form.FieldSet does not support 'fieldDefaults'

This took me quite some time to figure out since the FieldAncestor/fieldDefaults documentation mentions that this mixin is for Ext.container.Container and sub-classes thereof, and FieldSet is a sub-class of Container.
FieldSet, however, does not include the FieldAncestor mixin. The FieldSet docs correctly mention nothing of 'fieldDefaults'.
The truth is that I just expected FieldSet to support fieldDefaults because I always thought of it as a sub-form within a form that groups fields together, and it would just be very useful to apply defaults to its fields.



Docs for AbstractContainer#defaults are confusing and possibly wrong

Ext.container.AbstractContainer-cfg-defaults (http://docs.sencha.com/ext-js/4-0/index.html#/api/Ext.container.AbstractContainer-cfg-defaults)
The docs say
'If an added item is a config object, and not an instantiated Component, then the default properties are unconditionally applied.If the added item is an instantiated Component, then the default properties are applied conditionally so as not to override existing properties in the item.'

However, the example code showcases the complete opposite behavior (and is probably wrong IMHO)


defaults: { // defaults are applied to items, not the container
autoScroll:true
},
items: [
{
xtype: 'panel', // defaults do not have precedence over
id: 'panel1', // options in config objects, so the defaults
autoScroll: false // will not be applied here, panel1 will be autoScroll:false
},
new Ext.panel.Panel({ // defaults do have precedence over options
id: 'panel2', // options in components, so the defaults
autoScroll: false // will be applied here, panel2 will be autoScroll:true.
})
]
Furthermore, looking at the code in AbstractContainer#applyDefaults, the described behavior for items defined as xtype config appears to be different as well:



} else if (!config.isComponent) {
Ext.applyIf(config, defaults);
} else {
Ext.applyIf(config, defaults);
}
Note: Ext.applyIf does not check for 'hasOwnProperty', but object[property]. Obviously that code has been changed at one point, and the 'if(!config.isComponent)' statement is a left-over.



Default values applied in super-classes have precedence over default values in user code
for instantiated components

Since Ext.applyIf checks for object[property] it will include properties inherited from the prototype chain (super-classes). This basically means that instantiated components added to a container with a 'default' config will always inherit the values stated in the super-class (code), and not from the default config object that might be configured on the container.




Ext.onReady(function() {
var panel = Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
layout: 'anchor',
width: 600,
fieldDefaults: {
labelAlign: 'top',
labelSeparator: '> '
},
items: [
{
xtype: 'fieldset',
layout: 'anchor',
defaults: {
labelAlign: 'right',
labelSeparator: ':: '
},
items: [
// result>> align: 'right', labelSeparator: '::'
{
xtype: 'textfield',
fieldLabel: 'field1',
name: 'field1'
},
// result>> align: 'top', labelSeparator: '>'
Ext.widget('textfield', {
fieldLabel: 'field2',
name: 'field2'
})
]
}
]

});
});

Justin Noel
25 Aug 2011, 2:26 AM
+1


"Ext.form.FieldSet does not support 'fieldDefaults'"


I'm on 4.0.5 and still have this problem. If you configure fieldDefaults on the Panel, it is not passed down to items in fieldsets or field containers.

I'm having to manually configure each and every field.

mberrie
25 Aug 2011, 5:02 AM
Hm, that seems to be a different issue though.

I was talking about (re-)defining fieldDefaults on a FieldSet i.e. overriding any fieldDefaults that have been defined on the encapsulating form.Panel. This is not possible because FieldSet does not implement FieldAncestor.
I consider this more a non-feature than a bug.


What you describe, however, is that FieldSets kind of break the 'inheritance' chain of fieldDefaults. Looking at the code (4.0.2a), this should *not* happen and I would consider it a bug.

The code I posted in my OP actually considers this scenario. The 'field2' textfield inherits labelAlign and labelSeparator from the form.Panel while being nested inside a FieldSet. I just ran the example again and it works in 4.0.2a.

I wonder whether you have a different setup. I imagine it could make a difference whether you use xtype literals or instantiated components, and whether you pass items as part of the config object or add them later on.

Here is the stripped down test-case. Does this work for you in 4.0.5?



var panel = Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
layout: 'anchor',
width: 600,
fieldDefaults: {
labelAlign: 'top',
labelSeparator: '> '
},
items: [
{
xtype: 'fieldset',
layout: 'anchor',
items: [
// align: 'top', labelSeparator: '>'
Ext.widget('textfield', {
fieldLabel: 'field2',
name: 'field2'
})
]
}
]
});