001    package 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    
023    import org.gwtbootstrap3.client.shared.event.AlertCloseEvent;
024    import org.gwtbootstrap3.client.shared.event.AlertCloseHandler;
025    import org.gwtbootstrap3.client.shared.event.AlertClosedEvent;
026    import org.gwtbootstrap3.client.shared.event.AlertClosedHandler;
027    import org.gwtbootstrap3.client.ui.base.HasResponsiveness;
028    import org.gwtbootstrap3.client.ui.base.HasType;
029    import org.gwtbootstrap3.client.ui.base.button.CloseButton;
030    import org.gwtbootstrap3.client.ui.base.helper.StyleHelper;
031    import org.gwtbootstrap3.client.ui.constants.AlertType;
032    import org.gwtbootstrap3.client.ui.constants.ButtonDismiss;
033    import org.gwtbootstrap3.client.ui.constants.Styles;
034    import org.gwtbootstrap3.client.ui.html.Div;
035    import org.gwtbootstrap3.client.ui.html.Text;
036    
037    import com.google.gwt.dom.client.Element;
038    import com.google.gwt.user.client.Event;
039    import com.google.gwt.user.client.ui.HasText;
040    import com.google.gwt.user.client.ui.HasWidgets;
041    import com.google.web.bindery.event.shared.HandlerRegistration;
042    
043    /**
044     * Alert block.
045     * <p/>
046     * Use {@link #setDismissable(boolean)} to add a close ("x") button.
047     *
048     * @author Sven Jacobs
049     * @author Joshua Godi
050     * @see org.gwtbootstrap3.client.shared.event.AlertCloseEvent
051     * @see org.gwtbootstrap3.client.shared.event.AlertClosedEvent
052     */
053    public class Alert extends Div implements HasWidgets, HasText, HasType<AlertType>, HasResponsiveness {
054        private static final String CLOSE = "close";
055    
056        private final Text text = new Text();
057        private final CloseButton closeButton = new CloseButton();
058    
059        /**
060         * Builds a default alert
061         */
062        public Alert() {
063            setStyleName(Styles.ALERT);
064            setType(AlertType.WARNING);
065            closeButton.setDataDismiss(ButtonDismiss.ALERT);
066        }
067    
068        /**
069         * Builds a default alert with the desired text
070         *
071         * @param text text for the alert
072         */
073        public Alert(final String text) {
074            this();
075            setText(text);
076        }
077    
078        /**
079         * Builds an alert with the desired text and type
080         *
081         * @param text text for the alert
082         * @param type type for the alert
083         */
084        public Alert(final String text, final AlertType type) {
085            this(text);
086            setType(type);
087        }
088    
089        @Override
090        protected void onLoad() {
091            super.onLoad();
092    
093            // Bind the events
094            bindJavaScriptEvents(getElement());
095        }
096    
097        @Override
098        protected void onUnload() {
099            super.onUnload();
100    
101            // Unbind the events
102            unbindJavaScriptEvents(getElement());
103        }
104    
105        /**
106         * {@inheritDoc}
107         */
108        @Override
109        public String getText() {
110            return text.getText();
111        }
112    
113        /**
114         * {@inheritDoc}
115         */
116        @Override
117        public void setText(final String text) {
118            this.text.setText(text);
119            insert(this.text, 0);
120        }
121    
122        /**
123         * {@inheritDoc}
124         */
125        @Override
126        public void setType(final AlertType type) {
127            StyleHelper.addUniqueEnumStyleName(this, AlertType.class, type);
128        }
129    
130        /**
131         * {@inheritDoc}
132         */
133        @Override
134        public AlertType getType() {
135            return AlertType.fromStyleName(getStyleName());
136        }
137    
138        /**
139         * Adds a close button to the alert
140         *
141         * @param dismissable Adds close button when {@code true}
142         */
143        public void setDismissable(final boolean dismissable) {
144            if (dismissable) {
145                insert(closeButton, (Element) getElement(), 0, true);
146                addStyleName(Styles.ALERT_DISMISSABLE);
147            } else {
148                closeButton.removeFromParent();
149                removeStyleName(Styles.ALERT_DISMISSABLE);
150            }
151        }
152    
153        /**
154         * Returns if the alert can be closed or not
155         *
156         * @return true = alert can be closed, false = alert cannot be closed
157         */
158        public boolean isDismissable() {
159            return closeButton.getParent() != null;
160        }
161    
162        /**
163         * Closes alert.
164         */
165        public void close() {
166            alert(getElement(), CLOSE);
167        }
168    
169        /**
170         * Event fired when the close is initiated on the alert
171         *
172         * @param evt event
173         */
174        protected void onClose(final Event evt) {
175            fireEvent(new AlertCloseEvent(evt));
176        }
177    
178        /**
179         * Event fired when the alert is fully closed (will wait for CSS transitions)
180         *
181         * @param evt event
182         */
183        protected void onClosed(final Event evt) {
184            fireEvent(new AlertClosedEvent(evt));
185        }
186    
187        /**
188         * Add a handler to be used when the close event is fired
189         *
190         * @param handler handler for event
191         * @return handler registration for the handler
192         */
193        public HandlerRegistration addCloseHandler(final AlertCloseHandler handler) {
194            return addHandler(handler, AlertCloseEvent.getType());
195        }
196    
197        /**
198         * Add a handler to be used when the closed event is fired
199         *
200         * @param handler handler for event
201         * @return handler registration for the handler
202         */
203        public HandlerRegistration addClosedHandler(final AlertClosedHandler handler) {
204            return addHandler(handler, AlertClosedEvent.getType());
205        }
206    
207        // @formatter:off
208        private native void alert(final Element e, final String arg) /*-{
209            $wnd.jQuery(e).alert(arg);
210        }-*/;
211    
212        private native void bindJavaScriptEvents(final Element e) /*-{
213            var target = this;
214            var $alert = $wnd.jQuery(e);
215    
216            $alert.on('close.bs.alert', function (evt) {
217                target.@org.gwtbootstrap3.client.ui.Alert::onClose(Lcom/google/gwt/user/client/Event;)(evt);
218            });
219    
220            $alert.on('closed.bs.alert', function (evt) {
221                target.@org.gwtbootstrap3.client.ui.Alert::onClosed(Lcom/google/gwt/user/client/Event;)(evt);
222            });
223        }-*/;
224    
225        private native void unbindJavaScriptEvents(final Element e) /*-{
226            $wnd.jQuery(e).off('close.bs.alert');
227            $wnd.jQuery(e).off('closed.bs.alert');
228        }-*/;
229    }