Form: Select elements and default values

Hi,

I use a
Form
with
Select
components and I have some difficulties with default values.

This is my example project:
My Form is binded to a POJO (with two
Integer
values in this case). I build a
ChoiceBox
and an
OptionGroup
. Here’s the FieldFactory:

   private class TestFieldFactory extends DefaultFieldFactory {
      public TestFieldFactory() {}

      @Override
      public Field createField(Item item, Object propertyId, Component uiContext) {
         IndexedContainer ic = new IndexedContainer();
         ic.addContainerProperty("value", String.class, null);

         if ("test1".equals(propertyId)) {
            ComboBox cb = new ComboBox("Test1");
            cb.setRequired(true);
            cb.setRequiredError("Please select a test1 value");

            item = ic.addItem(100);
            item.getItemProperty("value").setValue("One hundred");
            item = ic.addItem(200);
            item.getItemProperty("value").setValue("Two hundred");

            cb.setContainerDataSource(ic);
            cb.setItemCaptionPropertyId("value");

            cb.setNullSelectionItemId(100);
            cb.select(100);

            return cb;
         }
         if ("test2".equals(propertyId)) {
            OptionGroup og = new OptionGroup("Test2");
            og.setMultiSelect(false);

            item = ic.addItem(0);
            item.getItemProperty("value").setValue("NO");
            item = ic.addItem(1);
            item.getItemProperty("value").setValue("YES");

            og.setContainerDataSource(ic);
            og.setItemCaptionPropertyId("value");

            og.setNullSelectionItemId(1);
            og.select(1);
            return og;
         }
         return null;
      }
   }

Furthermore I insert a
Commit
button which calls (surprise)
Form.commit()
. I use these commit options:

testForm.setWriteThrough(false);
testForm.setInvalidCommitted(false);

After restart both elements display the intended values. But there a some strange effects:

  • Beside the ComboBox there is the exclamation point icon (“Please select a test1 value”)
  • If I execute
    commit()
    without any changes the RequiredError message is shown (“Please select a test1 value”)…
  • …and the default values are not stored within the POJO

I would like to know how I can assign default values properly. If I do not change anything and press the Commit button, the default values should be stored to the POJO (without any errors).

Any ideas what went wrong? Thanks for your help, Thorsten

••••••••••
Eclipse 3.5.1 • Vaadin 6.2.2 • Vaadin Eclipse Integration 1.2.0 • Java 1.5
Windows 2000 • IE7 • Tomcat 6.0

Hi,

I just want to simplify my question.

The main issue is that (as far as I see) in a POJO binded
form
(with select elements) the
commit()
method does not save previously assigned default values.

I break it down to this example:

public class SimpleformtestApplication extends Application {
   TestPojo testPojo;

   @Override
   public void init() {
      Window mainWindow = new Window("Simpleformtest Application");
      setMainWindow(mainWindow);

      testPojo = new TestPojo();
      BeanItem<TestPojo> testPojoItem = new BeanItem<TestPojo>(testPojo);

      // Create the Form
      final Form testForm = new Form();
      testForm.setCaption("Test");
      testForm.setWriteThrough(false);
      testForm.setInvalidCommitted(false);

      testForm.setFormFieldFactory(new TestFieldFactory());
      testForm.setItemDataSource(testPojoItem);

      testForm.setVisibleItemProperties(Arrays.asList(new String[] { "number" }));

      mainWindow.addComponent(testForm);

      HorizontalLayout buttons = new HorizontalLayout();
      buttons.setSpacing(true);

      Button apply = new Button("Commit", new Button.ClickListener() {
         public void buttonClick(ClickEvent event) {
            try {
               testForm.commit();
            } catch (Exception e) {
               // Ingnored, we'll let the Form handle the errors
            }
         }
      });
      buttons.addComponent(apply);
      testForm.getLayout().addComponent(buttons);

      // button for showing the internal state of the POJO
      Button showPojoState = new Button("showPojoState", new Button.ClickListener() {
         public void buttonClick(ClickEvent event) {
            System.out.println("Pojo 'Number': " + testPojo.getNumber());
         }
      });
      mainWindow.addComponent(showPojoState);
   }

   private class TestFieldFactory extends DefaultFieldFactory {
      public TestFieldFactory() {}

      @Override
      public Field createField(Item item, Object propertyId, Component uiContext) {
         IndexedContainer ic = new IndexedContainer();
         ic.addContainerProperty("value", String.class, null);

         if ("number".equals(propertyId)) {
            ComboBox cb = new ComboBox("Number");
           
            item = ic.addItem(100);
            item.getItemProperty("value").setValue("One hundred");
            item = ic.addItem(200);
            item.getItemProperty("value").setValue("Two hundred");

            cb.setContainerDataSource(ic);
            cb.setItemCaptionPropertyId("value");

            cb.setNullSelectionItemId(200);
            cb.select(200);

            return cb;
         }
         return null;
      }
   }

   public class TestPojo {
      private Integer number;
      public Integer getNumber() {return number;}
      public void setNumber(Integer number) {this.number = number;}
   }
}
  1. When I start this application, the ComboBox displays “Two hundred” (great)
  2. Next I press “Commit” and then “showPojoState” → the output is
    Pojo ‘Number’: null
    (not so great)
  3. Then I change ComboBox to “One hundred”, press “Commit”, “showPojoState” → output is
    Pojo ‘Number’: 100

In my opinion the application should save the value 200 after the first commit. Is there a way to do this?

Thanks, Thorsten

••••••••••
Eclipse 3.5.1 • Vaadin 6.2.5 • Vaadin Eclipse Integration 1.2.0 • Java 1.5
Windows 2000 • IE7 • Tomcat 6.0

Actually, the problem is that you bind the item id 200 to the value null. Hence when you commit the selection 200, the data source is set to the value null. To achieve what (I assume) you want, try these changes:

testPojo = new TestPojo();
BeanItem<TestPojo> testPojoItem = new BeanItem<TestPojo>(testPojo);
testPojoItem.getItemProperty("number").setValue(200);
if ("number".equals(propertyId)) {
ComboBox cb = new ComboBox("Number");

item = ic.addItem(100);
item.getItemProperty("value").setValue("One hundred");
item = ic.addItem(200);
item.getItemProperty("value").setValue("Two hundred");
cb.setContainerDataSource(ic);
cb.setItemCaptionPropertyId("value");

cb.setNullSelectionAllowed(false);

return cb;

So instead of setting the value of the field (which is overwritten anyway) try setting the value directly to the data source. The field picks it up from there.

That was the point! It works now and your hint also helps me with the other issues from my initial posting…

Thanks! :slight_smile: