Form in a window with Vaadin 7.0.5

Hi, I’m migrating an application to Vaadin 7 and got stuck with some basic layout and validation issues.

What I’m trying to achieve:
a) UI component in a modal window
b) fields:

  • title: text field that is about as wide as the modal window
  • text area: shown below the title and also as wide as the window. Vertically this should use all extra space that there is available
  • other fields: about ten smaller fields (organized in e.g. four columns an tree rows below the text area)
    c) Use existing Vaadin functionality like mandatory field marker, error marker, error tooltip etc.
    d) Use validators like RegexpValidator
    e) Use the framework as it is intended to be used

Maybe I don’t quite understand the roles of different Layouts and the FieldGroup (not using Form anymore as it’s deprecated). Therefore I would appreciate any help guiding me to the right direction so that I’m not trying to do something that is not supposed to be done.

BTW: The use case is such that the user cliks an item in a table to edit it. Typically the table and the “editor” wouldn’t fit on the screen together so I open a window on top of the table.

Below are tree simple classes demonstrating the issues that I have. There are tree different cases described in the comments in the code.

Best Regards,

Olli-Pekka

Here’s the UI


import com.vaadin.annotations.Theme;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.UI;
import com.vaadin.ui.Window;


@SuppressWarnings("serial")
@Theme("myapp")
public class MyappUI extends UI {

    @Override
    protected void init(VaadinRequest request) {
    	
		Window myWindow = new Window();
		myWindow.setCaption("MyWindow");
		myWindow.setWidth("80%");
		myWindow.setHeight("100%");
		
		/* Test1: Wrap the grid in the component in FormLayout
		   ---> Validation error Tooltips work nicely in Eclipse ide 
		        and Safari 5.1.9
		        but the Text grid "collapses" in Firefox 20.0
		        (the Text field becomes only a few pixels high)
		*/
		MyFormComponent myFormComponent = new MyFormComponent(true);
		myWindow.setModal(true);
		
		
		/* Test2: Wrap the grid in the component in VerticalLayout
		   ---> Validation error tooltips don't show when
		        hovering ower caption or error indicator. They also stay
		        visible when mouse is moved away from the field.
		        The layout is OK also in Firefox. 
		*/
		//MyFormComponent myFormComponent = new MyFormComponent(false);
		//myWindow.setModal(true);
        
		
		/* Test3: Don't use modal window. Wrap grid in VerticalLayout
		   ---> Layout OK and tooltips OK.
		        But in my real application:
		        a) There is also something else that causes the same
		           effect as modal in this example.
		        b) The application would need big changes to use non-modal window.
		*/
		//MyFormComponent myFormComponent = new MyFormComponent(false);
		
		// common code for all test cases:
		myWindow.setContent(myFormComponent);
		myWindow.getContent().setSizeFull();
		UI.getCurrent().addWindow(myWindow);
    }

}

And then the component for the window


import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.validator.StringLengthValidator;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Button.ClickEvent;

public class MyFormComponent extends CustomComponent implements ClickListener {
	//private FormLayout formLayout = new FormLayout();
    private GridLayout gridLayout = new GridLayout(3, 4);;
    private FieldGroup fieldGroup = null;
    TextField titleField = new TextField("Title");
    TextArea textField = new TextArea("Text");
    TextField misc1Field = new TextField("Misc 1");
    TextField misc2Field = new TextField("Misc 2");
    Button applyButton; 
    
   public MyFormComponent(boolean useFormLayout) {
		// create the fields
	    titleField.setNullRepresentation("");
    	titleField.setRequired(true);
    	titleField.setWidth("100%");
    	titleField.setRequiredError("Required title is missing");
    	textField.setNullRepresentation("");
    	textField.setSizeFull();
    	misc1Field.setNullRepresentation("");
    	misc1Field.addValidator(new StringLengthValidator("2-5 characters required", 2, 5, false));
    	misc2Field.setNullRepresentation("");
    	misc2Field.setNullSettingAllowed(true);
		
    	// make a field group
    	MyBean myBean = new MyBean();
    	BeanItem<MyBean> myItem = new BeanItem<MyBean>(myBean);
		fieldGroup = new FieldGroup(myItem);
		fieldGroup.bind(titleField,"title");
		fieldGroup.bind(textField, "text");
		fieldGroup.bind(misc1Field, "misc1");
		fieldGroup.bind(misc2Field, "misc2");
	    
	    // set up a grid with fields and a button 
        gridLayout.setSizeFull();
        gridLayout.setColumnExpandRatio(2, 1);
        gridLayout.setRowExpandRatio(1, 1);
        gridLayout.setSpacing(true);
        gridLayout.addComponent(titleField, 0, 0, 2, 0);
        gridLayout.addComponent(textField, 0, 1, 2, 1);
        gridLayout.addComponent(misc1Field, 0, 2);
        gridLayout.addComponent(misc2Field, 1, 2);
        applyButton = new Button("Apply",this);
        gridLayout.addComponent(applyButton,2,2);
        
        if (useFormLayout) {
        	FormLayout formLayout = new FormLayout();
	        formLayout.setMargin(true);
	        formLayout.setSizeFull();
	        formLayout.addComponent(gridLayout);
	        setCompositionRoot(formLayout);
        } else {
        	VerticalLayout vLayout = new VerticalLayout();
	        vLayout.setMargin(true);
	        vLayout.setSizeFull();
	        vLayout.addComponent(gridLayout);
	        setCompositionRoot(vLayout);
        }
	    
	}
    @Override
	public void buttonClick(ClickEvent event) {
		try {
			fieldGroup.commit();
			System.out.println("Committed");
		} catch (Exception e) {
			System.out.println(e.getClass() + " in commit: " + e.getMessage() );
		}
	}
}

And the simple bean


public class MyBean {
	private String title = null;
	private String text = null;
	private String misc1 = null;
	private String misc2 = null;
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getText() {
		return text;
	}
	public void setText(String text) {
		this.text = text;
	}
	public String getMisc1() {
		return misc1;
	}
	public void setMisc1(String misc1) {
		this.misc1 = misc1;
	}
	public String getMisc2() {
		return misc2;
	}
	public void setMisc2(String misc2) {
		this.misc2 = misc2;
	}
	
}

Now that I upgraded to 7.1.2, I tried this re-sizable modal sub-window again and it all works just fine in all browsers that I have. It also works with the GridLayout without any FormLayout. Error indicators and tooltips work as expected with validators and a couple of converters that I have.

Also added .v-textfield-error { background-color: #F3E2A9 !important;} to make missing mandatory values more obvious to the user as suggested somewhere on this forum.

Regards,

Olli-Pekka