Loading...
Important Notice - Forums is archived

To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Product icon
TUTORIAL

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.

Form and Bean with Collection Property doesn't work out of the box

Andreas Höhmann
10 years ago Mar 06, 2012 6:34am

hi folks,

I found out that Form API works with a workaround for Beans with Collection properties ...

I must fill the UI element (i.e. a Table) for the Collection property with the content of that property?! All other "simple field" filled automatically by the form :)

See com.vaadin.ui.Form.setItemDataSource(Item, Collection<?>) line 770 ...

I marked the problem in the code below:

public class FormTestApplication extends Application {

  public static class Contact {
    String name;
    public Contact(final String name) {
      this.name = name;
    }
    public String getName() {
      return name;
    }
    public void setName(final String name) {
      this.name = name;
    }
  }

  public static class Person {
    String name;
    Collection<Contact> contacts = new ArrayList();
    public Person(final String name, final Collection<Contact> contacts) {
      this.name = name;
      this.contacts = contacts;
    }
    public Collection<Contact> getContacts() {
      return contacts;
    }
    public String getName() {
      return name;
    }
    public void setContacts(final Collection<Contact> contacts) {
      this.contacts = contacts;
    } 
    public void setName(final String name) {
      this.name = name;
    }
  }

  @Override
  public void init() {
    final Window mainWindow = new Window("Vaadin_faq Application");
    final Label label = new Label("Hello Vaadin user");
    mainWindow.addComponent(label);
    setMainWindow(mainWindow);
    final Form form = new Form(new VerticalLayout(), new DefaultFieldFactory() {
      @Override
      public Field createField(final Item item, final Object propertyId, final Component uiContext) {
        if ("contacts".equals(propertyId)) {
          final Table table = new Table();
          table.setSizeFull();
          // XXX here I must fill the table with the content --- but why? all other "simple field" filled automatically by the form
         table.setContainerDataSource(new BeanItemContainer<Contact>(Contact.class,(Collection<? extends Contact>) item.getItemProperty(propertyId).getValue()));
          // What I expect is something like this:
          // table.setPropertyDataSource(item.getItemProperty(propertyId));
          // but if I debug the application I see that com.vaadin.ui.Form.bindPropertyToField(Object, Property, Field)
          // is this a bug?
          return table;
        } else {
          return super.createField(item, propertyId, uiContext);
        }
      }
    });
    final Person p = new Person("Hans Karl", Arrays.asList(new Contact[]{
        new Contact("Musterstrasse 3"),
        new Contact("Sonstwo 123")
    }));
    form.setItemDataSource(new BeanItem<Person>(p));
    mainWindow.addComponent(form);
  }
}

Kind regards
Andreas

Last updated on Mar, 6th 2012
Marko Grönroos
10 years ago Mar 06, 2012 12:14pm
Marko Grönroos
10 years ago Mar 06, 2012 12:28pm

Hmm, I just remembered that here's an example of such form. Notice that the value of a Table is its selection, not its contents, while the Form expects a value of the collection type. So it's not just as simple as filling the table .

The example also handles read-only mode properly (click the button to see the form in read-only mode).

Last updated on Mar, 6th 2012