001package org.gwtbootstrap3.extras.datetimepicker.client.ui.base; 002 003/* 004 * #%L 005 * GwtBootstrap3 006 * %% 007 * Copyright (C) 2016 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 023import java.util.Date; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Map; 027 028import org.gwtbootstrap3.client.shared.event.HideEvent; 029import org.gwtbootstrap3.client.shared.event.HideHandler; 030import org.gwtbootstrap3.client.shared.event.ShowEvent; 031import org.gwtbootstrap3.client.shared.event.ShowHandler; 032import org.gwtbootstrap3.client.ui.TextBox; 033import org.gwtbootstrap3.client.ui.base.HasId; 034import org.gwtbootstrap3.client.ui.base.HasPlaceholder; 035import org.gwtbootstrap3.client.ui.base.HasReadOnly; 036import org.gwtbootstrap3.client.ui.base.HasResponsiveness; 037import org.gwtbootstrap3.client.ui.base.ValueBoxBase; 038import org.gwtbootstrap3.client.ui.base.helper.StyleHelper; 039import org.gwtbootstrap3.client.ui.base.mixin.BlankValidatorMixin; 040import org.gwtbootstrap3.client.ui.base.mixin.ErrorHandlerMixin; 041import org.gwtbootstrap3.client.ui.constants.DeviceSize; 042import org.gwtbootstrap3.client.ui.form.error.ErrorHandler; 043import org.gwtbootstrap3.client.ui.form.error.ErrorHandlerType; 044import org.gwtbootstrap3.client.ui.form.error.HasErrorHandler; 045import org.gwtbootstrap3.client.ui.form.validator.HasBlankValidator; 046import org.gwtbootstrap3.client.ui.form.validator.HasValidators; 047import org.gwtbootstrap3.client.ui.form.validator.ValidationChangedEvent.ValidationChangedHandler; 048import org.gwtbootstrap3.client.ui.form.validator.Validator; 049import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.DateTimePickerDayOfWeek; 050import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.DateTimePickerFormatViewType; 051import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.DateTimePickerLanguage; 052import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.DateTimePickerPosition; 053import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.DateTimePickerView; 054import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasAutoClose; 055import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasDateTimePickerHandlers; 056import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasDaysOfWeekDisabled; 057import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasEndDate; 058import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasForceParse; 059import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasFormat; 060import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasHighlightToday; 061import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasKeyboardNavigation; 062import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasLanguage; 063import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasMaxView; 064import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasMinView; 065import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasMinuteStep; 066import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasPosition; 067import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasShowMeridian; 068import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasShowTodayButton; 069import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasStartDate; 070import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasStartView; 071import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasViewSelect; 072import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.constants.HasWeekStart; 073import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.events.ChangeDateEvent; 074import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.events.ChangeDateHandler; 075import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.events.ChangeMonthEvent; 076import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.events.ChangeMonthHandler; 077import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.events.ChangeYearEvent; 078import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.events.ChangeYearHandler; 079import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.events.OutOfRangeEvent; 080import org.gwtbootstrap3.extras.datetimepicker.client.ui.base.events.OutOfRangeHandler; 081 082import com.google.gwt.core.client.ScriptInjector; 083import com.google.gwt.dom.client.Element; 084import com.google.gwt.editor.client.EditorError; 085import com.google.gwt.editor.client.HasEditorErrors; 086import com.google.gwt.editor.client.LeafValueEditor; 087import com.google.gwt.event.dom.client.BlurEvent; 088import com.google.gwt.event.dom.client.BlurHandler; 089import com.google.gwt.event.logical.shared.ValueChangeEvent; 090import com.google.gwt.event.logical.shared.ValueChangeHandler; 091import com.google.gwt.event.shared.HandlerRegistration; 092import com.google.gwt.i18n.client.DateTimeFormat; 093import com.google.gwt.user.client.Event; 094import com.google.gwt.user.client.ui.HasEnabled; 095import com.google.gwt.user.client.ui.HasName; 096import com.google.gwt.user.client.ui.HasValue; 097import com.google.gwt.user.client.ui.HasVisibility; 098import com.google.gwt.user.client.ui.Widget; 099 100/** 101 * @author Joshua Godi 102 * @author Steven Jardine 103 */ 104public class DateTimePickerBase extends Widget implements HasEnabled, HasReadOnly, HasId, HasResponsiveness, HasVisibility, 105 HasPlaceholder, HasAutoClose, HasDaysOfWeekDisabled, HasEndDate, HasForceParse, HasFormat, HasHighlightToday, 106 HasKeyboardNavigation, HasMaxView, HasMinuteStep, HasMinView, HasShowMeridian, HasShowTodayButton, HasStartDate, 107 HasStartView, HasViewSelect, HasWeekStart, HasDateTimePickerHandlers, HasLanguage, HasName, HasValue<Date>, HasPosition, 108 LeafValueEditor<Date>, HasEditorErrors<Date>, HasErrorHandler, HasValidators<Date>, HasBlankValidator<Date> { 109 110 static class DatePickerValidatorMixin extends BlankValidatorMixin<DateTimePickerBase, Date> { 111 112 private boolean showing = false; 113 114 public void setShowing(boolean showing) { 115 this.showing = showing; 116 } 117 118 public DatePickerValidatorMixin(DateTimePickerBase inputWidget, ErrorHandler errorHandler) { 119 super(inputWidget, errorHandler); 120 } 121 122 @Override 123 protected com.google.web.bindery.event.shared.HandlerRegistration setupBlurValidation() { 124 return getInputWidget().addDomHandler(new BlurHandler() { 125 @Override 126 public void onBlur(BlurEvent event) { 127 getInputWidget().validate(!showing && getValidateOnBlur()); 128 } 129 }, BlurEvent.getType()); 130 } 131 132 } 133 134 // Check http://www.gwtproject.org/javadoc/latest/com/google/gwt/i18n/client/DateTimeFormat.html 135 // for more information on syntax 136 private static final Map<Character, Character> DATE_TIME_FORMAT_MAP = new HashMap<Character, Character>(); 137 static { 138 DATE_TIME_FORMAT_MAP.put('h', 'H'); // 12/24 hours 139 DATE_TIME_FORMAT_MAP.put('H', 'h'); // 12/24 hours 140 DATE_TIME_FORMAT_MAP.put('m', 'M'); // months 141 DATE_TIME_FORMAT_MAP.put('i', 'm'); // minutes 142 DATE_TIME_FORMAT_MAP.put('p', 'a'); // meridian 143 DATE_TIME_FORMAT_MAP.put('P', 'a'); // meridian 144 } 145 146 private final TextBox textBox; 147 private DateTimeFormat dateTimeFormat; 148 private final DateTimeFormat startEndDateFormat = DateTimeFormat.getFormat("yyyy-MM-dd"); 149 private LeafValueEditor<Date> editor; 150 private final ErrorHandlerMixin<Date> errorHandlerMixin = new ErrorHandlerMixin<Date>(this); 151 private final DatePickerValidatorMixin validatorMixin = new DatePickerValidatorMixin(this, 152 errorHandlerMixin.getErrorHandler()); 153 154 /** 155 * DEFAULT values 156 */ 157 private String format = "mm/dd/yyyy hh:ii"; 158 private DateTimePickerFormatViewType formatViewType = DateTimePickerFormatViewType.DATE_TIME; 159 private DateTimePickerDayOfWeek weekStart = DateTimePickerDayOfWeek.SUNDAY; 160 private DateTimePickerDayOfWeek[] daysOfWeekDisabled = {}; 161 private boolean autoClose = false; 162 private DateTimePickerView startView = DateTimePickerView.MONTH; 163 private DateTimePickerView minView = DateTimePickerView.HOUR; 164 private DateTimePickerView maxView = DateTimePickerView.DECADE; 165 private boolean showTodayButton = false; 166 private boolean highlightToday = false; 167 private boolean keyboardNavigation = true; 168 private boolean forceParse = true; 169 private int minuteStep = 5; 170 private DateTimePickerView viewSelect = DateTimePickerView.HOUR; 171 private boolean showMeridian = false; 172 private DateTimePickerLanguage language = DateTimePickerLanguage.EN; 173 private DateTimePickerPosition position = DateTimePickerPosition.BOTTOM_RIGHT; 174 175 public DateTimePickerBase() { 176 textBox = new TextBox(); 177 setElement((Element) textBox.getElement()); 178 setFormat(format); 179 } 180 181 public TextBox getTextBox() { 182 return textBox; 183 } 184 185 public void setAlignment(final ValueBoxBase.TextAlignment align) { 186 textBox.setAlignment(align); 187 } 188 189 /** {@inheritDoc} */ 190 @Override 191 public void setPlaceholder(final String placeHolder) { 192 textBox.setPlaceholder(placeHolder); 193 } 194 195 /** {@inheritDoc} */ 196 @Override 197 public String getPlaceholder() { 198 return textBox.getPlaceholder(); 199 } 200 201 public void setReadOnly(final boolean readOnly) { 202 textBox.setReadOnly(readOnly); 203 } 204 205 public boolean isReadOnly() { 206 return textBox.isReadOnly(); 207 } 208 209 210 /** {@inheritDoc} */ 211 @Override 212 public boolean isEnabled() { 213 return textBox.isEnabled(); 214 } 215 216 /** {@inheritDoc} */ 217 @Override 218 public void setEnabled(final boolean enabled) { 219 textBox.setEnabled(enabled); 220 } 221 222 /** {@inheritDoc} */ 223 @Override 224 public void setId(final String id) { 225 textBox.setId(id); 226 } 227 228 /** {@inheritDoc} */ 229 @Override 230 public String getId() { 231 return textBox.getId(); 232 } 233 234 /** {@inheritDoc} */ 235 @Override 236 public void setName(final String name) { 237 textBox.setName(name); 238 } 239 240 /** {@inheritDoc} */ 241 @Override 242 public String getName() { 243 return textBox.getName(); 244 } 245 246 /** {@inheritDoc} */ 247 @Override 248 public void setVisibleOn(final DeviceSize deviceSize) { 249 StyleHelper.setVisibleOn(this, deviceSize); 250 } 251 252 /** {@inheritDoc} */ 253 @Override 254 public void setHiddenOn(final DeviceSize deviceSize) { 255 StyleHelper.setHiddenOn(this, deviceSize); 256 } 257 258 /** {@inheritDoc} */ 259 @Override 260 public void setLanguage(final DateTimePickerLanguage language) { 261 this.language = language; 262 263 // Inject the JS for the language 264 if (language.getJs() != null) { 265 ScriptInjector.fromString(language.getJs().getText()) 266 .setWindow(ScriptInjector.TOP_WINDOW).inject(); 267 } 268 } 269 270 /** {@inheritDoc} */ 271 @Override 272 public DateTimePickerLanguage getLanguage() { 273 return language; 274 } 275 276 /** {@inheritDoc} */ 277 @Override 278 public void setPosition(final DateTimePickerPosition position) { 279 this.position = position; 280 } 281 282 /** {@inheritDoc} */ 283 @Override 284 public DateTimePickerPosition getPosition() { 285 return position; 286 } 287 288 /** 289 * Call this whenever changing any settings: minView, startView, format, etc. If you are changing 290 * format and date value, the updates must take in such order: 291 * <p/> 292 * 1. DateTimePicker.reload() 293 * 2. DateTimePicker.setValue(newDate); // Date newDate. 294 * <p/> 295 * Otherwise date value is not updated. 296 */ 297 public void reload() { 298 configure(); 299 } 300 301 public void show() { 302 show(getElement()); 303 } 304 305 public void hide() { 306 hide(getElement()); 307 } 308 309 /** {@inheritDoc} */ 310 @Override 311 public void setAutoClose(final boolean autoClose) { 312 this.autoClose = autoClose; 313 } 314 315 /** {@inheritDoc} */ 316 @Override 317 public void onShow(final Event e) { 318 validatorMixin.setShowing(true); 319 fireEvent(new ShowEvent(e)); 320 } 321 322 /** {@inheritDoc} */ 323 @Override 324 public HandlerRegistration addShowHandler(final ShowHandler showHandler) { 325 return addHandler(showHandler, ShowEvent.getType()); 326 } 327 328 /** {@inheritDoc} */ 329 @Override 330 public void onHide(final Event e) { 331 validatorMixin.setShowing(false); 332 validate(getValidateOnBlur()); 333 fireEvent(new HideEvent(e)); 334 } 335 336 /** {@inheritDoc} */ 337 @Override 338 public HandlerRegistration addHideHandler(final HideHandler hideHandler) { 339 return addHandler(hideHandler, HideEvent.getType()); 340 } 341 342 /** {@inheritDoc} */ 343 @Override 344 public void onChangeDate(final Event e) { 345 fireEvent(new ChangeDateEvent(e)); 346 ValueChangeEvent.fire(DateTimePickerBase.this, getValue()); 347 hide(); 348 } 349 350 /** {@inheritDoc} */ 351 @Override 352 public HandlerRegistration addChangeDateHandler(final ChangeDateHandler changeDateHandler) { 353 return addHandler(changeDateHandler, ChangeDateEvent.getType()); 354 } 355 356 /** {@inheritDoc} */ 357 @Override 358 public void onChangeYear(final Event e) { 359 fireEvent(new ChangeYearEvent(e)); 360 } 361 362 /** {@inheritDoc} */ 363 @Override 364 public HandlerRegistration addChangeYearHandler(final ChangeYearHandler changeYearHandler) { 365 return addHandler(changeYearHandler, ChangeYearEvent.getType()); 366 } 367 368 /** {@inheritDoc} */ 369 @Override 370 public void onChangeMonth(final Event e) { 371 fireEvent(new ChangeMonthEvent(e)); 372 } 373 374 /** {@inheritDoc} */ 375 @Override 376 public HandlerRegistration addChangeMonthHandler(final ChangeMonthHandler changeMonthHandler) { 377 return addHandler(changeMonthHandler, ChangeMonthEvent.getType()); 378 } 379 380 /** {@inheritDoc} */ 381 @Override 382 public void onOutOfRange(final Event e) { 383 fireEvent(new OutOfRangeEvent(e)); 384 } 385 386 /** {@inheritDoc} */ 387 @Override 388 public HandlerRegistration addOutOfRangeHandler(final OutOfRangeHandler outOfRangeHandler) { 389 return addHandler(outOfRangeHandler, OutOfRangeEvent.getType()); 390 } 391 392 /** {@inheritDoc} */ 393 @Override 394 public void setDaysOfWeekDisabled(final DateTimePickerDayOfWeek... daysOfWeekDisabled) { 395 setDaysOfWeekDisabled(getElement(), toDaysOfWeekDisabledString(daysOfWeekDisabled)); 396 } 397 398 /** {@inheritDoc} */ 399 @Override 400 public void setEndDate(final Date endDate) { 401 // Has to be in the format YYYY-MM-DD 402 setEndDate(startEndDateFormat.format(endDate)); 403 } 404 405 /** {@inheritDoc} */ 406 @Override 407 public void setEndDate(final String endDate) { 408 // Has to be in the format YYYY-MM-DD 409 setEndDate(getElement(), endDate); 410 } 411 412 /** {@inheritDoc} */ 413 @Override 414 public void clearEndDate() { 415 setStartDate(getElement(), null); 416 } 417 418 /** {@inheritDoc} */ 419 @Override 420 public void setForceParse(final boolean forceParse) { 421 this.forceParse = forceParse; 422 } 423 424 /** {@inheritDoc} */ 425 @Override 426 public void setHighlightToday(final boolean highlightToday) { 427 this.highlightToday = highlightToday; 428 } 429 430 /** {@inheritDoc} */ 431 @Override 432 public void setHasKeyboardNavigation(final boolean hasKeyboardNavigation) { 433 this.keyboardNavigation = hasKeyboardNavigation; 434 } 435 436 /** {@inheritDoc} */ 437 @Override 438 public void setMaxView(final DateTimePickerView dateTimePickerView) { 439 this.maxView = dateTimePickerView; 440 } 441 442 /** {@inheritDoc} */ 443 @Override 444 public void setMinView(final DateTimePickerView dateTimePickerView) { 445 this.minView = dateTimePickerView; 446 447 // We keep the view select the same as the min view 448 if (viewSelect != minView) { 449 setViewSelect(dateTimePickerView); 450 } 451 } 452 453 /** {@inheritDoc} */ 454 @Override 455 public void setMinuteStep(final int minuteStep) { 456 this.minuteStep = minuteStep; 457 } 458 459 /** {@inheritDoc} */ 460 @Override 461 public void setShowMeridian(final boolean showMeridian) { 462 this.showMeridian = showMeridian; 463 } 464 465 /** {@inheritDoc} */ 466 @Override 467 public void setShowTodayButton(final boolean showTodayButton) { 468 this.showTodayButton = showTodayButton; 469 } 470 471 /** {@inheritDoc} */ 472 @Override 473 public void setStartDate(final Date startDate) { 474 // Has to be in the format YYYY-MM-DD 475 setStartDate(startEndDateFormat.format(startDate)); 476 } 477 478 /** {@inheritDoc} */ 479 @Override 480 public void setStartDate(final String startDate) { 481 // Has to be in the format YYYY-MM-DD 482 setStartDate(getElement(), startDate); 483 } 484 485 /** {@inheritDoc} */ 486 @Override 487 public void clearStartDate() { 488 setStartDate(getElement(), null); 489 } 490 491 /** {@inheritDoc} */ 492 @Override 493 public void setStartView(final DateTimePickerView dateTimePickerView) { 494 this.startView = dateTimePickerView; 495 } 496 497 /** {@inheritDoc} */ 498 @Override 499 public void setViewSelect(final DateTimePickerView dateTimePickerView) { 500 this.viewSelect = dateTimePickerView; 501 502 // We keep the min view the same as the view select 503 if (viewSelect != minView) { 504 setMinView(dateTimePickerView); 505 } 506 } 507 508 /** {@inheritDoc} */ 509 @Override 510 public void setWeekStart(final DateTimePickerDayOfWeek weekStart) { 511 this.weekStart = weekStart; 512 } 513 514 /** 515 * Convert GWT date time format to bootstrap date time format 516 * 517 * @param format date time format using GWT notation 518 * @return date time format using bootstrap notation 519 */ 520 private static String toBootstrapDateFormat(final String format) { 521 String bootstrap_format = format; 522 523 // Replace long day name "EEEE" with "DD" 524 bootstrap_format = bootstrap_format.replace("EEEE", "DD"); 525 // Replace short day name "EE" with "DD" 526 bootstrap_format = bootstrap_format.replaceAll("E{1,3}", "D"); 527 // Replace minutes "m" with "i" 528 bootstrap_format = bootstrap_format.replaceAll("m", "i"); 529 // Replace "H" with "h" and vice versa 530 bootstrap_format = bootstrap_format.replaceAll("H", "Q"); 531 bootstrap_format = bootstrap_format.replaceAll("h", "H"); 532 bootstrap_format = bootstrap_format.replaceAll("Q", "h"); 533 // Replace "a" with "P" for AM/PM markers 534 bootstrap_format = bootstrap_format.replaceAll("a", "P"); 535 536 // If there are at least 3 Ms there is month name in wording 537 if (bootstrap_format.contains("MMM")) { 538 // Replace long date month "MMMM" with "MM" 539 bootstrap_format = bootstrap_format.replace("MMMM", "MM"); 540 // Replace month name "MMM" with "M" 541 bootstrap_format = bootstrap_format.replace("MMM", "M"); 542 } 543 else { 544 // Replace month number with leading 0 "MM" with "mm" 545 bootstrap_format = bootstrap_format.replace("MM", "mm"); 546 // Replace month number "M" with "m" 547 bootstrap_format = bootstrap_format.replace("M", "m"); 548 } 549 if (!bootstrap_format.contains("yy")) { 550 // Replace full year format "y" with "yyyy" 551 bootstrap_format = bootstrap_format.replace("y", "yyyy"); 552 } 553 554 return bootstrap_format; 555 } 556 557 /** 558 * Sets format of the date using GWT notation 559 * 560 * @param format date time format in GWT notation 561 */ 562 public void setGWTFormat(final String format) { 563 this.format = toBootstrapDateFormat(format); 564 565 // Get the old value 566 final Date oldValue = getValue(); 567 568 // Make the new DateTimeFormat 569 this.dateTimeFormat = DateTimeFormat.getFormat(format); 570 571 if (oldValue != null) { 572 setValue(oldValue); 573 } 574 } 575 576 /** {@inheritDoc} */ 577 @Override 578 public void setFormat(final String format) { 579 this.format = format; 580 581 // Get the old value 582 final Date oldValue = getValue(); 583 584 // Make the new DateTimeFormat 585 setDateTimeFormat(format); 586 587 if (oldValue != null) { 588 setValue(oldValue); 589 } 590 } 591 592 private void setDateTimeFormat(final String format) { 593 final StringBuilder fb = new StringBuilder(format); 594 for (int i = 0; i < fb.length(); i++) { 595 if (DATE_TIME_FORMAT_MAP.containsKey(fb.charAt(i))) { 596 fb.setCharAt(i, DATE_TIME_FORMAT_MAP.get(fb.charAt(i))); 597 } 598 } 599 600 this.dateTimeFormat = DateTimeFormat.getFormat(fb.toString()); 601 } 602 603 /** 604 * Sets the format view type. 605 * 606 * @param formatViewType 607 * @see DateTimePickerFormatViewType 608 */ 609 public void setFormatViewType(DateTimePickerFormatViewType formatViewType) { 610 if (formatViewType != null) 611 this.formatViewType = formatViewType; 612 } 613 614 /** {@inheritDoc} */ 615 @Override 616 public Date getValue() { 617 try { 618 return dateTimeFormat != null && textBox.getValue() != null ? dateTimeFormat.parse(textBox.getValue()) : null; 619 } catch (final Exception e) { 620 return null; 621 } 622 } 623 624 public String getBaseValue() { 625 return textBox.getValue(); 626 } 627 628 /** {@inheritDoc} */ 629 @Override 630 public HandlerRegistration addValueChangeHandler(final ValueChangeHandler<Date> dateValueChangeHandler) { 631 textBox.addValueChangeHandler(new ValueChangeHandler<String>() { 632 @Override 633 public void onValueChange(ValueChangeEvent<String> event) { 634 ValueChangeEvent.fire(DateTimePickerBase.this, getValue()); 635 } 636 }); 637 return addHandler(dateValueChangeHandler, ValueChangeEvent.getType()); 638 } 639 640 /** {@inheritDoc} */ 641 @Override 642 public void setValue(final Date value) { 643 setValue(value, false); 644 } 645 646 /** {@inheritDoc} */ 647 @Override 648 public void setValue(final Date value, final boolean fireEvents) { 649 errorHandlerMixin.clearErrors(); 650 textBox.setValue(value != null ? dateTimeFormat.format(value) : null); 651 update(textBox.getElement()); 652 653 if (fireEvents) { 654 ValueChangeEvent.fire(DateTimePickerBase.this, value); 655 } 656 } 657 658 /** {@inheritDoc} */ 659 @Override 660 protected void onLoad() { 661 super.onLoad(); 662 configure(); 663 } 664 665 /** {@inheritDoc} */ 666 @Override 667 protected void onUnload() { 668 super.onUnload(); 669 remove(getElement()); 670 } 671 672 protected void configure() { 673 getElement().setAttribute("data-date-format", format); 674 675 // If configuring not for the first time, datetimepicker must be removed first. 676 this.remove(getElement()); 677 678 configure(getElement(), format, formatViewType.getValue(), weekStart.getValue(), toDaysOfWeekDisabledString(daysOfWeekDisabled), 679 autoClose, startView.getValue(), minView.getValue(), maxView.getValue(), showTodayButton, highlightToday, 680 keyboardNavigation, forceParse, minuteStep, viewSelect.getValue(), showMeridian, language.getCode(), position.getPosition()); 681 } 682 683 protected void execute(final String cmd) { 684 execute(getElement(), cmd); 685 } 686 687 private native void execute(Element e, String cmd) /*-{ 688 $wnd.jQuery(e).datetimepicker(cmd); 689 }-*/; 690 691 private native void remove(Element e) /*-{ 692 $wnd.jQuery(e).datetimepicker('remove'); 693 }-*/; 694 695 private native void show(Element e) /*-{ 696 $wnd.jQuery(e).datetimepicker('show'); 697 }-*/; 698 699 private native void hide(Element e) /*-{ 700 $wnd.jQuery(e).datetimepicker('hide'); 701 }-*/; 702 703 private native void update(Element e) /*-{ 704 $wnd.jQuery(e).datetimepicker('update'); 705 }-*/; 706 707 private native void setStartDate(Element e, String startDate) /*-{ 708 $wnd.jQuery(e).datetimepicker('setStartDate', startDate); 709 }-*/; 710 711 private native void setEndDate(Element e, String endDate) /*-{ 712 $wnd.jQuery(e).datetimepicker('setEndDate', endDate); 713 }-*/; 714 715 private native void setDaysOfWeekDisabled(Element e, String daysOfWeekDisabled) /*-{ 716 $wnd.jQuery(e).datetimepicker('setDaysOfWeekDisabled', daysOfWeekDisabled); 717 }-*/; 718 719 protected native void configure(Element e, String format, String formatViewType, int weekStart, 720 String daysOfWeekDisabled, boolean autoClose, int startView, int minView, int maxView, boolean todayBtn, 721 boolean highlightToday, boolean keyboardNavigation, boolean forceParse, int minuteStep, int viewSelect, 722 boolean showMeridian, String language, String position) /*-{ 723 var that = this; 724 $wnd.jQuery(e).datetimepicker({ 725 format: format, 726 formatViewType: formatViewType, 727 language: language, 728 weekStart: weekStart, 729 daysOfWeekDisabled: daysOfWeekDisabled, 730 autoclose: autoClose, 731 startView: startView, 732 minView: minView, 733 maxView: maxView, 734 todayBtn: todayBtn, 735 todayHighlight: highlightToday, 736 keyboardNavigation: keyboardNavigation, 737 forceParse: forceParse, 738 minuteStep: minuteStep, 739 showMeridian: showMeridian, 740 pickerPosition: position 741 }) 742 .on('show', function (e) { 743 that.@org.gwtbootstrap3.extras.datetimepicker.client.ui.base.DateTimePickerBase::onShow(Lcom/google/gwt/user/client/Event;)(e); 744 }) 745 .on("hide", function (e) { 746 that.@org.gwtbootstrap3.extras.datetimepicker.client.ui.base.DateTimePickerBase::onHide(Lcom/google/gwt/user/client/Event;)(e); 747 }) 748 .on("changeDate", function (e) { 749 that.@org.gwtbootstrap3.extras.datetimepicker.client.ui.base.DateTimePickerBase::onChangeDate(Lcom/google/gwt/user/client/Event;)(e); 750 }) 751 .on("changeYear", function (e) { 752 that.@org.gwtbootstrap3.extras.datetimepicker.client.ui.base.DateTimePickerBase::onChangeYear(Lcom/google/gwt/user/client/Event;)(e); 753 }) 754 .on("changeMonth", function (e) { 755 that.@org.gwtbootstrap3.extras.datetimepicker.client.ui.base.DateTimePickerBase::onChangeMonth(Lcom/google/gwt/user/client/Event;)(e); 756 }) 757 .on("outOfRange", function (e) { 758 that.@org.gwtbootstrap3.extras.datetimepicker.client.ui.base.DateTimePickerBase::onOutOfRange(Lcom/google/gwt/user/client/Event;)(e); 759 }); 760 }-*/; 761 762 protected String toDaysOfWeekDisabledString(final DateTimePickerDayOfWeek... dateTimePickerDayOfWeeks) { 763 this.daysOfWeekDisabled = dateTimePickerDayOfWeeks; 764 765 final StringBuilder builder = new StringBuilder(); 766 767 if (dateTimePickerDayOfWeeks != null) { 768 int i = 0; 769 for (final DateTimePickerDayOfWeek dayOfWeek : dateTimePickerDayOfWeeks) { 770 builder.append(dayOfWeek.getValue()); 771 772 i++; 773 if (i < dateTimePickerDayOfWeeks.length) { 774 builder.append(","); 775 } 776 } 777 } 778 return builder.toString(); 779 } 780 781 /** {@inheritDoc} */ 782 @Override 783 public com.google.web.bindery.event.shared.HandlerRegistration addValidationChangedHandler(ValidationChangedHandler handler) { 784 return validatorMixin.addValidationChangedHandler(handler); 785 } 786 787 /** {@inheritDoc} */ 788 @Override 789 public boolean getAllowBlank() { 790 return validatorMixin.getAllowBlank(); 791 } 792 793 /** {@inheritDoc} */ 794 @Override 795 public void setAllowBlank(boolean allowBlank) { 796 validatorMixin.setAllowBlank(allowBlank); 797 } 798 799 /** {@inheritDoc} */ 800 @Override 801 public void addValidator(Validator<Date> validator) { 802 validatorMixin.addValidator(validator); 803 } 804 805 /** {@inheritDoc} */ 806 @Override 807 public boolean getValidateOnBlur() { 808 return validatorMixin.getValidateOnBlur(); 809 } 810 811 /** {@inheritDoc} */ 812 @Override 813 public boolean removeValidator(Validator<Date> validator) { 814 return validatorMixin.removeValidator(validator); 815 } 816 817 /** {@inheritDoc} */ 818 @Override 819 public void reset() { 820 validatorMixin.reset(); 821 } 822 823 /** {@inheritDoc} */ 824 @Override 825 public void setValidateOnBlur(boolean validateOnBlur) { 826 validatorMixin.setValidateOnBlur(validateOnBlur); 827 } 828 829 /** {@inheritDoc} */ 830 @Override 831 public void setValidators(@SuppressWarnings("unchecked") Validator<Date>... validators) { 832 validatorMixin.setValidators(validators); 833 } 834 835 /** {@inheritDoc} */ 836 @Override 837 public boolean validate() { 838 return validatorMixin.validate(); 839 } 840 841 /** {@inheritDoc} */ 842 @Override 843 public boolean validate(boolean show) { 844 return validatorMixin.validate(show); 845 } 846 847 /** {@inheritDoc} */ 848 @Override 849 public ErrorHandler getErrorHandler() { 850 return errorHandlerMixin.getErrorHandler(); 851 } 852 853 /** {@inheritDoc} */ 854 @Override 855 public void setErrorHandler(ErrorHandler errorHandler) { 856 errorHandlerMixin.setErrorHandler(errorHandler); 857 validatorMixin.setErrorHandler(errorHandler); 858 } 859 860 /** {@inheritDoc} */ 861 @Override 862 public ErrorHandlerType getErrorHandlerType() { 863 return errorHandlerMixin.getErrorHandlerType(); 864 } 865 866 /** {@inheritDoc} */ 867 @Override 868 public void setErrorHandlerType(ErrorHandlerType errorHandlerType) { 869 errorHandlerMixin.setErrorHandlerType(errorHandlerType); 870 } 871 872 /** {@inheritDoc} */ 873 @Override 874 public void showErrors(List<EditorError> errors) { 875 errorHandlerMixin.showErrors(errors); 876 } 877 878}