Best way to show validation errors

With the old Form component, required fields and related errors were automatically handled - with FieldGroup nothing of that is handled and the CommitException that is thrown does not even give a pointer or message that helps with finding out which field that was invalid?

Well, Fields with Validation-errors are still marked with an error-indicator and the first error-message can be obtained from the CommitException by calling getCause() to get the underlying InvalidValueException. That one can be asked for it’s detail-message.

An easy way to get all error-messages from the Fields is still missing somehow, you have to iterate the field-list and call validate() for each one. But that has been the same with Vaadin 6 …

You are quite right, while the Vaadin 7 way of doing forms is a lot more flexible, displaying a form error requires a lot more work.

We’ve discussed the problem a bit, but do not have a clear solution for it yet. Check out
this example
for a sketch of one suggested solution. Well, the ErrorDisplay interface helps a bit, but does not make simple forms nearly as easy as with Vaadin 6.

Vaadin 6 forms do work in Vaadin 7 even though they are deprecated. Well, there’s
a bug
with them at the moment.

I write a utility class to do this:

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.vaadin.server.ErrorMessage;
import com.vaadin.server.Page;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;

public class ErrorUtils {
    public static List<String> getComponentError(
            final AbstractComponent[] componentArray) {
        List<String> errorList = new ArrayList<String>();

        for (AbstractComponent component : componentArray) {
            ErrorMessage errorMessage = component.getErrorMessage();
            if (errorMessage != null) {
                errorList.add(errorMessage.getFormattedHtmlMessage());
            }
        }

        return errorList;
    }

    public static List<String> getComponentError(
            final Collection<?> componentCollection) {
        AbstractComponent[] componentArray = componentCollection
                .toArray(new AbstractComponent[] {});
        return ErrorUtils.getComponentError(componentArray);
    }

    public static void showComponentErrors(
            final AbstractComponent[] componentArray) {
        List<String> errorList = ErrorUtils.getComponentError(componentArray);

        String error = StringUtils.join(errorList, "\n");

        Notification notification = new Notification("Error", error,
                Type.ERROR_MESSAGE, true);

        notification.show(Page.getCurrent());
    }

    public static void showComponentErrors(
            final Collection<?> componentCollection) {
        AbstractComponent[] componentArray = componentCollection
                .toArray(new AbstractComponent[] {});

        ErrorUtils.showComponentErrors(componentArray);
    }
}

The the following code is a simple sample showing how to use it:

   private void saveButtonClicked() {
        // this method is the handler of the click event of the [save]
 button

        try {
            this.fieldGroup.commit();
        } catch (CommitException e) {
            // Show all the validate errors:
            ErrorUtils.showComponentErrors(this.fieldGroup.getFields());

            return;
        }

        // save data, if there is no validate error
    }

Neat way of doing it. I really like just putting the field in setImmediate(true) state.
That way as soon as the user tabs out they know that field is not valid.

Clean, simple and effecient in my humble opinon.

I also put .isValid() checks for special fields in my forms save() action BEFORE the commit()
method call and before that I have a .isModified() on my FieldGroup object to
prevent them from saving with no edit changes.

Cheers

Hi,

I think Vaadin should do much better job here. This is really the place where Vaadin should shine, but there is lots of inconveniences and boiler plate code that needs to be written. Binding a simple pojo to a form shouldn’t be that hard. I hope you all would fill in enhancement tickets to dev.vaadin.com about any related improvement ideas.

I have recently done some helpers also to make user friendly form forms, but without writing huge amounts of boiler plate code. I also wanted my forms to really take the advantage of RIA thing. Like Ed, I make my fields immediate to get feedback earlier for end user, but I took it bit further. I also control save/cancel buttons based on changes and validity and do the validation even more eagerly - while typing into fields. Making this all work was quite tricky, but I’m now quite satisfied with the result.

My helpers are available in my
Vaadin helper library
. I’d be very happy to get some feedback and contributions. Simple usage example is in my tiny
Vaadin + Java EE example
. This
pojo
, with standard bean validation annotations, is bound to this
form
, using
setEntity
method. Then just hook in
save/reset listeners
. You’ll get a from with decent UX, with rather minimal boiler plate.

Online demo (on a randomly running demo machnice):

http://matti.app.fi:8081/java-ee-essentials/

cheers,
matti

save data, if there is no validate error…