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 } 175 176 /** 177 * Sets the type of the Alert. 178 * 179 * @param type 180 */ 181 public void setType(AlertType type) { 182 StyleHelper.changeStyle(this, type, AlertType.class); 183 } 184 185 /** 186 * Sets the text of an optional heading. The implementation depends on the 187 * subclass. 188 * 189 * @param text the new heading 190 */ 191 public void setHeading(String text) { 192 headingContainer.clear(); 193 headingContainer.add(new HTMLPanel("span", text)); 194 } 195 196 /** 197 * Sets whether the Alert should be animated. 198 * 199 * @param animated <code>true</code> if the Alert should fade out. Default: 200 * <code>false</code> 201 */ 202 public void setAnimation(boolean animated) { 203 this.fade = animated; 204 setFade(); 205 } 206 207 /** 208 * {@inheritDoc} 209 */ 210 public boolean getAnimation() { 211 return fade; 212 } 213 214 /** 215 * Delete the whole content of the Alert. This includes text, heading and 216 * close icon. 217 */ 218 @Override 219 public void clear() { 220 container.clear(); 221 } 222 223 /** 224 * Sets the classes that define whether the Alert fades or not. 225 */ 226 private void setFade() { 227 if (fade) { 228 addStyleName("fade"); 229 addStyleName("in"); 230 } else { 231 removeStyleName("fade"); 232 removeStyleName("in"); 233 } 234 } 235 236 /** 237 * {@inheritDoc} 238 */ 239 public String getText() { 240 return container.getElement().getInnerText(); 241 } 242 243 /** 244 * {@inheritDoc} 245 */ 246 public void setText(String text) { 247 setHTML(SafeHtmlUtils.htmlEscape(text)); 248 } 249 250 /** 251 * {@inheritDoc} 252 */ 253 public String getHTML() { 254 return container.getElement().getInnerHTML(); 255 } 256 257 public void setHTML(String html) { 258 container.clear(); 259 container.add(new HTMLPanel("span", html)); 260 } 261 262 /** 263 * Close this alert. 264 */ 265 public void close() { 266 close(getElement()); 267 } 268 269 /** 270 * {@inheritDoc} 271 */ 272 @Override 273 public HandlerRegistration addCloseHandler(CloseHandler<AlertBase> handler) { 274 return addHandler(handler, CloseEvent.getType()); 275 } 276 277 /** 278 * {@inheritDoc} 279 */ 280 @Override 281 public HandlerRegistration addClosedHandler(ClosedHandler<AlertBase> handler) { 282 return addHandler(handler, ClosedEvent.getType()); 283 } 284 285 //@formatter:off 286 287 /** 288 * Adds the Java functions that fire the Events to document. It is a 289 * convenience method to have a cleaner code later on. 290 */ 291 // TODO: Add autoTriggered feature in order to support autoClosed events. See {@link Modal}. 292 private native void setHandlerFunctions(Element e) /*-{ 293 var that = this; 294 var $e = $wnd.jQuery(e); 295 $e.bind('close', function () { 296 [email protected]::onClose()(); 297 }); 298 $e.bind('closed', function () { 299 [email protected]::onClosed()(); 300 }); 301 }-*/; 302 303 private native void configure(Element e) /*-{ 304 $wnd.jQuery(e).alert(e); 305 }-*/; 306 307 private native void close(Element e)/*-{ 308 $wnd.jQuery(e).alert('close'); 309 }-*/; 310 //@formatter:on 311 312}