Search code examples
javavalidationgwtgxt

GXT validation feedback


I have some POJO with JSR 303 validation like this one :

@NotNull
@Size(max = 80)
@Column(name = "trs_name")
private String name;

In the application, I render it with a GXT TextField wrapped in a GXT FieldLabel, inside a GWT Editor. If the validation fails, the FieldLabel automatically displays a red wave and a red flag :

Validation

And this is exactly what I need.

But for more complex validation like this one :

@Size(min = 1)
private Set<EnumRole> roles;

I created a custom Editor<Set<Enum>> :

public class EnumSetEditor<T extends Enum<T>> extends Composite implements LeafValueEditor<Set<T>> {


  private Map<T, CheckBox> map;

  public EnumSetEditor(Class<T> clazz) {
    FlowPanel panel = new FlowPanel();

    this.map = new HashMap<T, CheckBox>();
    for(T t : clazz.getEnumConstants()) {
      CheckBox cb = new CheckBox();
      cb.setBoxLabel(I18nEnum.i18nEnum(t)); //translates the enum
      panel.add(cb);
      map.put(t, cb);
    }
    this.initWidget(panel);
  }

  @Override
  public void setValue(Set<T> value) {
    for(Map.Entry<T, CheckBox> entry : map.entrySet()) {
      entry.getValue().setValue(value.contains(entry.getKey()));
    }
  }

  @Override
  public Set<T> getValue() {
    Set<T> result = new HashSet<T>();
    for(Map.Entry<T, CheckBox> entry : map.entrySet()) {
      if(entry.getValue().getValue()) {
        result.add(entry.getKey());
      }
    }
    return result;
  }
}

It is rendred like this :

SetEnum

The problem is that, even wrapped in a GXT FieldLabel, I have no feedback if no option is checked. Hence, the validation fails and the user has no feedback.

I thought that the GXT FieldLabel would automatically add the red flag on the right of the editor in case of validation failure.

  1. Do I do something wrong ?
  2. Is there a best practice to obtain this feedback ?

Solution

  • I finally found the solution myself : I believed that the FieldLabel handled the feedback itself but this is wrong.

    1. My class must implement HasEditorErrors<Set<T>> so that method void showErrors(List<EditorError> errors) is called. I can do whatever I want in this case : display an icon, underline something etc.

    2. There is a predefined class in GXT which handles the icon + the validation message : SideErrorHandler.

    Hence, I modified the class like this :

    public class EnumSetEditor<T extends Enum<T>> extends Composite implements LeafValueEditor<Set<T>>, HasEditorErrors<Set<T>> {
    
      //Added errorHandler attribute
      private SideErrorHandler errorHandler;
    
      public EnumSetEditor(Class<T> clazz) {
    
        ...
        //Initialize the ErrorHandler
        this.errorHandler = new SideErrorHandler(this);
      }
    
      /* 
       * Implemented showErrors(List<EditorError> errors)
       * I only delegate the errors to the ErrorHandler.
       */
    
      @Override
      public void showErrors(List<EditorError> errors) {
        if(errors.isEmpty()) {
          errorHandler.clearInvalid();
        } else {
          errorHandler.markInvalid(errors);
        }
      }
    }