Radio buttons (OptionGroup) in a Form

Is there a way to assign the value distinct from the displayed option using an OptionGroup since I don’t see any other RadioButton type class? I’d like to use this in a Form with BeanItems.

That is, I have a getStatus/setStatus method in my bean, that returns “E” or “D”, but I’d like the displayed radio button labels to be “Enabled” or “Disabled”. Then when I do a commit() on the Form, it will then call setStatus() with the correct “E”/“D” string rather than the word labels “Enabled” or “Disabled” (which in fact come from PropertyBundle and are not tied to my bean otherwise).

We do the same when they have a choice between a few U.S. states where we’d like the bean values to be state codes like NY, WA, CA with labels showing “New York”, “Washington” and “California”.

Is this possible, or do I need to keep track of the mapping in my code and not actually use BeanItems that will try to get/set these values?

Quick help: see if
Select.setItemCaptionPropertyId(Object)
is the thing you need.

Is there a nice example of this somewhere. I must be missing something still since I tried and my radio buttons have no captions next to them (just two radio buttons without labels). Here’s what I tried:

First, I built a simple class to hold the value (like “E”) and the caption (like “Enabled”):

    public class SelectItemCaption {
    	private String value;
    	private String caption;
    	public SelectItemCaption( String value, String caption ) {
    		this.value = value;
    		this.caption = caption == null ? value : caption;
    	}
    	public String getValue() { 
    		return value; 
    	}
    	public String getCaption() { 
    		return caption; 
    	}
    	public String toString() { 
    		return value; 
    	}
    }

Then in my Form’s ‘createField’ method I do (the “string” versions are correct and were loaded from a properties file):

    	setFormFieldFactory( new DefaultFieldFactory() {
                        @Override
			public Field createField(Item item, Object propertyId, Component uiContext) {
				// Status will be an option group (radio buttons and not a text field)
				if ( propertyId.equals("status") ) {
					
					SelectItemCaption eSelect = new SelectItemCaption( Literals.STATUS_ENABLED, statusEnableString );
					SelectItemCaption dSelect = new SelectItemCaption( Literals.STATUS_DISABLED, statusDisableString );
					
					ArrayList<SelectItemCaption> values = new ArrayList<SelectItemCaption>();
					values.add(eSelect);
					values.add(dSelect);
					OptionGroup og = new OptionGroup(null,values);
					og.setItemCaptionPropertyId("caption");
					return og;
				}
....

I had hoped that “caption” meant that it would call SelectItemCaption.getCaption(), but that’s not being called.
It does appear that when I save/commit the Form it calls my SelectItemCaption.toString() which returns “E” or “D” which is then set in my BeanItem correctly, so it’s using the right value to set my bean, but I have no captions displayed.

And when the original ‘status’ property is “E” it’s not selecting that radio button when I go into edit mode on the bean. Do I need to call OptionGroup.setValue() to set an initial value from my bean? I tried this, but it made no difference (no radio button was selected) (and the get property called returns “E”):

og.setValue(item.getItemProperty(propertyId));

Clearly I’m not setting this up correctly or my SelectItemCaption class is not needed or is otherwise incorrect.

Well, I never did figure out how to use setItemCaptionPropertyId(Object), but I would be curious to understand how that works since I will no doubt need to use it one day.

Here’s how I resolved it through various trial and error:

ArrayList<String> values = new ArrayList<String>(2);
values.add("E");
values.add("D");				
statusOptionGroup = new OptionGroup("Status",values);
statusOptionGroup.setItemCaption("E", "Enabled");
statusOptionGroup.setItemCaption("D", "Disabled");

The two setItemCaption() calls seem to make the mapping between the value (code we use in our object and store in the database) and the user visible string (caption).

While I am able to cache this option group, it seems like a lot of code to do the mapping, which will get uglier when I map the 50+ states/territories in the US (though all data driven the mapping). Is this where the setItemCaptionPropertyId() technique might be cleaner?

Someone more familiar with the data API’s could be kind enough to explain it in detail. I just know it’s there, but if I try to explain it, I’m pretty sure I’ll just confuse you more :slight_smile:

Isn’t there anything about this method in the Book of Vaadin?

The Book has some info, but I think only people who understand Vaadin intimately can make sense of it.

None of the examples for the various select boxes or radio buttons shows distinct values and options, which are pretty common in HTML widgets themselves:

<input type="radio" name="status" value="E" /> Enabled
<input type="radio" name="status" value="D" /> Disabled

and

<select name="status">
  <option value="E">Enabled</option>
  <option value="D">Disabled</option>
</select>

I’m sure as you get up to speed, Vaadin makes more sense, but all those Object parameters make it really hard to know what you’re dealing with until you get into a debugger. Flexibility has its price in complexity for newbies. But overall, I’m still finding Vaadin to be a great toolkit. And while documentation can always be better with more examples of the myriad scenarios programmers run into, Vaadin has some of the most complete ones I’ve seen.

From The Book:

I know this could be easier for me somehow, perhaps, since I do display the Enabled/Disabled text in a column of the Table that drives my Form. But my impression is it makes more sense for a select box or option group that has a list that perhaps contains the same number of elements as there are rows in the Table (Item). So maybe it doesn’t fit for my simpler radio button which are just two values used to specify a single column of the table without regard to the number of rows (it’s the same two values whether I have zero rows or 1000 rows in the table).

It’s all just part of the learning curve…thanks for all your help and patience.

If I’m reading this right, the problem is that you use the Collection constructor. It seems that it uses the given objects as item ids for the new items, but doesn’t give them any properties. My guess is that you wanted to use the bean class SelectItemCaption as the basis for the items, not just as the item id.

You could try using a BeanItemContainer with the OptionGroup. The BeanItemContainer inspects the used bean class and sets the bean properties as …err… properties of the items.

To sum it up: when using the collections constructor the given beans are used as item id’s and nothing more, since an IndexedContainer is used in the background. When using a BeanItemContainer, the beans act as item id’s AND the source for properties.

Confusing enough? :slight_smile:

Guys,
you look like you could help me :slight_smile:

Can you take al look at this post:
How to create option group
?

Thanks

I`ve found an elegant solution.
First of all:
when creating OptionGroup, use the next constructor public OptionGroup(String caption, Container container)
It could be as next:


IndexedContainer container = new IndexedContainer();
container.addContainerProperty("displayName", String.class, null);        
for (YourBean bean : beans) {
    String name = bean.getDisplayName();
    String id = bean.getId();            
    Item item = container.addItem(id);
    item.getItemProperty("displayName").setValue(name);                        
}
container.sort(new Object[] { "displayName" }, new boolean[]
 { true });

And when initializing optionGroup, use next instructions:

optionGroup.setItemCaptionMode(OptionGroup.ITEM_CAPTION_MODE_PROPERTY);
optionGroup.setItemCaptionPropertyId("displayName");

And at the end we got what we need:
displayed names are business friendly, when select any of them we get the technical id of the element.

Hello David, thank you for this example, where is clearly explained how to set up captions for items in Option Group which are diferent from values. :slight_smile:

the simplest way is

ogFriOption = new OptionGroup(“Select Option”);
ogFriOption.addItem(“One”);
ogFriOption.addItem(“Two”);
ogFriOption.setValue(“Two”);

addcomponent(ogFriOption );