PDA

View Full Version : RadioGroup binding broken (and fixed)



voodude
7 Sep 2009, 8:51 PM
In 2.0.1, FormBinding does not work with RadioGroup. The fundamental problem is that RadioGroup's setValue()/getValue() works with values of type Radio, which of course is not going to work with a bound Model.

This RadioGroupBinding class (used instead of FieldBinding on the RadioGroup fields) fixes the problem:

package com.similarity.simi.gwt.client;

import com.extjs.gxt.ui.client.binding.FieldBinding;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.form.Radio;
import com.extjs.gxt.ui.client.widget.form.RadioGroup;

/**
* <p>FieldBinding is broken for RadioGroup fields. This fixes it.</p>
*
* <p>The bug is that RadioGroup's value is a Radio type, but all
* models will have a String type. This converts between the two.
* Really, RadioGroup's value should be a String type, associated
* with the valueAttribute property.</p>
*/
public class RadioGroupBinding extends FieldBinding
{
/** */
public RadioGroupBinding(RadioGroup group, String property)
{
super(group, property);
}

/** Auto-ish binding; model property name is assumed same as group name */
public RadioGroupBinding(RadioGroup group)
{
// This hoop is necessary because the RadioGroup doesn't set its Name property
this(group, group.get(0).getName());
}

/** Takes the radio and turns it into a string, easy */
@Override
protected Object onConvertFieldValue(Object value)
{
return ((Radio)value).getValueAttribute();
}

/** Takes the string and looks up the radio with the appropriate value attribute */
@Override
@SuppressWarnings("unchecked")
protected Object onConvertModelValue(Object value)
{
for (Field rad: ((RadioGroup)this.field).getAll())
if (((Radio)rad).getValueAttribute() == value)
return rad;

return null;
}
}

voodude
7 Sep 2009, 9:15 PM
Fixing my own bug... the comparison in onConvertModelValue() needs to be this:

if (((Radio)rad).getValueAttribute().equals(value))

rather than ==. Amusingly, == works in the GWT-compiled version but fails in the hosted mode.

Jeff

voodude
14 Sep 2009, 6:04 PM
By the way, my comment about fixing my own bug was fixing the code above - RadioGroup binding is still broken without that code.

Can this get moved into the Bug forum and tracked, fixed?

Jeff

sven
14 Sep 2009, 6:10 PM
It is not a bug in GXT, so this does not need to be moved to the bug forums

voodude
14 Sep 2009, 6:24 PM
How can "Binding doesn't work with RadioGroup fields" not be a bug?

Jeff

sven
14 Sep 2009, 6:29 PM
There is no RadioGroup binding included in GXT.

voodude
14 Sep 2009, 6:36 PM
Then the bug is "Documentation lacks any indication of what can and cannot be bound".

Jeff

Arno.Nyhm
17 Sep 2009, 1:22 AM
i see there are 2 more "special" bindings:

TimeFieldBinding
SimpleComboBoxFieldBinding

so i think it is no problem to add the RadioGroupBinding to the gxt package :-)

ksz
6 Nov 2009, 8:14 AM
voodude (http://www.extjs.com/forum/member.php?u=88324) - thanks for this useful code. I would suggest to replace two lines with:

return super.onConvertFieldValue(((Radio) value).getValueAttribute());

and:

return super.onConvertModelValue(rad);

You will not miss converters processing in this case.

WolfDogg
26 Jan 2010, 7:28 AM
Thank you so much for this, this one was really annoying. Be great if the GXT people could try to actually help or shed some direction rather than try to disregard such things. Radio's groups are common use in forms so why does 'Form' binding not work as the marketing suggests?

WolfDogg
27 Jan 2010, 4:37 AM
Yes voodude, better to have the call's to super in there. However in the method onConvertModelValue you want to call the super.onConvertFieldValue before any other code just in case you have a Converter assigned to the Binder. In my case I had a radio button group for YES/NO and my bean/model had a boolean property to map to this. I had to assign my own converter to this great RadioGroupBinding so the boolean-string conversion took place, and until I put this code at top of method my radio fields weren't being set from the underlying bean/model.


so the method ends up looking like this....

/** Takes the string and looks up the radio with the appropriate value attribute */
@Override
@SuppressWarnings("unchecked")
protected Object onConvertModelValue(Object value)
value = super.onConvertFieldValue;
{
for (Field rad: ((RadioGroup)this.field).getAll())
if (((Radio)rad).getValueAttribute() == value)
return rad;

return null;
}
}

Arno.Nyhm
29 Jan 2010, 3:52 AM
it would be nice if you also create a thread with the RadioGroupBinding in the category "Gxt: User Extensions and Plugins" so it is better found by new users.

tortexy
19 Feb 2010, 9:22 AM
Hey!

Is there any specific reason, this class is not in the plugins section?

This is a very useful class you have put together! So it deserves to be known and used! ;)

sraubal
24 Nov 2010, 11:33 PM
Hi,

thanks for this posting. To sum up the improvements added by WolfDogg and ksz (and correct the obvious copy & paste errors), here's the class as I think it should be:



/**
* <p>
* FieldBinding is broken for RadioGroup fields. This fixes it.
* </p>
* <p>
* The bug is that RadioGroup's value is a Radio type, but all models will have a String type. This converts between the
* two. Really, RadioGroup's value should be a String type, associated with the valueAttribute property.
* </p>
*/
public class RadioGroupBinding extends FieldBinding {

/**
* Main c'tor.
*
* @param group widget
* @param property binding path
*/
public RadioGroupBinding(RadioGroup group, String property) {
super(group, property);
}

/**
* Auto-ish binding; model property name is assumed same as group name.
*
* @param group widget
*/
public RadioGroupBinding(RadioGroup group) {
// This hoop is necessary because the RadioGroup doesn't set its Name property
this(group, group.get(0).getName());
}

/**
* {@inheritDoc}
*/
@Override
protected Object onConvertFieldValue(Object value) {
return super.onConvertFieldValue(((Radio) value).getValueAttribute());
}

/**
* {@inheritDoc}
*/
@Override
protected Object onConvertModelValue(Object value) {
value = super.onConvertModelValue(value);
for (Field< ? > rad : ((RadioGroup) this.field).getAll()) {
if (((Radio) rad).getValueAttribute().equals(value)) {
return rad;
}
}
return null;
}
}


Hope that helps save some time,

Stefan