IsEditor and Editor hasErrors always false problem, and getErrors always empty

181 views
Skip to first unread message

Milan Cvejic

unread,
Aug 31, 2012, 6:00:54 PM8/31/12
to google-we...@googlegroups.com
Hi Everyone,
I am stuck with validating objects. So if anyone can help me or point me to the right direction that would be great.

I have following code:

SettingsViewImpl.ui.xml

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:g="urn:import:com.google.gwt.user.client.ui"
    xmlns:c="urn:import:com.google.gwt.user.cellview.client"
    xmlns:w="urn:import:com.hat.coupled.client.ui.widget"
    xmlns:b="urn:import:com.github.gwtbootstrap.client.ui"
    xmlns:customPanel="urn:import:com.hat.coupled.client.ui.panel.disclosure"
    xmlns:customPanelHeader="urn:import:com.hat.coupled.client.ui.widget.header">
   
    <ui:image field="dpheaderbackground" />
   
    <ui:style>
        .disclosurePanelStyle {
            width: 100%;
            display: block;
            position: relative;
        }

        @sprite .disclosurePanelHeaderTextWrapperStyle {
            gwt-image: 'dpheaderbackground';
            background-repeat: repeat-x;
            background-position: 30px center;
            height: auto;
            width: 100%;
        }

        .disclosurePanelHeaderTextStyle {
            font-size: 13pt;
            line-height: 18pt;
            background-color: #F5F5F5;
            height: auto;
            width: auto;
            float: left;
            padding-right: 5px;
            padding-left: 5px;
        }

        .disclosurePanelHeaderStyle {
            margin-bottom: 10px;
        }
    </ui:style>
    <b:FluidContainer>
        <b:FluidRow ui:field="settingsPanelRow">
            <b:ButtonToolbar ui:field="buttonToolbar">
                <b:ButtonGroup>
                    <b:Button ui:field="backButton" icon="ARROW_LEFT">Back</b:Button>
                </b:ButtonGroup>
                <b:ButtonGroup>
                    <b:Button ui:field="saveButton" icon="SAVE" type="DANGER">Save</b:Button>
                </b:ButtonGroup>
            </b:ButtonToolbar>
        </b:FluidRow>
       
        <b:FluidRow ui:field="alertMessageWrapper">
            <!-- placeholder for alerts -->
        </b:FluidRow>
       
        <b:FluidRow ui:field="globalSettings">
                <b:Well>
                    <customPanel:DisclosurePanelWithDragHandler header="Global Site Settings"
                        width="100%" height="100%" animationEnabled="true"
                        open="true" isDraggable="false"
                        addHeaderTextWrapperStyleNames="{style.disclosurePanelHeaderTextWrapperStyle}"
                        addHeaderTextStyleNames="{style.disclosurePanelHeaderTextStyle}"
                        addHeaderStyleNames="{style.disclosurePanelHeaderStyle}"
                        >
                        <b:Form type="HORIZONTAL" ui:field="siteConfigForm">
                            <b:Fieldset>
                                <b:ControlGroup>
                                    <b:ControlLabel for="siteName">Site Name</b:ControlLabel>
                                    <b:Controls controlsRow="true">
                                           <b:Tooltip text='Site name is text that will be displayed in the browser titlebar' trigger="FOCUS" placement="RIGHT">
                                            <b:TextBox alternateSize="XLARGE" b:id="siteName"
                                                ui:field="siteName"></b:TextBox>
                                        </b:Tooltip>
                                    </b:Controls>
                               
                                    <b:ControlLabel for="siteEmail">Site Email</b:ControlLabel>
                                    <b:Controls controlsRow="true">
                                        <b:Tooltip text='Email that will be used to send all kind of information' trigger="HOVER" placement="RIGHT">
                                            <b:TextBox alternateSize="XLARGE" b:id="siteEmail"
                                            ui:field="siteEmail"></b:TextBox>
                                        </b:Tooltip>
                                    </b:Controls>
                           
                                    <b:ControlLabel for="contactEmail">Contact Email</b:ControlLabel>
                                    <b:Controls controlsRow="true">                                   
                                        <b:TextBox alternateSize="XLARGE" b:id="contactEmail"
                                            ui:field="contactEmail"></b:TextBox>
                                    </b:Controls>
                                    <b:ControlLabel for="favicon">Favicon</b:ControlLabel>
                                    <b:Controls controlsRow="true">                                   
                                        <b:TextBox alternateSize="XLARGE" b:id="favicon"
                                            ui:field="favicon"></b:TextBox>
                                    </b:Controls>
                                   
                                    <b:ControlLabel for="textDirection">Text Direction</b:ControlLabel>
                                    <b:Controls controlsRow="true">
                                     <b:ValueListBox alternateSize="SMALL" ui:field="textDirection">
                                         <!-- This is dropdown box for text direction -->
                                     </b:ValueListBox>
                                     </b:Controls>
                                    <b:Controls>
                                        <b:Button ui:field="resetGlobalSiteSettingsButton">Reset</b:Button>
                                         <b:Button ui:field="saveGlobalSiteSettingsButton" icon="SAVE" type="DANGER">Save</b:Button>
                                    </b:Controls>                                        
                                </b:ControlGroup>
                            </b:Fieldset>
                        </b:Form>
                    </customPanel:DisclosurePanelWithDragHandler>
                </b:Well>
            </b:FluidRow>
           
            <b:FluidRow>
                <b:Well>
                    <customPanel:DisclosurePanelWithDragHandler header="Global Site Settings"
                        width="100%" height="100%" animationEnabled="true"
                        open="true" isDraggable="false"
                        addHeaderTextWrapperStyleNames="{style.disclosurePanelHeaderTextWrapperStyle}"
                        addHeaderTextStyleNames="{style.disclosurePanelHeaderTextStyle}"
                        addHeaderStyleNames="{style.disclosurePanelHeaderStyle}"
                        >
                        <b:Form type="HORIZONTAL">
                            <b:Fieldset>
                                <b:ControlGroup>
                                    <b:ControlLabel for="blaBla">Site Name</b:ControlLabel>
                                    <b:Controls controlsRow="true">
                                        <b:TextBox alternateSize="XLARGE" b:id="blaBla"></b:TextBox>
                                    </b:Controls>
                                </b:ControlGroup>
                            </b:Fieldset>
                        </b:Form>
                    </customPanel:DisclosurePanelWithDragHandler>
                </b:Well>
            </b:FluidRow>       
    </b:FluidContainer>
