How to save an other container property with a combobox in a form

Hello all,

I created a form with a comboBox to choose a parent of Tom (a Person). The container of the comboBox has two properties “firstName” and “lastName”, I set the item caption property to “firstname”. But when I commit i want to save the property “lastName”. For example when i choose “Claude” with the comboBox and I commit, the parent of Tom has to be “Martin” but, at the moment, it is “Claude”.

I thank you a lot for your help.

I join here my code:

package ch.rodano.studies.components;

import java.util.Arrays;

import ch.rodano.studies.Person;

import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

public class FormComboBoxSave extends VerticalLayout {

	private BeanItem<Person> item;

	private Form form;

	public FormComboBoxSave(Person person) {
		super();

		item = new BeanItem<Person>(person);

		form = new Form();
		
		form.setCaption("Person details");
		form.setWriteThrough(false);
		form.setFormFieldFactory(new PersonFieldFactory());
		form.setVisibleItemProperties(Arrays.asList(new String[] {"firstName","lastName","parentName"}));
		form.setItemDataSource(item);
		
		
		addComponent(form);
		
		Button buttonSave = new Button("Save", new ClickListener() {
			
			public void buttonClick(ClickEvent event) {
				save();
			}
		});
		addComponent(buttonSave);
	}

	public void save() {
			
			try {
				form.commit();
			} catch (Exception e) {
				e.printStackTrace();
			}
	}
	}



 class PersonFieldFactory extends DefaultFieldFactory {
	 
	public ComboBox parentBox = new ComboBox("parent");
	 
	public PersonFieldFactory(){
		super();
		 
		 IndexedContainer container = new IndexedContainer();
		 
		 container.addContainerProperty("firstName", String.class, null);
		 container.addContainerProperty("lastName", String.class, null);
		 
		 parentBox.setContainerDataSource(container);
		 parentBox.setInvalidAllowed(false);
		 parentBox.setNullSelectionAllowed(false);
		 parentBox.setNewItemsAllowed(false);
		 parentBox.setItemCaptionPropertyId("firstName");

				Item item = container.addItem("Claude");
				item.getItemProperty("firstName").setValue("Claude");
				item.getItemProperty("lastName").setValue("Martin");
				
				item = container.addItem("François");
				item.getItemProperty("firstName").setValue("François");
				item.getItemProperty("lastName").setValue("Doucan");

	 }

	private static final String COMMON_FIELD_WIDTH = "12em";

	@Override
	public Field createField(Item item, Object propertyId, Component uiContext) {
		System.out.println(propertyId);
		Field f = super.createField(item, propertyId, uiContext);
	    if ("firstName".equals(propertyId)) {
			TextField tf = (TextField) f;
			tf.setWidth(COMMON_FIELD_WIDTH);
			System.out.println("Test");
		} else if ("lastName".equals(propertyId)) {
			TextField tf = (TextField) f;
			tf.setWidth(COMMON_FIELD_WIDTH);
		} else if ("parentName".equals(propertyId)) {
			System.out.println("parent");
			return parentBox;
		} 
		return f;
	}
 }

The application is here.

public class myApplication extends Application{
@Override
	public void init() {
		
		final Person person = new Person();
		person.setFirstName("Tom");
		person.setLastName("Foo");
		
		_window = new Window("test");
		setMainWindow(_window);
		FormComboBoxSave combo = new FormComboBoxSave(person);
		combo.setSizeFull();
		_window.setContent(combo);
		combo.addComponent(new Button("Show parent", new ClickListener() {
			public void buttonClick(ClickEvent event) {
				_window.showNotification("Parent:" + person.getParentName());
			}
		}));
}

The value of the field is the item identifier you gave when adding the item, e.g. “Claude” in container.addItem(“Claude”). As you are already setting the item caption property ID to control what is shown, why not simply give the last name (or something else to use as the value) as the item identifier?

Note that IndexedContainer lets you give the item id explicitly (or have one automatically generated if you don’t give any), whereas it could be obtained or generated differently for different types of containers.

Thank you very much for your answer. It is a very simple solution, I did not know that the value of the field is the item identifier.

Thanks