001package gwt.material.design.client.base.error;
002
003/*
004 * #%L
005 * GwtBootstrap3
006 * %%
007 * Copyright (C) 2015 GwtBootstrap3
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import com.google.gwt.editor.client.EditorError;
024import com.google.gwt.event.logical.shared.AttachEvent;
025import com.google.gwt.event.logical.shared.AttachEvent.Handler;
026import com.google.gwt.user.client.ui.HasWidgets;
027import com.google.gwt.user.client.ui.Widget;
028import gwt.material.design.client.base.HasError;
029import gwt.material.design.client.ui.MaterialHelpBlock;
030
031import java.util.List;
032
033/**
034 * This is the default {@link ErrorHandler} implementation.
035 * If there is a {@link MaterialHelpBlock} that is a child then error messages
036 * will be displayed in the {@link MaterialHelpBlock}.
037 *
038 * Example:
039 *
040 * <pre>{@code
041 * <m:MaterialRow>
042 *     <m:TextBox m:id="username" ui:field="username" />
043 *     <m:MaterialHelpBlock iconType="EXCLAMATION" />
044 * </m:MaterialRow>
045 * }</pre>
046 *
047 * @author Steven Jardine
048 * @author Ben Dol
049 */
050public class DefaultErrorHandler implements ErrorHandler {
051
052    private boolean initialized = false;
053
054    private final Widget inputWidget;
055
056    private MaterialHelpBlock helpBlock = null;
057
058    /**
059     * Default error handler.
060     *
061     * @param widget the parent of this error handler.
062     */
063    public DefaultErrorHandler(Widget widget) {
064        super();
065        assert widget != null;
066        this.inputWidget = widget;
067        this.inputWidget.addAttachHandler(new Handler() {
068            @Override
069            public void onAttachOrDetach(AttachEvent event) {
070                init();
071            }
072        });
073    }
074
075    @Override
076    public void cleanup() {
077    }
078
079    @Override
080    public void clearErrors() {
081        if(inputWidget instanceof HasError) {
082            ((HasError) inputWidget).clearErrorOrSuccess();
083        }
084        if (helpBlock != null) {
085            helpBlock.removeStyleName("field-error-label");
086            helpBlock.removeStyleName("field-success-label");
087            helpBlock.clear();
088        }
089    }
090
091    /**
092     * Find the sibling {@link MaterialHelpBlock}.
093     *
094     * @param widget the {@link Widget} to search.
095     * @return the found {@link MaterialHelpBlock} of null if not found.
096     */
097    protected MaterialHelpBlock findHelpBlock(Widget widget) {
098        if(widget != null) {
099            if (widget instanceof MaterialHelpBlock) {
100                return (MaterialHelpBlock) widget;
101            }
102            // Try and find the MaterialHelpBlock in the children of the given widget.
103            if (widget instanceof HasWidgets) {
104                for (Widget w : (HasWidgets) widget) {
105                    if (w instanceof MaterialHelpBlock) {
106                        return (MaterialHelpBlock) w;
107                    }
108                }
109            }
110            // Try and find the MaterialHelpBlock in the parent of widget.
111            return findHelpBlock(widget.getParent());
112        }
113        return null;
114    }
115
116    /**
117     * Initialize the instance.
118     */
119    public void init() {
120        if (initialized) { return; }
121        Widget parent = inputWidget.getParent();
122        while (parent != null && !parent.getClass().getName().equals("com.google.gwt.user.client.ui.Widget")) {
123            helpBlock = findHelpBlock(inputWidget);
124            if(helpBlock != null) {
125                break;
126            } else {
127                parent = parent.getParent();
128            }
129        }
130        initialized = true;
131    }
132
133    @Override
134    public void showErrors(List<EditorError> errors) {
135        init();
136        String errorMsg = "";
137        for (int index = 0; index < errors.size(); index++) {
138            errorMsg = errors.get(0).getMessage();
139            if (index + 1 < errors.size()) { errorMsg += "; "; }
140        }
141
142        if(inputWidget instanceof HasError) {
143            ((HasError) inputWidget).setError(errorMsg);
144        }
145
146        if (helpBlock != null) {
147            helpBlock.addStyleName("field-error-label");
148            helpBlock.removeStyleName("field-success-label");
149            helpBlock.setText(errorMsg);
150        }
151    }
152}