0

The MVP model that I have implemented in my project is Passive MVP. The presenter has a reference to the view. Also, presenter has a Display interface which the view has to abide by.

My current Display interface is as below -

public interface Display {
    Widget asWidget();

    <Control extends HasValue<String> & HasBlurHandlers> Control code();
    <Control extends HasValue<String> & HasBlurHandlers> Control name();
    <Control extends HasValue<String> & HasBlurHandlers> Control address();
    <Control extends HasValue<String> & HasBlurHandlers> Control contactNumber1();
    <Control extends HasValue<String> & HasBlurHandlers> Control contactNumber2();
    <Control extends HasValue<String> & HasBlurHandlers> Control email();
    <Control extends HasValue<String> & HasBlurHandlers> Control registrationNumber();
    <Control extends HasValue<String> & HasBlurHandlers & HasEnabled> Control registrationYear();

    HasClickHandlers saveControl();
    HasClickHandlers cancelControl();

    void setCodeError(String message);
    void setNameError(String message);
    void setAddressError(String message);
    void setContactNumber1Error(String message);
    void setEmailError(String message);
    void setRegistrationNumberError(String message);

    void clearCodeError();
    void clearNameError();
    void clearAddressError();
    void clearContactNumber1Error();
    void clearEmailError();
    void clearRegistrationNumberError();
}

The pain here is the methods used to set/clear input error messages. Each setXXXError() implemented by a View will make the corresponding ErrorWidget visible, and perhaps also highlight the corresponding InputWidget (by marking it red or something). Conversely, each clearXXXError() method would hide the corresponding ErrorWidget, and remove the highlight from the corresponding InputWidget. This way, the presenter doesn't have to deal explicitly with CSS management, thus decoupling itself from changes in CSS. Only the view has to worry about it.

However, this approach has ended up in too many error-related methods in the interface.

An alternative approach that I thought of is to expose the ErrorWidgets in the interface. But, GWT having no HasCss-type interface, I would have to either explicitly specify the widget type (say, a Label), or use IsWidget interface (which would again expose the whole widget instead of just its CSS properties). Also, in this approach, I would then have to explicitly specify the CSS modifications in the presenter.

Is there any better alternative to my approach? Or what I am doing is good enough? I would also love any improvements in my current approach.

bhootjb
  • 1,501
  • 1
  • 21
  • 33
  • 1
    Are you using the GWT Editor Framework at all? If so, check out the `HasEditorError` interface - if each control is capable of displaying its own errors, you can just delegate down to there... – Colin Alworth Mar 29 '13 at 20:17

1 Answers1

1

Maybe you could consider using this tooltip plugin (focus on the validation example at the bottom). It enhances your widgets with very few lines of code.

The source code of the plugin and examples, and the info about how to add it to your project is in this github repo. And In this link you have the piece of code they use to enhance their example form.

In your case setup your form widgets with:

 @UiField TextBox myTextBoxWidget;

 $(myTextBoxWidget).id("textbox1").as(Tooltip).tooltip(new TooltipOptions()
            .withContent("Password cannot be empty")
            .withTrigger(TooltipTrigger.MANUAL)
            .withPlacement(TooltipPlacement.RIGHT)
            .withResources(ValidationTooltipResources.INSTANCE));

Then in your view you could add a method to notify from the presenter which widgets are in error, I would use a CSS selector (based on ids or classes), something like:

 myView.setError("#texbox1, #texbox2");

and the implementation of this method in the view could be:

 public void setError(cssSelector) {
   $(*, this).removeClass("invalid");
   $(cssSelector, this).addClass("invalid");
 }

As you can see this solution is not intrusive in the sense that the plugin don't need to know anything about your widgets implementation, and you aren't forced to implement certain interfaces in your widgets, etc.

Manolo Carrasco Moñino
  • 9,723
  • 1
  • 22
  • 27