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.datepicker.client.ui.base; 017 018import java.util.Date; 019 020import com.github.gwtbootstrap.client.ui.TextBox; 021import com.github.gwtbootstrap.client.ui.base.HasAlternateSize; 022import com.github.gwtbootstrap.client.ui.base.HasId; 023import com.github.gwtbootstrap.client.ui.base.HasPlaceholder; 024import com.github.gwtbootstrap.client.ui.base.HasSize; 025import com.github.gwtbootstrap.client.ui.base.HasStyle; 026import com.github.gwtbootstrap.client.ui.base.HasVisibility; 027import com.github.gwtbootstrap.client.ui.base.HasVisibleHandlers; 028import com.github.gwtbootstrap.client.ui.base.IsResponsive; 029import com.github.gwtbootstrap.client.ui.base.IsSearchQuery; 030import com.github.gwtbootstrap.client.ui.base.PlaceholderHelper; 031import com.github.gwtbootstrap.client.ui.base.ResponsiveHelper; 032import com.github.gwtbootstrap.client.ui.base.SearchQueryStyleHelper; 033import com.github.gwtbootstrap.client.ui.base.SizeHelper; 034import com.github.gwtbootstrap.client.ui.base.Style; 035import com.github.gwtbootstrap.client.ui.base.StyleHelper; 036import com.github.gwtbootstrap.client.ui.constants.AlternateSize; 037import com.github.gwtbootstrap.client.ui.constants.Device; 038import com.github.gwtbootstrap.client.ui.event.HiddenHandler; 039import com.github.gwtbootstrap.client.ui.event.HideEvent; 040import com.github.gwtbootstrap.client.ui.event.HideHandler; 041import com.github.gwtbootstrap.client.ui.event.ShowEvent; 042import com.github.gwtbootstrap.client.ui.event.ShowHandler; 043import com.github.gwtbootstrap.client.ui.event.ShownHandler; 044import com.github.gwtbootstrap.datepicker.client.ui.util.LocaleUtil; 045import com.google.gwt.core.client.GWT; 046import com.google.gwt.dom.client.Element; 047import com.google.gwt.editor.client.IsEditor; 048import com.google.gwt.editor.client.adapters.TakesValueEditor; 049import com.google.gwt.event.dom.client.ChangeEvent; 050import com.google.gwt.event.dom.client.ChangeHandler; 051import com.google.gwt.event.dom.client.HasChangeHandlers; 052import com.google.gwt.event.logical.shared.HasValueChangeHandlers; 053import com.google.gwt.event.logical.shared.ValueChangeEvent; 054import com.google.gwt.event.logical.shared.ValueChangeHandler; 055import com.google.gwt.event.shared.HandlerRegistration; 056import com.google.gwt.i18n.client.DateTimeFormat; 057import com.google.gwt.i18n.client.LocaleInfo; 058import com.google.gwt.user.client.Event; 059import com.google.gwt.user.client.ui.HasEnabled; 060import com.google.gwt.user.client.ui.HasValue; 061import com.google.gwt.user.client.ui.ValueBoxBase.TextAlignment; 062import com.google.gwt.user.client.ui.Widget; 063 064/** 065 * Base DatePicker component. 066 * 067 * @author Carlos Alexandro Becker 068 * @author ohashi keisuke 069 * @since 2.0.4.0 070 */ 071public class DateBoxBase extends Widget implements HasValue<Date>,HasEnabled, HasValueChangeHandlers<Date>, HasVisibility, 072 HasChangeHandlers, HasVisibleHandlers, HasAllDatePickerHandlers, IsEditor<TakesValueEditor<Date>>, HasPlaceholder, HasAlternateSize, IsSearchQuery, HasSize, HasId, IsResponsive , HasStyle { 073 074 private final TextBox box; 075 private String format; 076 private String language; 077 private DateTimeFormat dtf; 078 private TakesValueEditor<Date> editor; 079 080 /** placeholderHelper */ 081 private PlaceholderHelper placeholderHelper = GWT.create(PlaceholderHelper.class); 082 private boolean autoclose = false; 083 084 public DateBoxBase() { 085 this.box = new TextBox(); 086 this.language = LocaleUtil.getLanguage(); 087 setElement(box.getElement()); 088 setFormat(DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.DATE_SHORT).getPattern().toLowerCase()); 089 setWeekStart(LocaleInfo.getCurrentLocale().getDateTimeFormatInfo().firstDayOfTheWeek()); 090 setValue(new Date()); 091 } 092 093 public void setAlignment(TextAlignment align) { 094 box.setAlignment(align); 095 } 096 097 /** 098 * @see com.google.gwt.user.client.ui.ValueBoxBase#isReadOnly() 099 */ 100 public boolean isReadOnly() { 101 return box.isReadOnly(); 102 } 103 104 /** 105 * @see com.google.gwt.user.client.ui.ValueBoxBase#setReadOnly(boolean) 106 */ 107 public void setReadOnly(boolean readonly) { 108 box.setReadOnly(readonly); 109 } 110 111 /** 112 * {@inheritDoc} 113 */ 114 @Override 115 public void setFormat(String format) { 116 this.format = format; 117 Date oldValue = getValue(); 118 this.dtf = DateTimeFormat.getFormat(format.replaceAll("mm", "MM")); 119 if (oldValue != null) { 120 setValue(oldValue); 121 } 122 } 123 124 public void setLanguage(String language) { 125 this.language = language; 126 LocaleUtil.forceLocale(language); 127 } 128 129 /** 130 * Returns the internal instance of textbox element. Use only if know what you are doing. 131 * 132 * @return internal textbox intance. 133 */ 134 protected TextBox getBox() { 135 return box; 136 } 137 138 /** 139 * {@inheritDoc} 140 */ 141 @Override 142 public Date getValue() { 143 try { 144 return dtf != null && box.getValue() != null ? dtf.parse(box.getValue()) : null; 145 } catch(Exception e) { 146 return null; 147 } 148 } 149 150 /** 151 * Get un-tranceform text 152 * @return text box value 153 */ 154 public String getOriginalValue() { 155 return box.getValue(); 156 } 157 158 /** 159 * {@inheritDoc} 160 */ 161 @Override 162 public void setValue(Date value) { 163 setValue(value, false); 164 } 165 166 /** 167 * {@inheritDoc} 168 */ 169 @Override 170 public void setValue(Date value, boolean fireEvents) { 171 box.setValue(value != null ? dtf.format(value) : null); 172 173 updateValue(box.getElement()); 174 175 if (fireEvents) { 176 ValueChangeEvent.fire(this, value); 177 } 178 } 179 180 protected native void updateValue(Element e)/*-{ 181 if($wnd.jQuery(e).data('datepicker')) { 182 $wnd.jQuery(e).data('datepicker').update(); 183 } 184 }-*/; 185 186 /** 187 * {@inheritDoc} 188 */ 189 @Override 190 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Date> dateValueChangeHandler) { 191 return addHandler(dateValueChangeHandler, ValueChangeEvent.getType()); 192 } 193 194 /** 195 * {@inheritDoc} 196 */ 197 @Override 198 protected void onLoad() { 199 super.onLoad(); 200 configure(); 201 } 202 203 /** 204 * Configure the elements for a specific widget. 205 * Use only if you know what you are doing. 206 * 207 * @param w: the widget to configure. 208 */ 209 protected void configure(Widget w) { 210 w.getElement().setAttribute("data-date-format", format); 211 w.getElement().setAttribute("data-date-language", language); 212 configure(w.getElement(), autoclose); 213 } 214 215 /** 216 * dateChange event handler. 217 */ 218 public void onChange() { 219 ValueChangeEvent.fire(this, getValue()); 220 } 221 222 public void onShow(Event e) { 223 fireEvent(new ShowEvent(e)); 224 } 225 226 public void onHide(Event e) { 227 fireEvent(new HideEvent(e)); 228 } 229 public void reconfigure() { 230 removeDataIfExists(getElement()); 231 configure(); 232 } 233 234 /** 235 * configure this datepicker. 236 */ 237 protected void configure() { 238 configure(this); 239 } 240 241 protected native void removeDataIfExists(Element e) /*-{ 242 var $that = $wnd.jQuery(e); 243 if($that.data('datepicker')) { 244 console.log($that.data()); 245 $that.removeData('dateFormat'); 246 $that.removeData('dateLanguage'); 247 $that.removeData('dateWeekstart'); 248 $that.removeData('dateStartdate'); 249 $that.removeData('dateEnddate'); 250 $that.removeData('dateStartView'); 251 $that.removeData('datepicker'); 252 $that.off(); 253 } 254 }-*/; 255 256 /** 257 * call jquery datepicker plugin in a element. 258 * 259 * @param e: Element that will be transformed in a datepicker. 260 * @param autoclose is autoclose? 261 */ 262 protected native void configure(Element e, boolean autoclose) /*-{ 263 var that = this; 264 $wnd.jQuery(e).datepicker({autoclose : autoclose}) 265 .on('change' , function() { 266 that.@com.github.gwtbootstrap.datepicker.client.ui.base.DateBoxBase::onChange()(); 267 }) 268 .on("show", function (e) { 269 that.@com.github.gwtbootstrap.datepicker.client.ui.base.DateBoxBase::onShow(Lcom/google/gwt/user/client/Event;)(e); 270 }) 271 .on("hide", function (e) { 272 that.@com.github.gwtbootstrap.datepicker.client.ui.base.DateBoxBase::onHide(Lcom/google/gwt/user/client/Event;)(e); 273 }); 274 }-*/; 275 276 private native void execute(Element e, String cmd) /*-{ 277 $wnd.jQuery(e).datepicker(cmd); 278 }-*/; 279 280 private void execute(String cmd) { 281 execute(getElement(), cmd); 282 } 283 284 /** 285 * {@inheritDoc} 286 */ 287 @Override 288 public void show() { 289 execute("show"); 290 } 291 292 /** 293 * {@inheritDoc} 294 */ 295 @Override 296 public void hide() { 297 execute("hide"); 298 } 299 300 /** 301 * {@inheritDoc} 302 */ 303 @Override 304 public void toggle() { 305 //TODO 2012/06/21 ohashi keisuke shoud be support 306 throw new UnsupportedOperationException("not support toggle"); 307 } 308 309 /** 310 * {@inheritDoc} 311 */ 312 @Override 313 public HandlerRegistration addHideHandler(HideHandler handler) { 314 return addHandler(handler, HideEvent.getType()); 315 } 316 317 /** 318 * {@inheritDoc} 319 */ 320 @Override 321 public HandlerRegistration addHiddenHandler(HiddenHandler handler) { 322 //TODO 2012/06/21 ohashi keisuke shoud be support 323 throw new UnsupportedOperationException("not support hidden event"); 324 } 325 326 /** 327 * {@inheritDoc} 328 */ 329 @Override 330 public HandlerRegistration addShowHandler(ShowHandler handler) { 331 return addHandler(handler, ShowEvent.getType()); 332 } 333 334 /** 335 * {@inheritDoc} 336 */ 337 @Override 338 public HandlerRegistration addShownHandler(ShownHandler handler) { 339 //TODO 2012/06/21 ohashi keisuke shoud be support 340 throw new UnsupportedOperationException("not support shown event"); 341 } 342 343 /** 344 * {@inheritDoc} 345 */ 346 @Override 347 public void setWeekStart(int start) { 348 getElement().setAttribute("data-date-weekstart", start + ""); 349 } 350 351 /** 352 * {@inheritDoc} 353 */ 354 @Override 355 public void setStartDate(String startDate) { 356 getElement().setAttribute("data-date-startdate", startDate); 357 } 358 359 /** 360 * {@inheritDoc} 361 */ 362 @Override 363 public void setStartDate_(Date startDate) { 364 setStartDate(dtf.format(startDate)); 365 } 366 367 368 /** 369 * {@inheritDoc} 370 */ 371 @Override 372 public void setEndDate(String endDate) { 373 getElement().setAttribute("data-date-enddate", endDate); 374 } 375 376 /** 377 * {@inheritDoc} 378 */ 379 @Override 380 public void setEndDate_(Date endDate) { 381 setEndDate(dtf.format(endDate)); 382 } 383 384 /** 385 * {@inheritDoc} 386 */ 387 @Override 388 public void setAutoClose(boolean autoclose) { 389 this.autoclose = autoclose; 390 } 391 392 /** 393 * {@inheritDoc} 394 */ 395 @Override 396 public void setStartView(ViewMode mode) { 397 setStartView(mode.name()); 398 } 399 400 /** 401 * {@inheritDoc} 402 */ 403 @Override 404 public void setStartView(String mode) { 405 getElement().setAttribute("data-date-start-view", mode.toLowerCase()); 406 } 407 408 /** 409 * Retuen Editor 410 * @return editor 411 */ 412 @Override 413 public TakesValueEditor<Date> asEditor() { 414 if(editor == null){ 415 editor = TakesValueEditor.of(this); 416 } 417 return editor; 418 } 419 420 @Override 421 public HandlerRegistration addChangeHandler(ChangeHandler handler) { 422 return addHandler(handler, ChangeEvent.getType()); 423 } 424 425 /** 426 * {@inheritDoc} 427 */ 428 @Override 429 public void setPlaceholder(String placeholder) { 430 placeholderHelper.setPlaceholer(getElement(), placeholder); 431 } 432 433 /** 434 * {@inheritDoc} 435 */ 436 @Override 437 public String getPlaceholder() { 438 return placeholderHelper.getPlaceholder(getElement()); 439 } 440 441 /** 442 * {@inheritDoc} 443 */ 444 @Override 445 public void setSearchQuery(boolean searchQuery) { 446 SearchQueryStyleHelper.setSearchQuery(this, searchQuery); 447 } 448 449 /** 450 * {@inheritDoc} 451 */ 452 @Override 453 public boolean isSearchQuery() { 454 return SearchQueryStyleHelper.isSearchQuery(this); 455 } 456 457 /** 458 * {@inheritDoc} 459 */ 460 @Override 461 public void setAlternateSize(AlternateSize size) { 462 StyleHelper.changeStyle(this, size, AlternateSize.class); 463 } 464 465 /** 466 * {@inheritDoc} 467 */ 468 @Override 469 public void setSize(int size) { 470 SizeHelper.setSize(this, size); 471 } 472 473 /** 474 * {@inheritDoc} 475 */ 476 @Override 477 public String getId() { 478 return getElement().getId(); 479 } 480 481 /** 482 * {@inheritDoc} 483 */ 484 @Override 485 public void setId(String id) { 486 getElement().setId(id); 487 } 488 489 /** 490 * {@inheritDoc} 491 */ 492 @Override 493 public void setShowOn(Device device) { 494 ResponsiveHelper.setShowOn(this, device); 495 } 496 497 /** 498 * {@inheritDoc} 499 */ 500 @Override 501 public void setHideOn(Device device) { 502 ResponsiveHelper.setHideOn(this, device); 503 504 } 505 506 /** 507 * {@inheritDoc} 508 */ 509 @Override 510 public void setStyle(Style style) { 511 StyleHelper.setStyle(this, style); 512 } 513 514 /** 515 * {@inheritDoc} 516 */ 517 @Override 518 public void addStyle(Style style) { 519 StyleHelper.addStyle(this, style); 520 } 521 522 /** 523 * {@inheritDoc} 524 */ 525 @Override 526 public void removeStyle(Style style) { 527 StyleHelper.removeStyle(this, style); 528 529 } 530 531 /** 532 * {@inheritDoc} 533 */ 534 @Override 535 public boolean isEnabled() { 536 return false; 537 } 538 539 /** 540 * {@inheritDoc} 541 */ 542 @Override 543 public void setEnabled(boolean enabled) { 544 box.setEnabled(enabled); 545 } 546}