PDA

View Full Version : Fieldset with radio toggle component?



Max_nl
5 Feb 2010, 8:38 PM
The standard Fieldset component has a checkboxToggle option.
I was wondering if there is a user component or other easy method to get a radio button instead.

I have a form with several fieldsets, of which the user only needs to fill in the one that he choices.
Upon selection the others should be collapsed/disabled.

tobiu
6 Feb 2010, 1:48 AM
Hi Max_nl,

i don't think this is implemented in ext yet.

i simulated the behavior of radios with checkboxes. example: one fieldset to add a new customer, another one to edit an existing one. the second fieldset gets:



,listeners:{
collapse: function(e){
bT.disableFieldsetElements(fieldsets.selectCustomerFieldset);
bT.enableFieldsetElements(fieldsets.addCustomerFieldset);
fieldsets.addCustomerFieldset.expand(false);
},
expand: function(e){
bT.disableFieldsetElements(fieldsets.addCustomerFieldset);
bT.enableFieldsetElements(fieldsets.selectCustomerFieldset);
fieldsets.addCustomerFieldset.collapse(false);
}
}


the important thing is, that a collapsed fieldset gets submitted by default! so, if there are allowBlank = false - fields inside, they will get marked invalid. to prevent this:



bT.disableFieldsetElements = function (fieldset) {
for(var i=0; i < fieldset.items.getCount(); i++) {
fieldset.items.get(i).disable();
}
};


bT.enableFieldsetElements = function (fieldset) {
for(var i=0; i < fieldset.items.getCount(); i++) {
fieldset.items.get(i).enable();
}
};


(fieldset.items.each() would also do).

kind regards,
tobiu

Max_nl
6 Feb 2010, 8:33 AM
Thanks for the reply.
I would really like a radio instead of a checkbox though.


I'm not sure if this is the right approach to glue two components together, but today I experimented a bit with grouping a radio and fieldset with a panel.
This is the code of the component I have so far:



Ext.ns('Max');
Max.RadioFieldset = Ext.extend(Ext.Panel, {

/**
* @cfg {Boolean} checked
* True if the radiobutton is checked by default
*/
checked: false,

/**
* @cfg {String} name
* Name of the radio button group
*/
name: '',

/**
* @cfg {String} value
* Value of the radio button
*/
value: '',

/**
* @cfg {String} boxLabel
* Label of the radio button
*/
boxLabel: '',

/**
* @cfg {Boolean} fieldsetBorder
* Whether the fieldset should have a border
*/
border: false,

/**
* @cfg {Boolean} collapsibleFieldset
* Whether to collapse/expand the fielset upon checking the radio button
* If false the fields will only be disabled (greyed out)
*/
collapsibleFieldset: false,

/**
* @cfg {String} defaultType
* Default type of items
*/
defaultType: 'textfield',

/**
* @cfg {String} defaults
* Defaults for items
*/
defaults: {anchor: '-20'},

initComponent: function()
{
this.radio = new Ext.form.Radio({
name: this.name,
value: this.value,
checked: this.checked,
boxLabel: this.boxLabel,
hideLabel: true,
listeners:
{
check: function(box,checked)
{
if (checked)
{
this.fieldset.items.each(function(item,idx,total)
{
item.enable();
});

if (this.collapsibleFieldset)
{
this.fieldset.expand(false);
}
}
else
{
this.fieldset.items.each(function(item,idx,total)
{
item.disable();
});

if (this.collapsibleFieldset)
{
this.fieldset.collapse(false);
}
}
}, scope: this
}
});
this.fieldset = new Ext.form.FieldSet({
xtype: 'fieldset',
border: this.border,
collapsed: this.collapsibleFieldset && !this.checked,
hideLabel: true,
items: this.items,
defaults: this.defaults,
defaultType: this.defaultType
});

var cfg = {
items:
[
this.radio,
this.fieldset
],
border: false
};

Ext.apply(this, Ext.apply(this.initialConfig, cfg));
Max.RadioFieldset.superclass.initComponent.call(this);

if (!this.checked)
{
this.fieldset.items.each(function(item,idx,total)
{
item.disable();
});
}
}
});
Ext.reg('radiofieldset', Max.RadioFieldset);
It seems to work, but I'm not entirely happy with the layout:

http://bayimg.com/image/gakceaace.jpg

What would be the best way to reduce the space between the 3 fieldsets, and move them a bit to the right?
Create a custom css for the fieldset? For the panel? Some layout manager/margins setting?

tobiu
6 Feb 2010, 11:08 AM
the code looks clean, but i would extend / override Ext.form.fieldset:



onRender : function(ct, position){
if(!this.el){
this.el = document.createElement('fieldset');
this.el.id = this.id;
if (this.title || this.header || this.checkboxToggle) {
this.el.appendChild(document.createElement('legend')).className = 'x-fieldset-header';
}
}

Ext.form.FieldSet.superclass.onRender.call(this, ct, position);

if(this.checkboxToggle){
var o = typeof this.checkboxToggle == 'object' ?
this.checkboxToggle :
{tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
this.checkbox = this.header.insertFirst(o);
this.checkbox.dom.checked = !this.collapsed;
this.mon(this.checkbox, 'click', this.onCheckClick, this);
}
}


you could override the onRender method and replace the checkbox with a radio (or making both optional and then apply your wanted behaviour.

the positioning is a style issue: you could give the panel a padding left for example, or each fieldset a marginLeft and marginBottom (or top).

fieldsets have a config "bodyStyle", where you could set that.

kind regards,
tobiu

Max_nl
9 Feb 2010, 8:59 AM
Thanks for the reply.


the code looks clean, but i would extend / override Ext.form.fieldset:

I'm a bit hesitant to override onRender, as I'm afraid that might break things if I upgrade to another Ext.js release later, that has different original code in onRender.




the positioning is a style issue: you could give the panel a padding left for example, or each fieldset a marginLeft and marginBottom (or top).

fieldsets have a config "bodyStyle", where you could set that.


Managed to get rid of the extra space at the bottom, by adding "style: 'margin-bottom:0px;' " to the fieldset.

shinkenno
18 Jun 2010, 1:23 AM
Hi,

I am very interested by this 'radiofieldset'.
Can you please provide an example of usage for this class ?

Best regards,
Arnaud