PDA

View Full Version : [OPEN-977]CompositeField steals label of previous checkbox when not inside FormLayout



renku
18 May 2010, 2:15 AM
When Checkbox or Radio precedes CompositeField on a panel that doesn't have FormLayout, then CompositeField will still look up a preceding <label> and make its "for" attribute point to the ID of its first subfield.

Here's a simple testcase:


Ext.onReady(function(){

new Ext.Panel({
renderTo: document.body,
frame: true,
items: [
{
xtype: "checkbox",
boxLabel: "click me"
},
{
xtype: "compositefield",
items: [
{xtype: "textfield"},
{xtype: "textfield"}
]
}
]
});

});

Tested with Ext 3.2.1. Also looked at the code in Subversion, and the bug seems to be there too.

A possible fix is to only do the "for"-attribute-rewriting when CompositeField has fieldLabel defined:


Ext.override(Ext.form.CompositeField, {
buildLabel: function(segments) {
// -- start fix --
segments = Ext.clean(segments);
return segments.length ? segments.join(", ") : undefined;
// -- end fix --
},
onRender: function(ct, position) {
if (!this.el) {
/**
* @property innerCt
* @type Ext.Container
* A container configured with hbox layout which is responsible for laying out the subfields
*/
var innerCt = this.innerCt = new Ext.Container({
layout : 'hbox',
renderTo: ct,
items : this.items,
cls : 'x-form-composite',
defaultMargins: '0 3 0 0'
});

this.el = innerCt.getEl();

var fields = innerCt.findBy(function(c) {
return c.isFormField;
}, this);

/**
* @property items
* @type Ext.util.MixedCollection
* Internal collection of all of the subfields in this Composite
*/
this.items = new Ext.util.MixedCollection();
this.items.addAll(fields);

//if we're combining subfield errors into a single message, override the markInvalid and clearInvalid
//methods of each subfield and show them at the Composite level instead
if (this.combineErrors) {
this.eachItem(function(field) {
Ext.apply(field, {
markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0),
clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0)
});
});
}

// -- start fix --
// When label exists set the label 'for' to the first item
if (this.fieldLabel) {
var l = this.el.parent().parent().child('label', true);
if (l) {
l.setAttribute('for', this.items.items[0].id);
}
}
// -- end fix --
}

Ext.form.CompositeField.superclass.onRender.apply(this, arguments);
}
});

Another possibility would be to detect if CompositeField is used inside FormLayout or not.