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