</ui:UiBinder>



SettingsViewImpl.java

package com.hat.coupled.client.ui;

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

import com.github.gwtbootstrap.client.ui.Alert;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.ButtonToolbar;
import com.github.gwtbootstrap.client.ui.FluidContainer;
import com.github.gwtbootstrap.client.ui.Dropdown;
import com.github.gwtbootstrap.client.ui.FluidRow;
import com.github.gwtbootstrap.client.ui.Form;
import com.github.gwtbootstrap.client.ui.ValueListBox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.EditorDelegate;
import com.google.gwt.editor.client.EditorError;
import com.google.gwt.editor.client.IsEditor;
import com.google.gwt.editor.ui.client.adapters.ValueBoxEditor;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.text.shared.Renderer;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;

import com.github.gwtbootstrap.client.ui.TextBox;
import com.github.gwtbootstrap.client.ui.WellForm;
import com.hat.coupled.client.domain.ClientConfig;

public class SettingsViewImpl implements SettingsView {

    interface SettingsViewImplUiBinder extends UiBinder<FluidContainer, SettingsViewImpl> {
    }

    private static SettingsViewImplUiBinder    uiBinder    = GWT.create(SettingsViewImplUiBinder.class);

    private Presenter                        presenter;

    private final FluidContainer            settingsContainer;

    @UiField
    FluidRow                                alertMessageWrapper;
   
    @UiField
    ButtonToolbar                            buttonToolbar;
    @UiField
    Button                                    backButton;
    @UiField
    Button                                    saveButton;

    @UiField
    Form                                    siteConfigForm;
    @UiField(provided = true)
    ValueListBox                            textDirection;
    @UiField
    TextBox                                    siteName;
    @UiField
    TextBox                                    siteEmail;
    @UiField
    TextBox                                    contactEmail;
    @UiField
    TextBox                                    favicon;
    @UiField
    Button                                    saveGlobalSiteSettingsButton;
    @UiField
    Button                                    resetGlobalSiteSettingsButton;

