001package org.gwtbootstrap3.client.ui;
002
003/*
004 * #%L
005 * GwtBootstrap3
006 * %%
007 * Copyright (C) 2013 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 org.gwtbootstrap3.client.ui.base.AbstractTextWidget;
024import org.gwtbootstrap3.client.ui.constants.ElementTags;
025import org.gwtbootstrap3.client.ui.constants.IconType;
026import org.gwtbootstrap3.client.ui.constants.Styles;
027
028import com.google.gwt.dom.client.Document;
029import com.google.gwt.dom.client.Element;
030import com.google.gwt.dom.client.Style.Unit;
031import com.google.gwt.event.dom.client.ChangeEvent;
032import com.google.gwt.event.dom.client.ChangeHandler;
033import com.google.gwt.event.dom.client.DomEvent;
034
035/**
036 * Help block. Call {@link #setError(String)} to set ther error state of this
037 * {@link HelpBlock}.
038 * 
039 * @author Joshua Godi
040 * @author Steven Jardine
041 */
042public class HelpBlock extends AbstractTextWidget {
043
044    private boolean error = false;
045
046    private Element iconElement = null;
047
048    private IconType iconType = null;
049
050    /**
051     * Constructor.
052     */
053    public HelpBlock() {
054        super(Document.get().createSpanElement());
055        setStyleName(Styles.HELP_BLOCK);
056        addHandler(new ChangeHandler() {
057            @Override
058            public void onChange(ChangeEvent event) {
059                if (iconElement != null) {
060                    iconElement.removeFromParent();
061                }
062                if (error && iconType != null) {
063                    iconElement = createIconElement();
064                    getElement().insertFirst(iconElement);
065                }
066            }
067        }, ChangeEvent.getType());
068    }
069
070    /**
071     * Clear the error state of this help block.
072     */
073    public void clearError() {
074        error = false;
075        setText("");
076    }
077
078    /**
079     * @return a new icon element. We only create this when {@link #iconElement}
080     *         is null or the {@link #iconType} has changed.
081     */
082    protected Element createIconElement() {
083        Element e = Document.get().createElement(ElementTags.I);
084        e.addClassName(Styles.FONT_AWESOME_BASE);
085        e.addClassName(iconType.getCssName());
086        e.getStyle().setPaddingRight(5, Unit.PX);
087        return e;
088    }
089
090    /**
091     * @return the icon type
092     */
093    public IconType getIconType() {
094        return iconType;
095    }
096
097    /**
098     * Checks if this block is in the error state.
099     *
100     * @return true, if is error
101     */
102    public boolean isError() {
103        return error;
104    }
105
106    /**
107     * Set this {@link HelpBlock}'s error state.
108     * 
109     * @param message
110     *            the error message.
111     */
112    public void setError(String message) {
113        error = true;
114        setText(message);
115    }
116
117    /** {@inheritDoc} */
118    @Override
119    public void setHTML(String value) {
120        String oldValue = getHTML();
121        if (!oldValue.equals(value)) {
122            super.setHTML(value);
123            DomEvent.fireNativeEvent(Document.get().createChangeEvent(), this);
124        }
125    }
126
127    /**
128     * Sets the icon type. If the icon type changes programatically then the
129     * icon is removed from the dom and recreated.
130     *
131     * @param type
132     *            the new icon type
133     */
134    public void setIconType(IconType type) {
135        IconType prevType = iconType;
136        iconType = type;
137        if (iconType != prevType && iconElement != null) {
138            iconElement.removeFromParent();
139            iconElement = null;
140            DomEvent.fireNativeEvent(Document.get().createChangeEvent(), this);
141        }
142    }
143
144    /** {@inheritDoc} */
145    @Override
146    public void setText(String value) {
147        String oldValue = getText();
148        if (!oldValue.equals(value)) {
149            super.setText(value);
150            DomEvent.fireNativeEvent(Document.get().createChangeEvent(), this);
151        }
152    }
153
154}