How do I know when a form has sucessfully committed all the fields?

Hi

I would like to display a success message to the user when the form has successfully committed (when all validation passes and the backing form objects attributes have all been set).

Is there a prefered way of doing that?

The only way I could come up with on my own (and I’m a beginner on Vaadin) is this:
When the commit button is clicked in the form, normally a call to the Form.commit() method is made like this:


Button commitButton = new Button("Commit", form, "commit");

This is all according to the Book of Vaadin.

By changing that code and using a button click listener of my own, I can intercept the calls to commit. Like this:


Button commitButton = new Button("Commit", new ClickListener() {
	@Override
	public void buttonClick(ClickEvent event) {
		form.commit();
				
		// Successful commit (we don't get here otherwise)! Display a success message to the user.
		mainWindow.showNotification("Address successfully saved");
	}
});

This click listener delegates to the Form.commit() method. But the important thing is that I get a chance to do something after it returns. I noticed that the Form.commit() method throws exceptions if the validation fails. This means that my code that shows a notification is only displayed if the validation succeedes.


The only problem with this is that I feel that there must be a better way of doing this. But how?

This is the whole code with the interesting parts in bold:


public class TestApplication extends Application {
	
	@Override
	public void init() {
		final Window mainWindow = new Window("Address");
		
		final Label message = new Label();
		message.setVisible(false);
		
		// Create and initialize the address form.
		final Form form = new Form();
		form.setCaption("Enter address");
		form.setDescription("Enter your address");
		form.setImmediate(true);
		form.setWriteThrough(false);
		form.setItemDataSource(new BeanItem<Address>(new Address()));
		
		form.getField("name").setRequired(true);
		form.getField("name").setRequiredError("Name is missing");
		form.getField("address").setRequired(true);
		form.getField("address").setRequiredError("Address is missing");
		form.getField("zip").setRequired(true);
		form.getField("zip").setRequiredError("Zip code is missing");
		form.getField("city").setRequired(true);
		form.getField("city").setRequiredError("City is missing");
		
		// Use a form field factory to be able to change the null
		// representation and set validators etc.
		//
		// This code never gets called though!! Why?
		//
		form.setFormFieldFactory(new FormFieldFactory() {
			@Override
			public Field createField(Item item, Object propertyId, Component uiContext) {
				TextField text = new TextField();
				text.setNullRepresentation("");
				text.addValidator(new RegexpValidator("", "String must be at least 1 character long"));
				text.setRequired(true);
				return text; 
			}
		});
		
[b]
		// Create the commit button, but instead of just specifying that 
		// the commit method on the form should be called, add my own
		// click listener that intercepts the clicks on the button and
		// delegate to the form's commit method.
		// This gives us the chance to take action after a successful
		// commit. We then display a success message to the user.
		Button commitButton = new Button("Commit", new ClickListener() {
			@Override
			public void buttonClick(ClickEvent event) {
				form.commit();
				
				// Successful commit (we don't get here otherwise)! Display a success message to the user.
				mainWindow.showNotification("Address successfully saved");
			}
		});
[/b]
		
		// Add the form and the commit button to the main window.
		mainWindow.addComponent(message);
		mainWindow.addComponent(form);
		mainWindow.addComponent(commitButton);
		
		setMainWindow(mainWindow);
	}
}

Not sure if this is all you mean, but you can call form.isValid() in your commit/save button handler and display an error message that they need to fix the form first. You shouldn’t really have form.commit() failures if form.isValid() is true (at least not in my experience).