    public SettingsViewImpl() {

        textDirection = new ValueListBox<String>(new Renderer<String>() {

            public void render(String object, Appendable appendable) throws IOException {
                appendable.append(render(object));
            }

            public String render(String object) {
                return object;
            }
        });
        settingsContainer = uiBinder.createAndBindUi(this);

        backButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                History.back();
            }
        });

    }

    public Widget asWidget() {
        return settingsContainer;
    }

    public void setPresenter(Presenter presenter) {
        this.presenter = presenter;
    }

    public void reset() {
        // TODO implement reset method
    }

    public Boolean save() {
        // TODO Auto-generated method stub
        return null;
    }

    public FluidRow getAlertMessageWrapper() {
        return alertMessageWrapper;
    }
   
    public Button getSaveButton() {
        return saveButton;
    }

    public Button getSaveGlobalSiteSettingsButton() {
        return saveGlobalSiteSettingsButton;
    }

    public Button getResetGlobalSiteSettingsButton() {
        return resetGlobalSiteSettingsButton;
    }

    public ValueListBox<String> getTextDirectionEditor() {
        return textDirection;
    }

    public IsEditor<ValueBoxEditor<String>> getSiteNameEditor() {
        return siteName;
    }

    public IsEditor<ValueBoxEditor<String>> getSiteEmailEditor() {
        return siteEmail;
    }

    public IsEditor<ValueBoxEditor<String>> getContactEmailEditor() {
        return contactEmail;
    }

    public IsEditor<ValueBoxEditor<String>> getFaviconEditor() {
        return favicon;
    }

    public void showErrors(List<EditorError> errors) {
        Window.alert("ShowErrors" + errors.size());
        StringBuilder strBuilder = new StringBuilder();
        for (EditorError error : errors) {
            Window.alert(error.getAbsolutePath());
            strBuilder.append(error.getMessage()).append(error.getAbsolutePath());
        }
        Window.alert(strBuilder.toString());
    }

//    public void setDelegate(EditorDelegate<ClientConfig> delegate) {
//        delegate.recordError("kurac", new ClientConfig(), null);   
//    }
   
}

SettingsView.java

package com.hat.coupled.client.ui;

import java.util.List;

import com.github.gwtbootstrap.client.ui.Alert;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.FluidRow;
import com.github.gwtbootstrap.client.ui.ValueListBox;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.HasEditorDelegate;
import com.google.gwt.editor.client.HasEditorErrors;
import com.google.gwt.editor.client.IsEditor;
import com.google.gwt.editor.client.Editor.Path;
import com.google.gwt.editor.ui.client.adapters.ValueBoxEditor;
import com.google.gwt.user.client.ui.IsWidget;
import com.hat.coupled.client.domain.ClientConfig;

public interface SettingsView extends IsWidget, Editor<ClientConfig>,
    HasEditorErrors<ClientConfig> {
   
    void setPresenter(Presenter presenter);

    public interface Presenter {
       
    }
   
    @Path("textDirection")
    ValueListBox<String> getTextDirectionEditor();
   
    @Path("siteName")
    IsEditor<ValueBoxEditor<String>> getSiteNameEditor();
   
    @Path("siteEmail")
    IsEditor<ValueBoxEditor<String>> getSiteEmailEditor();
   
    @Path("contactEmail")
    IsEditor<ValueBoxEditor<String>> getContactEmailEditor();
   
    @Path("favicon")
    IsEditor<ValueBoxEditor<String>> getFaviconEditor();
   
    public void reset();
    public Boolean save();
   
    public FluidRow getAlertMessageWrapper();
   
    public Button getSaveButton();
   
    public Button getSaveGlobalSiteSettingsButton();
    public Button getResetGlobalSiteSettingsButton();
   
}


ClientConfig.java

package com.hat.coupled.client.domain;

import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;


public class ClientConfig {
    private Integer siteId;
   
    @NotNull
    private String textDirection = "ltr";
   
    @NotNull(message="bla bla bla")
    @Max(10)
    @Size(min = 3, max=10, message="size bla bla bla")
    private String siteName;
   
    @Size(min=7, max=100)
    @NotNull(message="site email is not set")
    @Pattern(regexp="\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b", message="email not valid")
    private String siteEmail;
   
    @Size(min=7, max=100)
    @NotNull(message="site email is not set")
    @Pattern(regexp="\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b", message="email not valid")
    private String contactEmail;
   
    private String favicon;

}


Each time, when I try to validate form, for example making Site Name empty i don't get any error message

i am validating using following code in my activity class:

                    ClientConfig config = editor.flush();
                    if (editor.hasErrors()) {
                        Window.alert("has errors");
                        List<EditorError> errors = editor.getErrors();
                        StringBuilder strBuilder = new StringBuilder();
                        for (EditorError error : errors) {
                            strBuilder.append(error.getMessage()).append(error.getAbsolutePath());
                        }
                    } else {
                        saveConfig(config);
                    }


Does anyone know why there are not error messages in editor.getErrors() and editor.hasErrors() is not being set to true.

Thanks,
Milan

Thomas Broyer

unread,
Sep 1, 2012, 5:48:54 AM9/1/12
to google-we...@googlegroups.com
There's absolutely no relationship between the Editor framework and JSR303 Bean Validation. That is to say: the Editor framework won't validate your objects, you have to do it yourself (and you can then pass the ConstraintViolations to the EditorDriver for display).
The hasErrors and getErrors only give you errors reported by the editors themselves (e.g. IntegerBox will report an error if you type in something that's not a number).
Reply all
Reply to author
Forward
0 new messages