001/* 002 * Copyright 2012 GWT-Bootstrap 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.github.gwtbootstrap.client.ui.base; 017 018import com.github.gwtbootstrap.client.ui.Close; 019import com.github.gwtbootstrap.client.ui.constants.AlertType; 020import com.github.gwtbootstrap.client.ui.constants.Constants; 021import com.github.gwtbootstrap.client.ui.constants.DismissType; 022import com.github.gwtbootstrap.client.ui.event.ClosedEvent; 023import com.github.gwtbootstrap.client.ui.event.ClosedHandler; 024import com.github.gwtbootstrap.client.ui.event.HasCloseHandlers; 025import com.google.gwt.dom.client.Element; 026import com.google.gwt.event.logical.shared.CloseEvent; 027import com.google.gwt.event.logical.shared.CloseHandler; 028import com.google.gwt.event.shared.HandlerRegistration; 029import com.google.gwt.safehtml.shared.SafeHtmlUtils; 030import com.google.gwt.user.client.ui.HTMLPanel; 031import com.google.gwt.user.client.ui.HasWidgets; 032 033/** 034 * Base class for Alert widgets. 035 * 036 * @author Dominik Mayer 037 * @author Carlos Alexandro Becker 038 * 039 * @see <a 040 * href="http://getbootstrap.com/2.3.2/components.html#alerts">Bootstrap 041 * documentation</a> 042 * 043 * @since 2.0.4.0 044 */ 045public abstract class AlertBase extends HtmlWidget implements IsAnimated, 046 HasCloseHandlers<AlertBase>, HasType<AlertType> { 047 048 private Close close; 049 050 private HTMLPanel closeReplacement = new HTMLPanel("span", ""); 051 052 private HTMLPanel headingContainer = new HTMLPanel("span", ""); 053 054 private HTMLPanel container; 055 056 private boolean fade; 057 058 private boolean hasClose; 059 060 /** 061 * Initializes an Alert with a close icon. 062 */ 063 public AlertBase() { 064 this("", true); 065 } 066 067 /** 068 * Initializes an Alert with a inner HTML. 069 * 070 * @param html inner HTML 071 */ 072 public AlertBase(String html) { 073 this(html, true); 074 } 075 076 /** 077 * Initializes an Alert with an optional close icon. 078 * 079 * @param html inner HTML 080 * @param hasClose whether the Alert should have a close icon. 081 */ 082 public AlertBase(String html, boolean hasClose) { 083 super("div", ""); 084 085 super.add(closeReplacement); 086 super.add(headingContainer); 087 container = new HTMLPanel("span", html); 088 super.add(container); 089 super.setStyleName(Constants.ALERT); 090 setClose(hasClose); 091 } 092 093 /** 094 * Initializes an Alert of given Type with a close icon. 095 * 096 * @param type of the Alert 097 */ 098 public AlertBase(AlertType type) { 099 this(); 100 setType(type); 101 } 102 103 /** 104 * Sets whether the Alert has a close icon or not. 105 * 106 * @param hasClose <code>false</code> if you don't want to have a close icon. 107 * Default: <code>true</code> 108 */ 109 public void setClose(boolean hasClose) { 110 111 this.hasClose = hasClose; 112 113 if (!isAttached()) { 114 return; 115 } 116 117 if (hasClose) { 118 if (close == null) { 119 close = new Close(DismissType.ALERT); 120 getElement().replaceChild(close.getElement(), closeReplacement.getElement()); 121 } 122 } else { 123 if (close != null) { 124 getElement().replaceChild(closeReplacement.getElement(), close.getElement()); 125 close = null; 126 } 127 } 128 } 129 130 /** 131 * {@inheritDoc} 132 */ 133 @Override 134 protected void onAttach() { 135 super.onAttach(); 136 setClose(hasClose); 137 configure(getElement()); 138 setHandlerFunctions(getElement()); 139 } 140 141 /** 142 * has Close 143 * 144 * @return true:has close false:does not has close 145 */ 146 public boolean hasClose() { 147 return hasClose; 148 } 149 150 /** 151 * Gets heading's container widget 152 * 153 * @return heading's container 154 */ 155 protected HasWidgets getHeadingContainer() { 156 return headingContainer; 157 } 158 159 /** 160 * This method is called immediately when the widget's close method is 161 * executed. 162 */ 163 // TODO: Get the source element from javascript 164 protected void onClose() { 165 CloseEvent.fire(this, this); 166 } 167 168 /** 169 * This method is called once the widget is completely closed. 170 */ 171 // TODO: Get the source element from javascript 172 protected void onClosed() { 173 ClosedEvent.fire(this, this); 174 this.onDetach(); 175 } 176 177 /** 178 * Sets the type of the Alert. 179 * 180 * @param type 181 */ 182 public void setType(AlertType type) { 183 StyleHelper.changeStyle(this, type, AlertType.class); 184 } 185 186 /** 187 * Sets the text of an optional heading. The implementation depends on the 188 * subclass. 189 * 190 * @param text the new heading 191 */ 192 public void setHeading(String text) { 193 headingContainer.clear(); 194 headingContainer.add(new HTMLPanel("span", text)); 195 } 196 197 /** 198 * Sets whether the Alert should be animated. 199 * 200 * @param animated <code>true</code> if the Alert should fade out. Default: 201 * <code>false</code> 202 */ 203 public void setAnimation(boolean animated) { 204 this.fade = animated; 205 setFade(); 206 } 207 208 /** 209 * {@inheritDoc} 210 */ 211 public boolean getAnimation() { 212 return fade; 213 } 214 215 /** 216 * Delete the whole content of the Alert. This includes text, heading and 217 * close icon. 218 */ 219 @Override 220 public void clear() { 221 container.clear(); 222 } 223 224 /** 225 * Sets the classes that define whether the Alert fades or not. 226 */ 227 private void setFade() { 228 if (fade) { 229 addStyleName("fade"); 230 addStyleName("in"); 231 } else { 232 removeStyleName("fade"); 233 removeStyleName("in"); 234 } 235 } 236 237 /** 238 * {@inheritDoc} 239 */ 240 public String getText() { 241 return container.getElement().getInnerText(); 242 } 243 244 /** 245 * {@inheritDoc} 246 */ 247 public void setText(String text) { 248 setHTML(SafeHtmlUtils.htmlEscape(text)); 249 } 250 251 /** 252 * {@inheritDoc} 253 */ 254 public String getHTML() { 255 return container.getElement().getInnerHTML(); 256 } 257 258 public void setHTML(String html) { 259 container.clear(); 260 container.add(new HTMLPanel("span", html)); 261 } 262 263 /** 264 * Close this alert. 265 */ 266 public void close() { 267 close(getElement()); 268 } 269 270 /** 271 * {@inheritDoc} 272 */ 273 @Override 274 public HandlerRegistration addCloseHandler(CloseHandler<AlertBase> handler) { 275 return addHandler(handler, CloseEvent.getType()); 276 } 277 278 /** 279 * {@inheritDoc} 280 */ 281 @Override 282 public HandlerRegistration addClosedHandler(ClosedHandler<AlertBase> handler) { 283 return addHandler(handler, ClosedEvent.getType()); 284 } 285 286 //@formatter:off 287 288 /** 289 * Adds the Java functions that fire the Events to document. It is a 290 * convenience method to have a cleaner code later on. 291 */ 292 // TODO: Add autoTriggered feature in order to support autoClosed events. See {@link Modal}. 293 private native void setHandlerFunctions(Element e) /*-{ 294 var that = this; 295 var $e = $wnd.jQuery(e); 296 $e.bind('close', function () { 297 that.@com.github.gwtbootstrap.client.ui.base.AlertBase::onClose()(); 298 }); 299 $e.bind('closed', function () { 300 that.@com.github.gwtbootstrap.client.ui.base.AlertBase::onClosed()(); 301 }); 302 }-*/; 303 304 private native void configure(Element e) /*-{ 305 $wnd.jQuery(e).alert(e); 306 }-*/; 307 308 private native void close(Element e)/*-{ 309 $wnd.jQuery(e).alert('close'); 310 }-*/; 311 //@formatter:on 312 313}