Browse Source

Introduce DateTimeFile and InlineDateTimeField. (#8218)

* Introduce DateTimeFile and InlineDateTimeField.

Fixes #8132

* Correct and provide declarative tests.

* Provide a date converter and UI tests.
tags/8.0.0.beta2
Denis 7 years ago
parent
commit
f42b9657b8
70 changed files with 3728 additions and 86 deletions
  1. 41
    13
      client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java
  2. 3
    4
      client/src/main/java/com/vaadin/client/ui/VAbstractDateFieldCalendar.java
  3. 4
    7
      client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java
  4. 2
    2
      client/src/main/java/com/vaadin/client/ui/VDateField.java
  5. 1
    1
      client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java
  6. 431
    0
      client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java
  7. 113
    0
      client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java
  8. 19
    6
      client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java
  9. 228
    0
      client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java
  10. 6
    3
      client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java
  11. 4
    2
      client/src/main/java/com/vaadin/client/ui/datefield/DateFieldConnector.java
  12. 87
    0
      client/src/main/java/com/vaadin/client/ui/datefield/DateTimeFieldConnector.java
  13. 6
    3
      client/src/main/java/com/vaadin/client/ui/datefield/InlineDateFieldConnector.java
  14. 79
    0
      client/src/main/java/com/vaadin/client/ui/datefield/InlineDateTimeFieldConnector.java
  15. 6
    0
      client/src/main/java/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java
  16. 32
    0
      client/src/main/java/com/vaadin/client/ui/datefield/PopupDateTimeFieldConnector.java
  17. 33
    11
      client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java
  18. 74
    0
      server/src/main/java/com/vaadin/data/converter/LocalDateTimeToDateConverter.java
  19. 51
    0
      server/src/main/java/com/vaadin/data/validator/DateTimeRangeValidator.java
  20. 4
    0
      server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java
  21. 113
    5
      server/src/main/java/com/vaadin/ui/AbstractLocalDateTimeField.java
  22. 139
    0
      server/src/main/java/com/vaadin/ui/DateTimeField.java
  23. 71
    0
      server/src/main/java/com/vaadin/ui/InlineDateTimeField.java
  24. 4
    0
      server/src/main/java/com/vaadin/ui/declarative/DesignFormatter.java
  25. 68
    0
      server/src/main/java/com/vaadin/ui/declarative/converters/DesignLocalDateTimeConverter.java
  26. 99
    0
      server/src/test/java/com/vaadin/tests/data/converter/LocalDateTimeToDateConverterTest.java
  27. 110
    0
      server/src/test/java/com/vaadin/tests/server/component/abstractdatefield/AbstractLocalDateTimeFieldDeclarativeTest.java
  28. 2
    0
      server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java
  29. 3
    2
      server/src/test/java/com/vaadin/tests/server/component/colorpicker/AbstractColorPickerDeclarativeTest.java
  30. 63
    0
      server/src/test/java/com/vaadin/tests/server/component/datefield/DateTimeFieldDeclarativeTest.java
  31. 71
    0
      server/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateTimeFieldDeclarativeTest.java
  32. 1
    1
      shared/src/main/java/com/vaadin/shared/ui/datefield/DateTimeResolution.java
  33. 26
    0
      shared/src/main/java/com/vaadin/shared/ui/datefield/InlineDateTimeFieldState.java
  34. 1
    1
      shared/src/main/java/com/vaadin/shared/ui/datefield/LocalDateTimeFieldState.java
  35. 1
    1
      tests/screenshots
  36. 27
    0
      uitest-common/src/main/java/com/vaadin/testbench/customelements/DateTimeFieldElement.java
  37. 28
    0
      uitest-common/src/main/java/com/vaadin/testbench/customelements/InlineDateTimeFieldElement.java
  38. 1
    8
      uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java
  39. 130
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateTimeFieldTest.java
  40. 49
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/AriaDateTimeDisabled.java
  41. 59
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateTimeFormat.java
  42. 11
    14
      uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldDayResolutionOffset.java
  43. 63
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldChangeResolution.java
  44. 24
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldElementUI.java
  45. 39
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldFastForward.java
  46. 53
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldIsValid.java
  47. 47
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldKeyboardInput.java
  48. 45
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldReadOnly.java
  49. 64
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldTest.java
  50. 50
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledInlineDateTimeField.java
  51. 32
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/InlineDateTimeFieldTest.java
  52. 68
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/PopupDateTimeFieldStates.java
  53. 62
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/PopupTimeClosingWithEsc.java
  54. 50
    0
      uitest/src/main/java/com/vaadin/tests/components/datefield/TimePopupSelection.java
  55. 44
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/AriaDateTimeDisabledTest.java
  56. 39
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/CustomDateTimeFormatTest.java
  57. 1
    1
      uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldDayResolutionOffsetTest.java
  58. 199
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldChangeResolutionTest.java
  59. 26
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldElementTest.java
  60. 72
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldFastForwardTest.java
  61. 66
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldIsValidTest.java
  62. 43
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldKeyboardInputTest.java
  63. 46
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldReadOnlyTest.java
  64. 5
    1
      uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldTestTest.java
  65. 79
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/DisabledInlineDateTimeFieldTest.java
  66. 37
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/InlineDateTimeFieldTestTest.java
  67. 12
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/PopupDateFieldStatesTest.java
  68. 31
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/PopupDateTimeFieldStatesTest.java
  69. 63
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/PopupTimeClosingWithEscTest.java
  70. 67
    0
      uitest/src/test/java/com/vaadin/tests/components/datefield/TimePopupSelectionTest.java

+ 41
- 13
client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java View File

@@ -421,11 +421,21 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>
this.resolution = resolution;
}

private boolean isReadonly() {
/**
* Checks whether the widget is not editable (read-only).
*
* @return {@code true} if the widget is read-only
*/
protected boolean isReadonly() {
return parent.isReadonly();
}

private boolean isEnabled() {
/**
* Checks whether the widget is enabled.
*
* @return {@code true} is the widget is enabled
*/
protected boolean isEnabled() {
return parent.isEnabled();
}

@@ -583,10 +593,26 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>

}

private DateTimeService getDateTimeService() {
/**
* Returns date time service for the widget.
*
* @see #setDateTimeService(DateTimeService)
*
* @return date time service
*/
protected DateTimeService getDateTimeService() {
return dateTimeService;
}

/**
* Returns the date field which this panel is attached to.
*
* @return the "parent" date field
*/
protected VDateField<R> getDateField() {
return parent;
}

public void setDateTimeService(DateTimeService dateTimeService) {
this.dateTimeService = dateTimeService;
}
@@ -721,7 +747,7 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>
setCellSpacing(0);
getFlexCellFormatter().setColSpan(1, 0, 5);
getFlexCellFormatter().setStyleName(1, 0,
parent.getStylePrimaryName() + "-calendarpanel-body");
getDateField().getStylePrimaryName() + "-calendarpanel-body");

days.getFlexCellFormatter().setStyleName(headerRow, weekColumn,
"v-week");
@@ -731,7 +757,8 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>
isShowISOWeekNumbers());

days.getRowFormatter().setStyleName(headerRow,
parent.getStylePrimaryName() + "-calendarpanel-weekdays");
getDateField().getStylePrimaryName()
+ "-calendarpanel-weekdays");

if (isShowISOWeekNumbers()) {
days.getFlexCellFormatter().setStyleName(headerRow, weekColumn,
@@ -739,7 +766,7 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>
days.getFlexCellFormatter().setStyleName(headerRow,
firstWeekdayColumn, "");
days.getRowFormatter().addStyleName(headerRow,
parent.getStylePrimaryName()
getDateField().getStylePrimaryName()
+ "-calendarpanel-weeknumbers");
} else {
days.getFlexCellFormatter().setStyleName(headerRow, weekColumn, "");
@@ -792,8 +819,8 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>
Date dayDate = (Date) curr.clone();
Day day = new Day(dayDate);

day.setStyleName(
parent.getStylePrimaryName() + "-calendarpanel-day");
day.setStyleName(getDateField().getStylePrimaryName()
+ "-calendarpanel-day");

if (!isDateInsideRange(dayDate, getResolution(this::isDay))) {
day.addStyleDependentName(CN_OUTSIDE_RANGE);
@@ -828,7 +855,8 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>
isShowISOWeekNumbers());

if (isShowISOWeekNumbers()) {
final String baseCssClass = parent.getStylePrimaryName()
final String baseCssClass = getDateField()
.getStylePrimaryName()
+ "-calendarpanel-weeknumber";
String weekCssClass = baseCssClass;

@@ -880,7 +908,7 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>
*/
protected void doRenderCalendar(boolean updateDate) {
super.setStylePrimaryName(
parent.getStylePrimaryName() + "-calendarpanel");
getDateField().getStylePrimaryName() + "-calendarpanel");

if (focusedDate == null) {
Date now = new Date();
@@ -896,7 +924,7 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>
}

final boolean needsMonth = !isYear(getResolution());
boolean needsBody = isDay(getResolution());
boolean needsBody = isBelowMonth(resolution);
buildCalendarHeader(needsMonth);
clearCalendarBody(!needsBody);
if (needsBody) {
@@ -1976,8 +2004,8 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>
}

private void setLabel() {
if (parent instanceof VAbstractPopupCalendar) {
((VAbstractPopupCalendar) parent).setFocusedDate(this);
if (getDateField() instanceof VAbstractPopupCalendar) {
((VAbstractPopupCalendar) getDateField()).setFocusedDate(this);
}
}
}

+ 3
- 4
client/src/main/java/com/vaadin/client/ui/VAbstractDateFieldCalendar.java View File

@@ -23,14 +23,13 @@ import com.vaadin.client.ui.VAbstractCalendarPanel.SubmitListener;
/**
* A client side implementation for inline date field.
*/
public abstract class VAbstractDateFieldCalendar<R extends Enum<R>>
public abstract class VAbstractDateFieldCalendar<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>>
extends VDateField<R> {

/** For internal use only. May be removed or replaced in the future. */
public final VAbstractCalendarPanel<R> calendarPanel;
public final PANEL calendarPanel;

public VAbstractDateFieldCalendar(VAbstractCalendarPanel<R> panel,
R resolution) {
public VAbstractDateFieldCalendar(PANEL panel, R resolution) {
super(resolution);
calendarPanel = panel;
calendarPanel.setParentField(this);

+ 4
- 7
client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java View File

@@ -17,7 +17,6 @@
package com.vaadin.client.ui;

import java.util.Date;
import java.util.Locale;

import com.google.gwt.aria.client.Id;
import com.google.gwt.aria.client.LiveValue;
@@ -63,7 +62,7 @@ import com.vaadin.shared.ui.datefield.TextualDateFieldState;
* <code>setCalendarPanel(VAbstractCalendarPanel panel)</code> method.
*
*/
public abstract class VAbstractPopupCalendar<R extends Enum<R>>
public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>>
extends VAbstractTextualDate<R>
implements Field, ClickHandler, CloseHandler<PopupPanel>, SubPartAware {

@@ -71,7 +70,7 @@ public abstract class VAbstractPopupCalendar<R extends Enum<R>>
public final Button calendarToggle = new Button();

/** For internal use only. May be removed or replaced in the future. */
public VAbstractCalendarPanel<R> calendar;
public PANEL calendar;

/** For internal use only. May be removed or replaced in the future. */
public final VOverlay popup;
@@ -100,8 +99,7 @@ public abstract class VAbstractPopupCalendar<R extends Enum<R>>

private final String CALENDAR_TOGGLE_ID = "popupButton";

public VAbstractPopupCalendar(VAbstractCalendarPanel<R> calendarPanel,
R resolution) {
public VAbstractPopupCalendar(PANEL calendarPanel, R resolution) {
super(resolution);

calendarToggle.setText("");
@@ -230,8 +228,7 @@ public abstract class VAbstractPopupCalendar<R extends Enum<R>>
if (!calendar.isYear(getCurrentResolution())) {
getClient().updateVariable(getId(),
getResolutionVariable(
calendar.getResolution(calendar::isMonth))
.toLowerCase(Locale.ENGLISH),
calendar.getResolution(calendar::isMonth)),
newDate.getMonth() + 1, false);
if (!calendar.isMonth(getCurrentResolution())) {
getClient().updateVariable(getId(),

+ 2
- 2
client/src/main/java/com/vaadin/client/ui/VDateField.java View File

@@ -230,11 +230,11 @@ public abstract class VDateField<R extends Enum<R>> extends FlowPanel
*
* @see #setCurrentDate(Map)
*
* @param dateVaules
* @param dateValues
* a map with date values to convert into a date
* @return the date based on the dateValues map
*/
protected abstract Date getDate(Map<R, Integer> dateVaules);
protected abstract Date getDate(Map<R, Integer> dateValues);

/**
* Returns all available resolutions as an array.

+ 1
- 1
client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java View File

@@ -28,7 +28,7 @@ import com.vaadin.shared.ui.datefield.DateResolution;
*
*/
public class VDateFieldCalendar
extends VAbstractDateFieldCalendar<DateResolution> {
extends VAbstractDateFieldCalendar<VDateCalendarPanel, DateResolution> {

public VDateFieldCalendar() {
super(GWT.create(VDateCalendarPanel.class), DateResolution.YEAR);

+ 431
- 0
client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java View File

@@ -0,0 +1,431 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.ui;

import java.util.Date;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.DateTimeService;
import com.vaadin.shared.ui.datefield.DateTimeResolution;

/**
* @author Vaadin Ltd
* @since 8.0
*/
public class VDateTimeCalendarPanel
extends VAbstractCalendarPanel<DateTimeResolution> {

private static final String SUBPART_HOUR_SELECT = "h";
private static final String SUBPART_MINUTE_SELECT = "m";
private static final String SUBPART_SECS_SELECT = "s";
private static final String SUBPART_AMPM_SELECT = "ampm";

private TimeChangeListener timeChangeListener;

private VTime time;

/**
* TimeSelector is a widget consisting of list boxes that modifie the Date
* object that is given for.
*
*/
public class VTime extends FlowPanel implements ChangeHandler {

private ListBox hours;

private ListBox mins;

private ListBox sec;

private ListBox ampm;

/**
* Constructor
*/
public VTime() {
super();
setStyleName(VDateField.CLASSNAME + "-time");
buildTime();
}

private ListBox createListBox() {
ListBox lb = new ListBox();
lb.setStyleName("v-select");
lb.addChangeHandler(this);
lb.addBlurHandler(VDateTimeCalendarPanel.this);
lb.addFocusHandler(VDateTimeCalendarPanel.this);
return lb;
}

/**
* Constructs the ListBoxes and updates their value
*
* @param redraw
* Should new instances of the listboxes be created
*/
private void buildTime() {
clear();

hours = createListBox();
if (getDateTimeService().isTwelveHourClock()) {
hours.addItem("12");
for (int i = 1; i < 12; i++) {
hours.addItem((i < 10) ? "0" + i : "" + i);
}
} else {
for (int i = 0; i < 24; i++) {
hours.addItem((i < 10) ? "0" + i : "" + i);
}
}

hours.addChangeHandler(this);
if (getDateTimeService().isTwelveHourClock()) {
ampm = createListBox();
final String[] ampmText = getDateTimeService().getAmPmStrings();
ampm.addItem(ampmText[0]);
ampm.addItem(ampmText[1]);
ampm.addChangeHandler(this);
}

if (getResolution().compareTo(DateTimeResolution.MINUTE) <= 0) {
mins = createListBox();
for (int i = 0; i < 60; i++) {
mins.addItem((i < 10) ? "0" + i : "" + i);
}
mins.addChangeHandler(this);
}
if (getResolution().compareTo(DateTimeResolution.SECOND) <= 0) {
sec = createListBox();
for (int i = 0; i < 60; i++) {
sec.addItem((i < 10) ? "0" + i : "" + i);
}
sec.addChangeHandler(this);
}

final String delimiter = getDateTimeService().getClockDelimeter();
if (isReadonly()) {
int h = 0;
if (getDate() != null) {
h = getDate().getHours();
}
if (getDateTimeService().isTwelveHourClock()) {
h -= h < 12 ? 0 : 12;
}
add(new VLabel(h < 10 ? "0" + h : "" + h));
} else {
add(hours);
}

if (getResolution().compareTo(DateTimeResolution.MINUTE) <= 0) {
add(new VLabel(delimiter));
if (isReadonly()) {
final int m = mins.getSelectedIndex();
add(new VLabel(m < 10 ? "0" + m : "" + m));
} else {
add(mins);
}
}
if (getResolution().compareTo(DateTimeResolution.SECOND) <= 0) {
add(new VLabel(delimiter));
if (isReadonly()) {
final int s = sec.getSelectedIndex();
add(new VLabel(s < 10 ? "0" + s : "" + s));
} else {
add(sec);
}
}
if (getResolution() == DateTimeResolution.HOUR) {
add(new VLabel(delimiter + "00")); // o'clock
}
if (getDateTimeService().isTwelveHourClock()) {
add(new VLabel("&nbsp;"));
if (isReadonly()) {
int i = 0;
if (getDate() != null) {
i = (getDate().getHours() < 12) ? 0 : 1;
}
add(new VLabel(ampm.getItemText(i)));
} else {
add(ampm);
}
}

if (isReadonly()) {
return;
}

// Update times
updateTimes();

ListBox lastDropDown = getLastDropDown();
lastDropDown.addKeyDownHandler(new KeyDownHandler() {
@Override
public void onKeyDown(KeyDownEvent event) {
boolean shiftKey = event.getNativeEvent().getShiftKey();
if (shiftKey) {
return;
} else {
int nativeKeyCode = event.getNativeKeyCode();
if (nativeKeyCode == KeyCodes.KEY_TAB) {
onTabOut(event);
}
}
}
});

}

private ListBox getLastDropDown() {
int i = getWidgetCount() - 1;
while (i >= 0) {
Widget widget = getWidget(i);
if (widget instanceof ListBox) {
return (ListBox) widget;
}
i--;
}
return null;
}

/**
* Updates the valus to correspond to the values in value
*/
public void updateTimes() {
if (getDate() == null) {
setDate(new Date());
}
if (getDateTimeService().isTwelveHourClock()) {
int h = getDate().getHours();
ampm.setSelectedIndex(h < 12 ? 0 : 1);
h -= ampm.getSelectedIndex() * 12;
hours.setSelectedIndex(h);
} else {
hours.setSelectedIndex(getDate().getHours());
}
if (getResolution().compareTo(DateTimeResolution.MINUTE) <= 0) {
mins.setSelectedIndex(getDate().getMinutes());
}
if (getResolution().compareTo(DateTimeResolution.SECOND) <= 0) {
sec.setSelectedIndex(getDate().getSeconds());
}
if (getDateTimeService().isTwelveHourClock()) {
ampm.setSelectedIndex(getDate().getHours() < 12 ? 0 : 1);
}

hours.setEnabled(isEnabled());
if (mins != null) {
mins.setEnabled(isEnabled());
}
if (sec != null) {
sec.setEnabled(isEnabled());
}
if (ampm != null) {
ampm.setEnabled(isEnabled());
}

}

private DateTimeService getDateTimeService() {
if (VDateTimeCalendarPanel.this.getDateTimeService() == null) {
setDateTimeService(new DateTimeService());
}
return VDateTimeCalendarPanel.this.getDateTimeService();
}

/*
* (non-Javadoc) VT
*
* @see
* com.google.gwt.event.dom.client.ChangeHandler#onChange(com.google.gwt
* .event.dom.client.ChangeEvent)
*/
@Override
public void onChange(ChangeEvent event) {
/*
* Value from dropdowns gets always set for the value. Like year and
* month when resolution is month or year.
*/
if (event.getSource() == hours) {
int h = hours.getSelectedIndex();
if (getDateTimeService().isTwelveHourClock()) {
h = h + ampm.getSelectedIndex() * 12;
}
getDate().setHours(h);
if (timeChangeListener != null) {
timeChangeListener.changed(h, getDate().getMinutes(),
getDate().getSeconds(),
DateTimeService.getMilliseconds(getDate()));
}
event.preventDefault();
event.stopPropagation();
} else if (event.getSource() == mins) {
final int m = mins.getSelectedIndex();
getDate().setMinutes(m);
if (timeChangeListener != null) {
timeChangeListener.changed(getDate().getHours(), m,
getDate().getSeconds(),
DateTimeService.getMilliseconds(getDate()));
}
event.preventDefault();
event.stopPropagation();
} else if (event.getSource() == sec) {
final int s = sec.getSelectedIndex();
getDate().setSeconds(s);
if (timeChangeListener != null) {
timeChangeListener.changed(getDate().getHours(),
getDate().getMinutes(), s,
DateTimeService.getMilliseconds(getDate()));
}
event.preventDefault();
event.stopPropagation();
} else if (event.getSource() == ampm) {
final int h = hours.getSelectedIndex()
+ (ampm.getSelectedIndex() * 12);
getDate().setHours(h);
if (timeChangeListener != null) {
timeChangeListener.changed(h, getDate().getMinutes(),
getDate().getSeconds(),
DateTimeService.getMilliseconds(getDate()));
}
event.preventDefault();
event.stopPropagation();
}
}

}

/**
* Dispatches an event when the panel when time is changed
*/
public interface TimeChangeListener {

void changed(int hour, int min, int sec, int msec);
}

/**
* The time change listener is triggered when the user changes the time.
*
* @param listener
*/
public void setTimeChangeListener(TimeChangeListener listener) {
timeChangeListener = listener;
}

@Override
public void setDate(Date currentDate) {
doSetDate(currentDate, isTimeSelectorNeeded() && time == null, () -> {
if (isTimeSelectorNeeded()) {
time.updateTimes();
}
});
}

@Override
public void setResolution(DateTimeResolution resolution) {
super.setResolution(resolution);
if (isTimeSelectorNeeded() && time != null) {
// resolution has changed => rebuild time UI
time.buildTime();
}
}

@Override
protected boolean acceptDayFocus() {
return getResolution().compareTo(DateTimeResolution.MONTH) < 0;
}

@Override
protected boolean isDay(DateTimeResolution resolution) {
return DateTimeResolution.DAY.equals(resolution);
}

@Override
protected boolean isMonth(DateTimeResolution resolution) {
return DateTimeResolution.MONTH.equals(resolution);
}

@Override
protected boolean isBelowMonth(DateTimeResolution resolution) {
return resolution.compareTo(DateTimeResolution.MONTH) < 0;
}

@Override
protected void doRenderCalendar(boolean updateDate) {
super.doRenderCalendar(updateDate);

if (isTimeSelectorNeeded()) {
time = new VTime();
setWidget(2, 0, time);
getFlexCellFormatter().setColSpan(2, 0, 5);
getFlexCellFormatter().setStyleName(2, 0,
getDateField().getStylePrimaryName()
+ "-calendarpanel-time");
} else if (time != null) {
remove(time);
}
}

@Override
public String getSubPartName(Element subElement) {
if (time != null) {
if (contains(time.hours, subElement)) {
return SUBPART_HOUR_SELECT;
} else if (contains(time.mins, subElement)) {
return SUBPART_MINUTE_SELECT;
} else if (contains(time.sec, subElement)) {
return SUBPART_SECS_SELECT;
} else if (contains(time.ampm, subElement)) {
return SUBPART_AMPM_SELECT;

}
}
return super.getSubPartName(subElement);
}

@Override
public Element getSubPartElement(String subPart) {
if (SUBPART_HOUR_SELECT.equals(subPart)) {
return time.hours.getElement();
}
if (SUBPART_MINUTE_SELECT.equals(subPart)) {
return time.mins.getElement();
}
if (SUBPART_SECS_SELECT.equals(subPart)) {
return time.sec.getElement();
}
if (SUBPART_AMPM_SELECT.equals(subPart)) {
return time.ampm.getElement();
}
return super.getSubPartElement(subPart);
}

/**
* Do we need the time selector
*
* @return True if it is required
*/
private boolean isTimeSelectorNeeded() {
return getResolution().compareTo(DateTimeResolution.DAY) < 0;
}
}

+ 113
- 0
client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java View File

@@ -0,0 +1,113 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.ui;

import java.util.Date;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.vaadin.shared.ui.datefield.DateTimeResolution;

/**
* A client side implementation for inline date/time field.
*
* @author Vaadin Ltd
* @since 8.0
*
*/
public class VDateTimeFieldCalendar extends
VAbstractDateFieldCalendar<VDateTimeCalendarPanel, DateTimeResolution> {

public VDateTimeFieldCalendar() {
super(GWT.create(VDateTimeCalendarPanel.class),
DateTimeResolution.MINUTE);
}

@Override
public void updateValueFromPanel() {
// If field is invisible at the beginning, client can still be null when
// this function is called.
if (getClient() == null) {
return;
}

Date date2 = calendarPanel.getDate();
Date currentDate = getCurrentDate();
if (currentDate == null || date2.getTime() != currentDate.getTime()) {
setCurrentDate((Date) date2.clone());
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.YEAR),
date2.getYear() + 1900, false);
if (getCurrentResolution().compareTo(DateTimeResolution.YEAR) < 0) {
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.MONTH),
date2.getMonth() + 1, false);
if (getCurrentResolution()
.compareTo(DateTimeResolution.MONTH) < 0) {
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.DAY),
date2.getDate(), false);
if (getCurrentResolution()
.compareTo(DateTimeResolution.DAY) < 0) {
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.HOUR),
date2.getHours(), false);
if (getCurrentResolution()
.compareTo(DateTimeResolution.HOUR) < 0) {
getClient().updateVariable(getId(),
getResolutionVariable(
DateTimeResolution.MINUTE),
date2.getMinutes(), false);
if (getCurrentResolution()
.compareTo(DateTimeResolution.MINUTE) < 0) {
getClient().updateVariable(getId(),
getResolutionVariable(
DateTimeResolution.SECOND),
date2.getSeconds(), false);
}
}
}
}
}
getClient().sendPendingVariableChanges();
}
}

@Override
public String resolutionAsString() {
if (getCurrentResolution().compareTo(DateTimeResolution.DAY) >= 0) {
return getResolutionVariable(getCurrentResolution());
} else {
return "full";
}
}

@Override
public boolean isYear(DateTimeResolution resolution) {
return DateTimeResolution.YEAR.equals(resolution);
}

@Override
protected Date getDate(Map<DateTimeResolution, Integer> dateValues) {
return VPopupTimeCalendar.makeDate(dateValues);
}

@Override
protected DateTimeResolution[] doGetResolutions() {
return DateTimeResolution.values();
}

}

+ 19
- 6
client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java View File

@@ -28,7 +28,8 @@ import com.vaadin.shared.ui.datefield.DateResolution;
* @author Vaadin Ltd
*
*/
public class VPopupCalendar extends VAbstractPopupCalendar<DateResolution> {
public class VPopupCalendar
extends VAbstractPopupCalendar<VDateCalendarPanel, DateResolution> {

public VPopupCalendar() {
super(GWT.create(VDateCalendarPanel.class), DateResolution.YEAR);
@@ -50,20 +51,20 @@ public class VPopupCalendar extends VAbstractPopupCalendar<DateResolution> {
resolution == null ? DateResolution.YEAR : resolution);
}

public static Date makeDate(Map<DateResolution, Integer> dateVaules) {
if (dateVaules.get(DateResolution.YEAR) == -1) {
public static Date makeDate(Map<DateResolution, Integer> dateValues) {
if (dateValues.get(DateResolution.YEAR) == -1) {
return null;
}
Date date = new Date(2000 - 1900, 0, 1);
int year = dateVaules.get(DateResolution.YEAR);
int year = dateValues.get(DateResolution.YEAR);
if (year >= 0) {
date.setYear(year - 1900);
}
int month = dateVaules.get(DateResolution.MONTH);
int month = dateValues.get(DateResolution.MONTH);
if (month >= 0) {
date.setMonth(month - 1);
}
int day = dateVaules.get(DateResolution.DAY);
int day = dateValues.get(DateResolution.DAY);
if (day >= 0) {
date.setDate(day);
}
@@ -101,4 +102,16 @@ public class VPopupCalendar extends VAbstractPopupCalendar<DateResolution> {
}
}

@Override
protected String cleanFormat(String format) {
// Remove unnecessary d & M if resolution is too low
if (getCurrentResolution().compareTo(DateResolution.DAY) > 0) {
format = format.replaceAll("d", "");
}
if (getCurrentResolution().compareTo(DateResolution.MONTH) > 0) {
format = format.replaceAll("M", "");
}
return super.cleanFormat(format);
}

}

+ 228
- 0
client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java View File

@@ -0,0 +1,228 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.ui;

import java.util.Date;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.vaadin.client.LocaleNotLoadedException;
import com.vaadin.client.LocaleService;
import com.vaadin.client.VConsole;
import com.vaadin.shared.ui.datefield.DateTimeResolution;

/**
* Represents a date-time selection component with a text field and a popup date
* selector.
*
* @author Vaadin Ltd
*
* @since 8.0
*/
public class VPopupTimeCalendar extends
VAbstractPopupCalendar<VDateTimeCalendarPanel, DateTimeResolution> {

public VPopupTimeCalendar() {
super(GWT.create(VDateTimeCalendarPanel.class),
DateTimeResolution.MINUTE);
}

@Override
protected DateTimeResolution[] doGetResolutions() {
return DateTimeResolution.values();
}

@Override
public String resolutionAsString() {
if (getCurrentResolution().compareTo(DateTimeResolution.DAY) >= 0) {
return getResolutionVariable(getCurrentResolution());
} else {
return "full";
}
}

@Override
public void setCurrentResolution(DateTimeResolution resolution) {
super.setCurrentResolution(
resolution == null ? DateTimeResolution.MINUTE : resolution);
}

public static Date makeDate(Map<DateTimeResolution, Integer> dateValues) {
if (dateValues.get(DateTimeResolution.YEAR) == -1) {
return null;
}
Date date = new Date(2000 - 1900, 0, 1);
int year = dateValues.get(DateTimeResolution.YEAR);
if (year >= 0) {
date.setYear(year - 1900);
}
int month = dateValues.get(DateTimeResolution.MONTH);
if (month >= 0) {
date.setMonth(month - 1);
}
int day = dateValues.get(DateTimeResolution.DAY);
if (day >= 0) {
date.setDate(day);
}
int hour = dateValues.get(DateTimeResolution.HOUR);
if (hour >= 0) {
date.setHours(hour);
}
int minute = dateValues.get(DateTimeResolution.MINUTE);
if (minute >= 0) {
date.setMinutes(minute);
}
int second = dateValues.get(DateTimeResolution.SECOND);
if (second >= 0) {
date.setSeconds(second);
}
return date;
}

@Override
public boolean isYear(DateTimeResolution resolution) {
return DateTimeResolution.YEAR.equals(resolution);
}

@Override
protected Date getDate(Map<DateTimeResolution, Integer> dateValues) {
return makeDate(dateValues);
}

@Override
protected void updateDateVariables() {
super.updateDateVariables();
// Update variables
// (only the smallest defining resolution needs to be
// immediate)
Date currentDate = getDate();
if (getCurrentResolution().compareTo(DateTimeResolution.MONTH) <= 0) {
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.MONTH),
currentDate != null ? currentDate.getMonth() + 1 : -1,
getCurrentResolution() == DateTimeResolution.MONTH);
}
if (getCurrentResolution().compareTo(DateTimeResolution.DAY) <= 0) {
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.DAY),
currentDate != null ? currentDate.getDate() : -1,
getCurrentResolution() == DateTimeResolution.DAY);
}
if (getCurrentResolution().compareTo(DateTimeResolution.HOUR) <= 0) {
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.HOUR),
currentDate != null ? currentDate.getHours() : -1,
getCurrentResolution() == DateTimeResolution.HOUR);
}
if (getCurrentResolution().compareTo(DateTimeResolution.MINUTE) <= 0) {
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.MINUTE),
currentDate != null ? currentDate.getMinutes() : -1,
getCurrentResolution() == DateTimeResolution.MINUTE);
}
if (getCurrentResolution().compareTo(DateTimeResolution.SECOND) <= 0) {
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.SECOND),
currentDate != null ? currentDate.getSeconds() : -1,
getCurrentResolution() == DateTimeResolution.SECOND);
}
}

@Override
@SuppressWarnings("deprecation")
public void updateValue(Date newDate) {
Date currentDate = getCurrentDate();
super.updateValue(newDate);
if (currentDate == null || newDate.getTime() != currentDate.getTime()) {
if (getCurrentResolution().compareTo(DateTimeResolution.DAY) < 0) {
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.HOUR),
newDate.getHours(), false);
if (getCurrentResolution()
.compareTo(DateTimeResolution.HOUR) < 0) {
getClient().updateVariable(getId(),
getResolutionVariable(DateTimeResolution.MINUTE),
newDate.getMinutes(), false);
if (getCurrentResolution()
.compareTo(DateTimeResolution.MINUTE) < 0) {
getClient().updateVariable(getId(),
getResolutionVariable(
DateTimeResolution.SECOND),
newDate.getSeconds(), false);
}
}
}
}
}

@Override
protected String getFormatString() {
if (formatStr == null) {
if (isYear(getCurrentResolution())) {
formatStr = "yyyy"; // force full year
} else {

try {
String frmString = LocaleService
.getDateFormat(currentLocale);
frmString = cleanFormat(frmString);
// String delim = LocaleService
// .getClockDelimiter(currentLocale);
if (getCurrentResolution()
.compareTo(DateTimeResolution.HOUR) <= 0) {
if (dts.isTwelveHourClock()) {
frmString += " hh";
} else {
frmString += " HH";
}
if (getCurrentResolution()
.compareTo(DateTimeResolution.MINUTE) <= 0) {
frmString += ":mm";
if (getCurrentResolution().compareTo(
DateTimeResolution.SECOND) <= 0) {
frmString += ":ss";
}
}
if (dts.isTwelveHourClock()) {
frmString += " aaa";
}

}

formatStr = frmString;
} catch (LocaleNotLoadedException e) {
// TODO should die instead? Can the component survive
// without format string?
VConsole.error(e);
}
}
}
return formatStr;
}

@Override
protected String cleanFormat(String format) {
// Remove unnecessary d & M if resolution is too low
if (getCurrentResolution().compareTo(DateTimeResolution.DAY) > 0) {
format = format.replaceAll("d", "");
}
if (getCurrentResolution().compareTo(DateTimeResolution.MONTH) > 0) {
format = format.replaceAll("M", "");
}
return super.cleanFormat(format);
}

}

+ 6
- 3
client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java View File

@@ -20,6 +20,7 @@ import java.util.Date;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.UIDL;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.VAbstractCalendarPanel;
import com.vaadin.client.ui.VAbstractCalendarPanel.FocusChangeListener;
import com.vaadin.client.ui.VAbstractDateFieldCalendar;
import com.vaadin.shared.ui.datefield.InlineDateFieldState;
@@ -31,8 +32,10 @@ import com.vaadin.shared.ui.datefield.InlineDateFieldState;
*
* @param <R>
* the resolution type which the field is based on (day, month, ...)
* @param <PANEL>
* Subclass of VAbstractCalendarPanel specific for the implementation
*/
public abstract class AbstractInlineDateFieldConnector<R extends Enum<R>>
public abstract class AbstractInlineDateFieldConnector<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>>
extends AbstractDateFieldConnector<R> {

@Override
@@ -107,8 +110,8 @@ public abstract class AbstractInlineDateFieldConnector<R extends Enum<R>>
}

@Override
public VAbstractDateFieldCalendar<R> getWidget() {
return (VAbstractDateFieldCalendar<R>) super.getWidget();
public VAbstractDateFieldCalendar<PANEL, R> getWidget() {
return (VAbstractDateFieldCalendar<PANEL, R>) super.getWidget();
}

@Override

+ 4
- 2
client/src/main/java/com/vaadin/client/ui/datefield/DateFieldConnector.java View File

@@ -15,6 +15,7 @@
*/
package com.vaadin.client.ui.datefield;

import com.vaadin.client.ui.VDateCalendarPanel;
import com.vaadin.client.ui.VPopupCalendar;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.datefield.DateResolution;
@@ -26,10 +27,11 @@ import com.vaadin.ui.AbstractLocalDateField;
*
*/
@Connect(AbstractLocalDateField.class)
public class DateFieldConnector extends TextualDateConnector<DateResolution> {
public class DateFieldConnector
extends TextualDateConnector<VDateCalendarPanel, DateResolution> {

@Override
protected boolean isResolutionAboveMonth() {
protected boolean isResolutionMonthOrHigher() {
return getWidget().getCurrentResolution()
.compareTo(DateResolution.MONTH) >= 0;
}

+ 87
- 0
client/src/main/java/com/vaadin/client/ui/datefield/DateTimeFieldConnector.java View File

@@ -0,0 +1,87 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.ui.datefield;

import java.util.Date;

import com.vaadin.client.DateTimeService;
import com.vaadin.client.ui.VDateTimeCalendarPanel;
import com.vaadin.client.ui.VDateTimeCalendarPanel.TimeChangeListener;
import com.vaadin.client.ui.VPopupTimeCalendar;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.shared.ui.datefield.LocalDateTimeFieldState;
import com.vaadin.ui.AbstractLocalDateTimeField;

/**
* The client-side connector for AbstractLocalDateTimeField.
*
* @author Vaadin Ltd
* @since 8.0
*/
@Connect(AbstractLocalDateTimeField.class)
public class DateTimeFieldConnector extends
TextualDateConnector<VDateTimeCalendarPanel, DateTimeResolution> {

@Override
protected boolean isResolutionMonthOrHigher() {
return getWidget().getCurrentResolution()
.compareTo(DateTimeResolution.MONTH) >= 0;
}

@Override
public VPopupTimeCalendar getWidget() {
return (VPopupTimeCalendar) super.getWidget();
}

@Override
public LocalDateTimeFieldState getState() {
return (LocalDateTimeFieldState) super.getState();
}

@Override
protected void updateListeners() {
super.updateListeners();
if (getWidget().getCurrentResolution()
.compareTo(DateTimeResolution.DAY) < 0) {
getWidget().calendar
.setTimeChangeListener(new TimeChangeListener() {
@Override
public void changed(int hour, int min, int sec,
int msec) {
Date d = getWidget().getDate();
if (d == null) {
// date currently null, use the value from
// calendarPanel
// (~ client time at the init of the widget)
d = (Date) getWidget().calendar.getDate()
.clone();
}
d.setHours(hour);
d.setMinutes(min);
d.setSeconds(sec);
DateTimeService.setMilliseconds(d, msec);

// Always update time changes to the server
getWidget().updateValue(d);

// Update text field
getWidget().buildDate();
}
});
}
}
}

+ 6
- 3
client/src/main/java/com/vaadin/client/ui/datefield/InlineDateFieldConnector.java View File

@@ -15,18 +15,21 @@
*/
package com.vaadin.client.ui.datefield;

import com.vaadin.client.ui.VDateCalendarPanel;
import com.vaadin.client.ui.VDateFieldCalendar;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.ui.InlineDateField;

/**
* The client-side connector for InlineDateField.
*
* @author Vaadin Ltd
*
* @since 8.0
*/
@Connect(InlineDateField.class)
public class InlineDateFieldConnector
extends AbstractInlineDateFieldConnector<DateResolution> {
public class InlineDateFieldConnector extends
AbstractInlineDateFieldConnector<VDateCalendarPanel, DateResolution> {

@Override
protected boolean isResolutionMonthOrHigher() {

+ 79
- 0
client/src/main/java/com/vaadin/client/ui/datefield/InlineDateTimeFieldConnector.java View File

@@ -0,0 +1,79 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.client.ui.datefield;

import java.util.Date;

import com.vaadin.client.DateTimeService;
import com.vaadin.client.ui.VDateTimeCalendarPanel;
import com.vaadin.client.ui.VDateTimeCalendarPanel.TimeChangeListener;
import com.vaadin.client.ui.VDateTimeFieldCalendar;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.ui.InlineDateTimeField;

/**
* The client-side connector for InlineDateTimeField.
*
* @author Vaadin Ltd
* @since 8.0
*/
@Connect(InlineDateTimeField.class)
public class InlineDateTimeFieldConnector extends
AbstractInlineDateFieldConnector<VDateTimeCalendarPanel, DateTimeResolution> {

@Override
protected boolean isResolutionMonthOrHigher() {
return getWidget().getCurrentResolution()
.compareTo(DateTimeResolution.MONTH) >= 0;
}

@Override
public VDateTimeFieldCalendar getWidget() {
return (VDateTimeFieldCalendar) super.getWidget();
}

@Override
protected void updateListeners() {
super.updateListeners();
if (getWidget().getCurrentResolution()
.compareTo(DateTimeResolution.DAY) < 0) {
getWidget().calendarPanel
.setTimeChangeListener(new TimeChangeListener() {
@Override
public void changed(int hour, int min, int sec,
int msec) {
Date d = getWidget().getDate();
if (d == null) {
// date currently null, use the value from
// calendarPanel
// (~ client time at the init of the widget)
d = (Date) getWidget().calendarPanel.getDate()
.clone();
}
d.setHours(hour);
d.setMinutes(min);
d.setSeconds(sec);
DateTimeService.setMilliseconds(d, msec);

// Always update time changes to the server
getWidget().calendarPanel.setDate(d);
getWidget().updateValueFromPanel();
}
});
}
}
}

+ 6
- 0
client/src/main/java/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java View File

@@ -19,6 +19,12 @@ package com.vaadin.client.ui.datefield;
import com.vaadin.shared.ui.Connect;
import com.vaadin.ui.DateField;

/**
* The client-side connector for DateField.
*
* @author Vaadin Ltd
* @since 8.0
*/
@Connect(DateField.class)
public class PopupDateFieldConnector extends DateFieldConnector {


+ 32
- 0
client/src/main/java/com/vaadin/client/ui/datefield/PopupDateTimeFieldConnector.java View File

@@ -0,0 +1,32 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package com.vaadin.client.ui.datefield;

import com.vaadin.shared.ui.Connect;
import com.vaadin.ui.DateTimeField;

/**
* The client-side connector for DateTimeField.
*
* @author Vaadin Ltd
* @since 8.0
*
*/
@Connect(DateTimeField.class)
public class PopupDateTimeFieldConnector extends DateTimeFieldConnector {

}

+ 33
- 11
client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java View File

@@ -24,11 +24,26 @@ import com.google.gwt.user.client.ui.PopupPanel;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.UIDL;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.VAbstractCalendarPanel;
import com.vaadin.client.ui.VAbstractCalendarPanel.FocusChangeListener;
import com.vaadin.client.ui.VAbstractPopupCalendar;
import com.vaadin.shared.ui.datefield.TextualDateFieldState;

public abstract class TextualDateConnector<R extends Enum<R>>
/**
* Abstract date/time field connector which extend
* {@link AbstractTextualDateConnector} functionality with widget that shows
* date/time chooser as a popup panel.
*
* @author Vaadin Ltd
*
* @since 8.0
*
* @param <PANEL>
* Subclass of VAbstractCalendarPanel specific for the implementation
* @param <R>
* the resolution type which the field is based on (day, month, ...)
*/
public abstract class TextualDateConnector<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>>
extends AbstractTextualDateConnector<R> {

@Override
@@ -112,17 +127,18 @@ public abstract class TextualDateConnector<R extends Enum<R>>
* customizing only listeners logic.
*/
protected void updateListeners() {
if (isResolutionAboveMonth()) {
if (isResolutionMonthOrHigher()) {
getWidget().calendar
.setFocusChangeListener(new FocusChangeListener() {
@Override
public void focusChanged(Date date) {

getWidget().updateValue(date);
getWidget().buildDate();
Date date2 = getWidget().calendar.getDate();
date2.setYear(date.getYear());
date2.setMonth(date.getMonth());
if (isResolutionMonthOrHigher()) {
getWidget().updateValue(date);
getWidget().buildDate();
Date date2 = getWidget().calendar.getDate();
date2.setYear(date.getYear());
date2.setMonth(date.getMonth());
}
}
});
} else {
@@ -130,11 +146,17 @@ public abstract class TextualDateConnector<R extends Enum<R>>
}
}

protected abstract boolean isResolutionAboveMonth();
/**
* Returns {@code true} is the current resolution of the widget is month or
* less specific (e.g. month, year, quarter, etc).
*
* @return {@code true} if the current resolution is above month
*/
protected abstract boolean isResolutionMonthOrHigher();

@Override
public VAbstractPopupCalendar<R> getWidget() {
return (VAbstractPopupCalendar<R>) super.getWidget();
public VAbstractPopupCalendar<PANEL, R> getWidget() {
return (VAbstractPopupCalendar<PANEL, R>) super.getWidget();
}

@Override

+ 74
- 0
server/src/main/java/com/vaadin/data/converter/LocalDateTimeToDateConverter.java View File

@@ -0,0 +1,74 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.data.converter;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.Objects;

import com.vaadin.data.Converter;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;
import com.vaadin.ui.DateTimeField;
import com.vaadin.ui.InlineDateTimeField;

/**
* A converter that converts between <code>LocalDateTime</code> and
* <code>Date</code>. This is used when a {@link DateTimeField} or
* {@link InlineDateTimeField} is bound to a {@link Date} property.
*
* @author Vaadin Ltd
*/
public class LocalDateTimeToDateConverter
implements Converter<LocalDateTime, Date> {

private ZoneOffset zoneOffset;

/**
* Creates a new converter using the given time zone.
*
* @param zoneOffset
* the time zone offset to use, not <code>null</code>
*/
public LocalDateTimeToDateConverter(ZoneOffset zoneOffset) {
this.zoneOffset = Objects.requireNonNull(zoneOffset,
"Zone offset cannot be null");
}

@Override
public Result<Date> convertToModel(LocalDateTime localDate,
ValueContext context) {
if (localDate == null) {
return Result.ok(null);
}

return Result.ok(Date.from(localDate.toInstant(zoneOffset)));
}

@Override
public LocalDateTime convertToPresentation(Date date,
ValueContext context) {
if (date == null) {
return null;
}

return Instant.ofEpochMilli(date.getTime()).atZone(zoneOffset)
.toLocalDateTime();
}

}

+ 51
- 0
server/src/main/java/com/vaadin/data/validator/DateTimeRangeValidator.java View File

@@ -0,0 +1,51 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.data.validator;

import java.time.LocalDateTime;
import java.util.Comparator;

/**
* Validator for validating that a {@link LocalDateTime} is inside a given
* range.
*
* @author Vaadin Ltd.
* @since 8.0
*/
public class DateTimeRangeValidator extends RangeValidator<LocalDateTime> {

/**
* Creates a validator for checking that a {@link LocalDateTime} is within a
* given range.
* <p>
* By default the range is inclusive i.e. both minValue and maxValue are
* valid values. Use {@link #setMinValueIncluded(boolean)} or
* {@link #setMaxValueIncluded(boolean)} to change it.
* </p>
*
* @param errorMessage
* the message to display in case the value does not validate.
* @param minValue
* The minimum value to accept or null for no limit
* @param maxValue
* The maximum value to accept or null for no limit
*/
public DateTimeRangeValidator(String errorMessage, LocalDateTime minValue,
LocalDateTime maxValue) {
super(errorMessage, Comparator.naturalOrder(), minValue, maxValue);
}

}

+ 4
- 0
server/src/main/java/com/vaadin/ui/AbstractLocalDateField.java View File

@@ -27,7 +27,11 @@ import com.vaadin.shared.ui.datefield.AbstractTextualDateFieldState;
import com.vaadin.shared.ui.datefield.DateResolution;

/**
* Abstract DateField class for {@link LocalDate} type.
*
* @author Vaadin Ltd
*
* @since 8.0
*
*/
public abstract class AbstractLocalDateField

+ 113
- 5
server/src/main/java/com/vaadin/ui/AbstractLocalDateTimeField.java View File

@@ -15,14 +15,24 @@
*/
package com.vaadin.ui;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Map;

import com.vaadin.data.validator.DateTimeRangeValidator;
import com.vaadin.data.validator.RangeValidator;
import com.vaadin.shared.ui.datefield.AbstractTextualDateFieldState;
import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.shared.ui.datefield.LocalDateTimeFieldState;

/**
* Abstract DateField class for {@link LocalDateTime} type.
*
* @author Vaadin Ltd
*
* @since 8.0
*/
public abstract class AbstractLocalDateTimeField
extends AbstractDateField<LocalDateTime, DateTimeResolution> {
@@ -45,14 +55,112 @@ public abstract class AbstractLocalDateTimeField
super(caption, DateTimeResolution.MINUTE);
}

/**
* Constructs a new <code>AbstractLocalDateTimeField</code> with the given
* caption and initial text contents.
*
* @param caption
* the caption <code>String</code> for the editor.
* @param value
* the LocalDateTime value.
*/
public AbstractLocalDateTimeField(String caption, LocalDateTime value) {
super(caption, value, DateTimeResolution.MINUTE);
}

@Override
protected AbstractTextualDateFieldState getState() {
return (AbstractTextualDateFieldState) super.getState();
}

@Override
protected AbstractTextualDateFieldState getState(boolean markAsDirty) {
return (AbstractTextualDateFieldState) super.getState(markAsDirty);
}

@Override
protected LocalDateTimeFieldState getState() {
return (LocalDateTimeFieldState) super.getState();
protected int getDatePart(LocalDateTime date,
DateTimeResolution resolution) {
LocalDateTime value = date;
if (value == null) {
value = LocalDateTime.of(1, 1, 1, 0, 0);
}
switch (resolution) {
case DAY:
return value.getDayOfMonth();
case MONTH:
return value.getMonthValue();
case YEAR:
return value.getYear();
case HOUR:
return value.getHour();
case MINUTE:
return value.getMinute();
case SECOND:
return value.getSecond();
default:
assert false : "Unexpected resolution argument " + resolution;
return -1;
}
}

@Override
protected LocalDateTimeFieldState getState(boolean markAsDirty) {
return (LocalDateTimeFieldState) super.getState(markAsDirty);
protected RangeValidator<LocalDateTime> getRangeValidator() {
return new DateTimeRangeValidator(getDateOutOfRangeMessage(),
getDate(getRangeStart(), getResolution()),
getDate(getRangeEnd(), getResolution()));
}

@Override
protected LocalDateTime buildDate(
Map<DateTimeResolution, Integer> resolutionValues) {
return LocalDateTime.of(resolutionValues.get(DateTimeResolution.YEAR),
resolutionValues.getOrDefault(DateTimeResolution.MONTH, 1),
resolutionValues.getOrDefault(DateTimeResolution.DAY, 1),
resolutionValues.getOrDefault(DateTimeResolution.HOUR, 0),
resolutionValues.getOrDefault(DateTimeResolution.MINUTE, 0),
resolutionValues.getOrDefault(DateTimeResolution.SECOND, 0));
}

@Override
protected LocalDateTime convertFromDate(Date date) {
if (date == null) {
return null;
}
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneOffset.UTC)
.toLocalDateTime();
}

@Override
protected Date convertToDate(LocalDateTime date) {
if (date == null) {
return null;
}
return Date.from(date.toInstant(ZoneOffset.UTC));
}

private LocalDateTime getDate(LocalDateTime date,
DateTimeResolution forResolution) {
if (date == null) {
return null;
}
switch (forResolution) {
case YEAR:
return date.withDayOfYear(1).toLocalDate().atStartOfDay();
case MONTH:
return date.withDayOfMonth(1).toLocalDate().atStartOfDay();
case DAY:
return date.toLocalDate().atStartOfDay();
case HOUR:
return date.truncatedTo(ChronoUnit.HOURS);
case MINUTE:
return date.truncatedTo(ChronoUnit.MINUTES);
case SECOND:
return date.truncatedTo(ChronoUnit.SECONDS);
default:
assert false : "Unexpected resolution argument " + forResolution;
return null;
}
}

}

+ 139
- 0
server/src/main/java/com/vaadin/ui/DateTimeField.java View File

@@ -0,0 +1,139 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.ui;

import java.time.LocalDateTime;

import com.vaadin.shared.ui.datefield.LocalDateTimeFieldState;

/**
* A date time entry component, which displays the actual date selector as a
* popup.
*
* @see AbstractLocalDateTimeField
* @see InlineDateTimeField
* @author Vaadin Ltd.
* @since 8.0
*/
public class DateTimeField extends AbstractLocalDateTimeField {

/**
* Constructs an empty <code>DateTimeField</code> with no caption.
*/
public DateTimeField() {
super();
}

/**
* Constructs a new <code>DateTimeField</code> with the given caption and
* initial text contents.
*
* @param caption
* the caption <code>String</code> for the editor.
* @param value
* the LocalDateTime value.
*/
public DateTimeField(String caption, LocalDateTime value) {
super(caption, value);
}

/**
* Constructs an empty <code>DateTimeField</code> with caption.
*
* @param caption
* the caption of the datefield.
*/
public DateTimeField(String caption) {
super(caption);
}

/**
* Returns the current placeholder text.
*
* @see #setPlaceholder(String)
* @return the placeholder text
*/
public String getPlaceholder() {
return getState(false).placeholder;
}

/**
* Sets the placeholder text. The placeholder is text that is displayed when
* the field would otherwise be empty, to prompt the user for input.
*
* @param placeholder
* the placeholder text to set
*/
public void setPlaceholder(String placeholder) {
getState().placeholder = placeholder;
}

@Override
protected LocalDateTimeFieldState getState() {
return (LocalDateTimeFieldState) super.getState();
}

@Override
protected LocalDateTimeFieldState getState(boolean markAsDirty) {
return (LocalDateTimeFieldState) super.getState(markAsDirty);
}

/**
* Checks whether the text field is enabled (default) or not.
*
* @see #setTextFieldEnabled(boolean)
*
* @return <b>true</b> if the text field is enabled, <b>false</b> otherwise.
*/
public boolean isTextFieldEnabled() {
return getState(false).textFieldEnabled;
}

/**
* Enables or disables the text field. By default the text field is enabled.
* Disabling it causes only the button for date selection to be active, thus
* preventing the user from entering invalid dates.
*
* See {@link http://dev.vaadin.com/ticket/6790}.
*
* @param state
* <b>true</b> to enable text field, <b>false</b> to disable it.
*/
public void setTextFieldEnabled(boolean state) {
getState().textFieldEnabled = state;
}

/**
* Set a description that explains the usage of the Widget for users of
* assistive devices.
*
* @param description
* String with the description
*/
public void setAssistiveText(String description) {
getState().descriptionForAssistiveDevices = description;
}

/**
* Get the description that explains the usage of the Widget for users of
* assistive devices.
*
* @return String with the description
*/
public String getAssistiveText() {
return getState(false).descriptionForAssistiveDevices;
}
}

+ 71
- 0
server/src/main/java/com/vaadin/ui/InlineDateTimeField.java View File

@@ -0,0 +1,71 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.ui;

import java.time.LocalDateTime;

import com.vaadin.shared.ui.datefield.InlineDateTimeFieldState;

/**
* A date time entry component, which displays the actual date selector inline.
*
* @see AbstractLocalDateTimeField
* @see DateTimeField
* @author Vaadin Ltd.
* @since 8.0
*/
public class InlineDateTimeField extends AbstractLocalDateTimeField {

/**
* Constructs an empty <code>InlineDateTimeField</code> with no caption.
*/
public InlineDateTimeField() {
super();
}

/**
* Constructs a new <code>InlineDateTimeField</code> with the given caption
* and initial text contents.
*
* @param caption
* the caption <code>String</code> for the editor.
* @param value
* the LocalDate value.
*/
public InlineDateTimeField(String caption, LocalDateTime value) {
super(caption, value);
}

/**
* Constructs an empty <code>InlineDateTimeField</code> with caption.
*
* @param caption
* the caption of the datefield.
*/
public InlineDateTimeField(String caption) {
super(caption);
}

@Override
protected InlineDateTimeFieldState getState() {
return (InlineDateTimeFieldState) super.getState();
}

@Override
protected InlineDateTimeFieldState getState(boolean markAsDirty) {
return (InlineDateTimeFieldState) super.getState(markAsDirty);
}
}

+ 4
- 0
server/src/main/java/com/vaadin/ui/declarative/DesignFormatter.java View File

@@ -21,6 +21,7 @@ import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;
import java.util.Locale;
@@ -42,6 +43,7 @@ import com.vaadin.server.Resource;
import com.vaadin.ui.declarative.converters.DesignDateConverter;
import com.vaadin.ui.declarative.converters.DesignEnumConverter;
import com.vaadin.ui.declarative.converters.DesignLocalDateConverter;
import com.vaadin.ui.declarative.converters.DesignLocalDateTimeConverter;
import com.vaadin.ui.declarative.converters.DesignObjectConverter;
import com.vaadin.ui.declarative.converters.DesignResourceConverter;
import com.vaadin.ui.declarative.converters.DesignShortcutActionConverter;
@@ -178,6 +180,8 @@ public class DesignFormatter implements Serializable {

converterMap.put(Date.class, new DesignDateConverter());
converterMap.put(LocalDate.class, new DesignLocalDateConverter());
converterMap.put(LocalDateTime.class,
new DesignLocalDateTimeConverter());
converterMap.put(ShortcutAction.class,
new DesignShortcutActionConverter());
converterMap.put(Resource.class, new DesignResourceConverter());

+ 68
- 0
server/src/main/java/com/vaadin/ui/declarative/converters/DesignLocalDateTimeConverter.java View File

@@ -0,0 +1,68 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.ui.declarative.converters;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;

import com.vaadin.data.Converter;
import com.vaadin.data.Result;
import com.vaadin.data.ValueContext;
import com.vaadin.ui.declarative.DesignAttributeHandler;

/**
* A {@link LocalDate} converter to be used by {@link DesignAttributeHandler}.
* Provides ISO-compliant way of storing date and time.
*
* @since 8.0
* @author Vaadin Ltd
*/
public class DesignLocalDateTimeConverter
implements Converter<String, LocalDateTime> {

@Override
public Result<LocalDateTime> convertToModel(String value,
ValueContext context) {
for (String pattern : new String[] { "yyyy-MM-dd HH:mm:ssZ",
"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH",
"yyyy-MM-dd", "yyyy-MM", "yyyy" }) {
try {
Locale effectiveLocale = context.getLocale()
.orElse(Locale.ENGLISH);
LocalDateTime date = DateTimeFormatter
.ofPattern(pattern, effectiveLocale)
.parse(value, LocalDateTime::from);
return Result.ok(date);
} catch (DateTimeParseException ignored) {
// not parseable, ignore and try another format
}
}
return Result.error("Could not parse date value: " + value);
}

@Override
public String convertToPresentation(LocalDateTime value,
ValueContext context) {
return DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss",
context.getLocale().orElse(Locale.ENGLISH))
.format(value);
}

}

+ 99
- 0
server/src/test/java/com/vaadin/tests/data/converter/LocalDateTimeToDateConverterTest.java View File

@@ -0,0 +1,99 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.data.converter;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.junit.Assert;
import org.junit.Test;

import com.vaadin.data.Binder;
import com.vaadin.data.ValidationException;
import com.vaadin.data.ValueContext;
import com.vaadin.data.converter.LocalDateTimeToDateConverter;
import com.vaadin.ui.DateTimeField;

public class LocalDateTimeToDateConverterTest extends AbstractConverterTest {

private static final LocalDateTime LOCAL_DATE = LocalDateTime.of(2017, 1, 1,
1, 1, 1);
private static final Date DATE = createDate();

@Override
protected LocalDateTimeToDateConverter getConverter() {
return new LocalDateTimeToDateConverter(ZoneOffset.UTC);
}

@Test
public void testToModel() {
assertValue(DATE,
getConverter().convertToModel(LOCAL_DATE, new ValueContext()));
}

@Test
public void testToModelFromSqlDate() {
// Check that SQL dates also work (e.g. java.sql.Date.toInstant throws)
assertValue(new java.sql.Date(DATE.getTime()),
getConverter().convertToModel(LOCAL_DATE, new ValueContext()));
}

@Test
public void testToPresentation() {
Assert.assertEquals(LOCAL_DATE,
getConverter().convertToPresentation(DATE, new ValueContext()));
}

@Test
public void useWithBinder() throws ValidationException {
Binder<BeanWithDate> binder = new Binder<>();
DateTimeField dateField = new DateTimeField();

binder.forField(dateField).withConverter(getConverter())
.bind(BeanWithDate::getDate, BeanWithDate::setDate);

dateField.setValue(LOCAL_DATE);

BeanWithDate bean = new BeanWithDate();
binder.writeBean(bean);

Assert.assertEquals(DATE, bean.getDate());
}

public static class BeanWithDate {
private Date date;

public void setDate(Date date) {
this.date = date;
}

public Date getDate() {
return date;
}
}

private static Date createDate() {
Calendar calendar = Calendar
.getInstance(TimeZone.getTimeZone(ZoneOffset.UTC));
calendar.clear();
calendar.set(2017, Calendar.JANUARY, 1, 1, 1, 1);
return calendar.getTime();
}

}

+ 110
- 0
server/src/test/java/com/vaadin/tests/server/component/abstractdatefield/AbstractLocalDateTimeFieldDeclarativeTest.java View File

@@ -0,0 +1,110 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.server.component.abstractdatefield;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

import org.junit.Test;

import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.tests.server.component.abstractfield.AbstractFieldDeclarativeTest;
import com.vaadin.ui.AbstractLocalDateTimeField;

/**
* Abstract test class which contains tests for declarative format for
* properties that are common for AbstractDateField.
* <p>
* It's an abstract so it's not supposed to be run as is. Instead each
* declarative test for a real component should extend it and implement abstract
* methods to be able to test the common properties. Components specific
* properties should be tested additionally in the subclasses implementations.
*
* @author Vaadin Ltd
*
*/
public abstract class AbstractLocalDateTimeFieldDeclarativeTest<T extends AbstractLocalDateTimeField>
extends AbstractFieldDeclarativeTest<T, LocalDateTime> {

protected DateTimeFormatter DATE_FORMATTER = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);

@Override
public void valueDeserialization()
throws InstantiationException, IllegalAccessException {
LocalDateTime value = LocalDateTime.of(2003, 02, 27, 10, 37, 43);
String design = String.format("<%s value='%s'/>", getComponentTag(),
DATE_FORMATTER.format(value));

T component = getComponentClass().newInstance();
component.setValue(value);

testRead(design, component);
testWrite(design, component);
}

@Test
public void abstractDateFieldAttributesDeserialization()
throws InstantiationException, IllegalAccessException {
boolean showIsoWeeks = true;
LocalDateTime end = LocalDateTime.of(2019, 02, 27, 10, 37, 43);
LocalDateTime start = LocalDateTime.of(2001, 02, 27, 23, 12, 34);
String dateOutOfRange = "test date out of range";
DateTimeResolution resolution = DateTimeResolution.HOUR;
String dateFormat = "test format";
boolean lenient = true;
String parseErrorMsg = "test parse error";
String design = String.format(
"<%s show-iso-week-numbers range-end='%s' range-start='%s' "
+ "date-out-of-range-message='%s' resolution='%s' "
+ "date-format='%s' lenient parse-error-message='%s'/>",
getComponentTag(), DATE_FORMATTER.format(end),
DATE_FORMATTER.format(start), dateOutOfRange,
resolution.name().toLowerCase(Locale.ENGLISH), dateFormat,
parseErrorMsg);

T component = getComponentClass().newInstance();

component.setShowISOWeekNumbers(showIsoWeeks);
component.setRangeEnd(end);
component.setRangeStart(start);
component.setDateOutOfRangeMessage(dateOutOfRange);
component.setResolution(resolution);
component.setDateFormat(dateFormat);
component.setLenient(lenient);
component.setParseErrorMessage(parseErrorMsg);

testRead(design, component);
testWrite(design, component);
}

@Override
public void readOnlyValue()
throws InstantiationException, IllegalAccessException {
LocalDateTime value = LocalDateTime.of(2003, 02, 27, 23, 12, 34);
String design = String.format("<%s value='%s' readonly/>",
getComponentTag(), DATE_FORMATTER.format(value));

T component = getComponentClass().newInstance();
component.setValue(value);
component.setReadOnly(true);

testRead(design, component);
testWrite(design, component);
}

}

+ 2
- 0
server/src/test/java/com/vaadin/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java View File

@@ -62,9 +62,11 @@ public abstract class AbstractFieldDeclarativeTest<T extends AbstractField<V>, V
testWrite(design, component);
}

@Test
public abstract void valueDeserialization()
throws InstantiationException, IllegalAccessException;

@Test
public abstract void readOnlyValue()
throws InstantiationException, IllegalAccessException;
}

+ 3
- 2
server/src/test/java/com/vaadin/tests/server/component/colorpicker/AbstractColorPickerDeclarativeTest.java View File

@@ -75,7 +75,8 @@ public abstract class AbstractColorPickerDeclarativeTest<T extends AbstractColor
public void valueDeserialization()
throws InstantiationException, IllegalAccessException {
String rgb = "fafafa";
String design = String.format("<%s color='#%s'/>", getComponentTag());
String design = String.format("<%s color='#%s'/>", getComponentTag(),
rgb);

T colorPicker = getComponentClass().newInstance();
int colorInt = Integer.parseInt(rgb, 16);
@@ -91,7 +92,7 @@ public abstract class AbstractColorPickerDeclarativeTest<T extends AbstractColor
throws InstantiationException, IllegalAccessException {
String rgb = "fafafa";
String design = String.format("<%s color='#%s' readonly/>",
getComponentTag());
getComponentTag(), rgb);

T colorPicker = getComponentClass().newInstance();
int colorInt = Integer.parseInt(rgb, 16);

+ 63
- 0
server/src/test/java/com/vaadin/tests/server/component/datefield/DateTimeFieldDeclarativeTest.java View File

@@ -0,0 +1,63 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.server.component.datefield;

import org.junit.Test;

import com.vaadin.tests.server.component.abstractdatefield.AbstractLocalDateTimeFieldDeclarativeTest;
import com.vaadin.ui.DateTimeField;

/**
* Tests the declarative support for implementations of {@link DateTimeField}.
*
* @since 8.0
* @author Vaadin Ltd
*/
public class DateTimeFieldDeclarativeTest
extends AbstractLocalDateTimeFieldDeclarativeTest<DateTimeField> {

@Test
public void remainingAttributes()
throws InstantiationException, IllegalAccessException {
String placeholder = "foo";
String assistiveText = "at";
boolean textFieldEnabled = false;
String design = String.format(
"<%s placeholder='%s' "
+ "assistive-text='%s' text-field-enabled='%s'/>",
getComponentTag(), placeholder, assistiveText,
textFieldEnabled);

DateTimeField component = getComponentClass().newInstance();
component.setPlaceholder(placeholder);
component.setTextFieldEnabled(textFieldEnabled);
component.setAssistiveText(assistiveText);

testRead(design, component);
testWrite(design, component);
}

@Override
protected String getComponentTag() {
return "vaadin-date-time-field";
}

@Override
protected Class<? extends DateTimeField> getComponentClass() {
return DateTimeField.class;
}

}

+ 71
- 0
server/src/test/java/com/vaadin/tests/server/component/datefield/InlineDateTimeFieldDeclarativeTest.java View File

@@ -0,0 +1,71 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.server.component.datefield;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.time.LocalDateTime;

import org.junit.Test;

import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.tests.server.component.abstractdatefield.AbstractLocalDateTimeFieldDeclarativeTest;
import com.vaadin.ui.AbstractDateField;
import com.vaadin.ui.InlineDateTimeField;
import com.vaadin.ui.declarative.Design;

/**
* Tests the declarative support for implementations of
* {@link AbstractDateField}.
*
* @since 7.4
* @author Vaadin Ltd
*/
public class InlineDateTimeFieldDeclarativeTest
extends AbstractLocalDateTimeFieldDeclarativeTest<InlineDateTimeField> {

@Test
public void testInlineDateFieldToFromDesign() throws Exception {
InlineDateTimeField field = new InlineDateTimeField("Day is",
LocalDateTime.of(2003, 2, 27, 4, 13, 45));
field.setShowISOWeekNumbers(true);
field.setRangeStart(LocalDateTime.of(2001, 2, 27, 6, 12, 53));
field.setRangeEnd(LocalDateTime.of(20011, 2, 27, 3, 43, 23));
field.setResolution(DateTimeResolution.SECOND);

ByteArrayOutputStream bos = new ByteArrayOutputStream();
Design.write(field, bos);

InlineDateTimeField result = (InlineDateTimeField) Design
.read(new ByteArrayInputStream(bos.toByteArray()));
assertEquals(field.getResolution(), result.getResolution());
assertEquals(field.getCaption(), result.getCaption());
assertEquals(field.getValue(), result.getValue());
assertEquals(field.getRangeStart(), result.getRangeStart());
assertEquals(field.getRangeEnd(), result.getRangeEnd());
}

@Override
protected String getComponentTag() {
return "vaadin-inline-date-time-field";
}

@Override
protected Class<? extends InlineDateTimeField> getComponentClass() {
return InlineDateTimeField.class;
}

}

+ 1
- 1
shared/src/main/java/com/vaadin/shared/ui/datefield/DateTimeResolution.java View File

@@ -16,7 +16,7 @@
package com.vaadin.shared.ui.datefield;

/**
* Resolutions for DateTimeFields
* Resolutions for DateTimeFields.
*
* @author Vaadin Ltd.
* @since 8.0

+ 26
- 0
shared/src/main/java/com/vaadin/shared/ui/datefield/InlineDateTimeFieldState.java View File

@@ -0,0 +1,26 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.shared.ui.datefield;

/**
* @author Vaadin Ltd
*
*/
public class InlineDateTimeFieldState extends AbstractTextualDateFieldState {
{
primaryStyleName = "v-inline-datefield";
}
}

+ 1
- 1
shared/src/main/java/com/vaadin/shared/ui/datefield/LocalDateTimeFieldState.java View File

@@ -21,6 +21,6 @@ package com.vaadin.shared.ui.datefield;
* @author Vaadin Ltd
*
*/
public class LocalDateTimeFieldState extends AbstractTextualDateFieldState {
public class LocalDateTimeFieldState extends TextualDateFieldState {

}

+ 1
- 1
tests/screenshots

@@ -1 +1 @@
Subproject commit 203312a80a5f76d48fc36ef8d215f8b70b8e7545
Subproject commit e9f8b30d0db8076f24c9253f078b2931f0ecd3fa

+ 27
- 0
uitest-common/src/main/java/com/vaadin/testbench/customelements/DateTimeFieldElement.java View File

@@ -0,0 +1,27 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.testbench.customelements;

import com.vaadin.testbench.elementsbase.ServerClass;

/**
* @author Vaadin Ltd
*
*/
@ServerClass("com.vaadin.ui.DateTimeField")
public class DateTimeFieldElement extends DateFieldElement {

}

+ 28
- 0
uitest-common/src/main/java/com/vaadin/testbench/customelements/InlineDateTimeFieldElement.java View File

@@ -0,0 +1,28 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.testbench.customelements;

import com.vaadin.testbench.elements.InlineDateFieldElement;
import com.vaadin.testbench.elementsbase.ServerClass;

/**
* @author Vaadin Ltd
*
*/
@ServerClass("com.vaadin.ui.InlineDateTimeField")
public class InlineDateTimeFieldElement extends InlineDateFieldElement {

}

+ 1
- 8
uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateFieldTest.java View File

@@ -7,19 +7,12 @@ import java.util.LinkedHashMap;
import java.util.Locale;

import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.tests.components.TestDateField;
import com.vaadin.tests.components.abstractfield.AbstractFieldTest;
import com.vaadin.ui.AbstractLocalDateField;

public class AbstractDateFieldTest<T extends AbstractLocalDateField>
public abstract class AbstractDateFieldTest<T extends AbstractLocalDateField>
extends AbstractFieldTest<T, LocalDate> {

@SuppressWarnings("unchecked")
@Override
protected Class<T> getTestClass() {
return (Class<T>) TestDateField.class;
}

private Command<T, LocalDate> setValue = new Command<T, LocalDate>() {

@Override

+ 130
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/AbstractDateTimeFieldTest.java View File

@@ -0,0 +1,130 @@
package com.vaadin.tests.components.datefield;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.Locale;

import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.tests.components.abstractfield.AbstractFieldTest;
import com.vaadin.ui.AbstractLocalDateTimeField;

public abstract class AbstractDateTimeFieldTest<T extends AbstractLocalDateTimeField>
extends AbstractFieldTest<T, LocalDateTime> {

private Command<T, LocalDateTime> setValue = new Command<T, LocalDateTime>() {

@Override
public void execute(T c, LocalDateTime value, Object data) {
c.setValue(value);
}
};

@Override
protected void createActions() {
super.createActions();
createResolutionSelectAction(CATEGORY_FEATURES);
createBooleanAction("Lenient", CATEGORY_FEATURES, false,
lenientCommand);
createBooleanAction("Show week numbers", CATEGORY_FEATURES, false,
weekNumberCommand);
createDateFormatSelectAction(CATEGORY_FEATURES);
createSetValueAction(CATEGORY_FEATURES);

}

private void createSetValueAction(String category) {
LinkedHashMap<String, LocalDateTime> options = new LinkedHashMap<>();
options.put("(null)", null);
options.put("(current time)", LocalDateTime.now());
options.put("2010-12-12", LocalDateTime.of(2010, 12, 12, 6, 34, 23));
createMultiClickAction("Set value", category, options, setValue, null);
}

private void createDateFormatSelectAction(String category) {
LinkedHashMap<String, String> options = new LinkedHashMap<>();

options.put("-", null);
options.put("d M yyyy", "d M yyyy");
options.put("d MM yyyy", "d MM yyyy");
options.put("d MMM yyyy", "d MMM yyyy");
options.put("d MMMM yyyy", "d MMMM yyyy");
options.put("dd M yyyy", "dd M yyyy");
options.put("ddd M yyyy", "ddd M yyyy");
options.put("d M y", "d M y");
options.put("d M yy", "d M yy");
options.put("d M yyy", "d M yyy");
options.put("d M yyyy", "d M yyyy");
options.put("d M 'custom text' yyyy", "d M 'custom text' yyyy");
options.put("'day:'d', month:'M', year: 'yyyy",
"'day:'d', month:'M', year: 'yyyy");
options.put(getDatePattern(new Locale("fi", "FI"), DateFormat.LONG),
getDatePattern(new Locale("fi", "FI"), DateFormat.LONG));
options.put(getDatePattern(new Locale("fi", "FI"), DateFormat.MEDIUM),
getDatePattern(new Locale("fi", "FI"), DateFormat.MEDIUM));
options.put(getDatePattern(new Locale("fi", "FI"), DateFormat.SHORT),
getDatePattern(new Locale("fi", "FI"), DateFormat.SHORT));

createSelectAction("Date format", category, options, "-",
dateFormatCommand);

}

private String getDatePattern(Locale locale, int dateStyle) {
DateFormat dateFormat = DateFormat.getDateInstance(dateStyle, locale);

if (dateFormat instanceof SimpleDateFormat) {
String pattern = ((SimpleDateFormat) dateFormat).toPattern();
return pattern;
}
return null;

}

private void createResolutionSelectAction(String category) {
LinkedHashMap<String, DateTimeResolution> options = new LinkedHashMap<>();
options.put("Year", DateTimeResolution.YEAR);
options.put("Month", DateTimeResolution.MONTH);
options.put("Day", DateTimeResolution.DAY);
options.put("Hour", DateTimeResolution.HOUR);
options.put("Min", DateTimeResolution.MINUTE);
options.put("Sec", DateTimeResolution.SECOND);

createSelectAction("Resolution", category, options, "Year",
resolutionCommand);
}

private Command<T, DateTimeResolution> resolutionCommand = new Command<T, DateTimeResolution>() {

@Override
public void execute(T c, DateTimeResolution value, Object data) {
c.setResolution(value);

}
};
private Command<T, Boolean> lenientCommand = new Command<T, Boolean>() {

@Override
public void execute(T c, Boolean value, Object data) {
c.setLenient(false);

}
};
private Command<T, Boolean> weekNumberCommand = new Command<T, Boolean>() {

@Override
public void execute(T c, Boolean value, Object data) {
c.setShowISOWeekNumbers(value);

}
};
private Command<T, String> dateFormatCommand = new Command<T, String>() {

@Override
public void execute(T c, String value, Object data) {
c.setDateFormat(value);
}
};

}

+ 49
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/AriaDateTimeDisabled.java View File

@@ -0,0 +1,49 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.ui.DateTimeField;
import com.vaadin.ui.VerticalLayout;

public class AriaDateTimeDisabled extends AbstractReindeerTestUI {

@Override
protected void setup(VaadinRequest request) {
VerticalLayout content = new VerticalLayout();
content.setMargin(true);
content.setSpacing(true);

final DateTimeField disabledDateField = new DateTimeField(
"Disabled DateField");
disabledDateField.setEnabled(false);

setContent(content);
content.addComponent(disabledDateField);
content.addComponent(new DateTimeField("Enabled DateField"));
}

@Override
protected String getTestDescription() {
return "Test for aria-disabled attribute on DateField.";
}

@Override
protected Integer getTicketNumber() {
return 13463;
}
}

+ 59
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/CustomDateTimeFormat.java View File

@@ -0,0 +1,59 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import java.time.LocalDateTime;
import java.util.Locale;

import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.DateTimeField;

/**
* @author Vaadin Ltd
*
*/
public class CustomDateTimeFormat extends AbstractTestUI {

@Override
protected void setup(VaadinRequest request) {
setLocale(new Locale("fi", "FI"));

DateTimeField field = new DateTimeField();
field.setResolution(DateTimeResolution.SECOND);
field.setWidth("300px");

String pattern = "d. MMMM'ta 'yyyy 'klo 'H.mm.ss";
field.setDateFormat(pattern);

field.setValue(LocalDateTime.of(2010, 1, 1, 12, 23, 45));

addComponent(field);

}

@Override
protected String getTestDescription() {
return "Month name should be visible in text box if format pattern includes it";
}

@Override
protected Integer getTicketNumber() {
return 3490;
}

}

+ 11
- 14
uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldDayResolutionOffset.java View File

@@ -1,18 +1,17 @@
package com.vaadin.tests.components.datefield;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.tests.components.TestDateField;
import com.vaadin.ui.AbstractDateField;
import com.vaadin.ui.DateTimeField;
import com.vaadin.ui.Label;

public class DateFieldDayResolutionOffset extends AbstractReindeerTestUI {

private final String initialDateString = "09/01/2014";
private final String initialDateString = "09/01/2014 00:00:00";

@Override
protected void setup(VaadinRequest request) {
@@ -20,8 +19,7 @@ public class DateFieldDayResolutionOffset extends AbstractReindeerTestUI {
dateValue.setId("dateValue");

final DateTimeFormatter dateformat = getDateFormat();
final AbstractDateField<LocalDate, DateResolution> dateField = getDateField(
dateformat);
final DateTimeField dateField = getDateField(dateformat);

addComponent(dateValue);
addComponent(dateField);
@@ -30,19 +28,18 @@ public class DateFieldDayResolutionOffset extends AbstractReindeerTestUI {
.setValue(dateformat.format(dateField.getValue())));
}

private AbstractDateField<LocalDate, DateResolution> getDateField(
DateTimeFormatter dateformat) {
final AbstractDateField<LocalDate, DateResolution> dateField = new TestDateField();
LocalDate initialDate = dateformat.parse(initialDateString,
LocalDate::from);
dateField.setResolution(DateResolution.DAY);
private DateTimeField getDateField(DateTimeFormatter dateformat) {
final DateTimeField dateField = new DateTimeField();
LocalDateTime initialDate = dateformat.parse(initialDateString,
LocalDateTime::from);
dateField.setResolution(DateTimeResolution.DAY);
dateField.setValue(initialDate);
return dateField;
}

private DateTimeFormatter getDateFormat() {
final DateTimeFormatter dateformat = DateTimeFormatter
.ofPattern("MM/dd/yyyy");
.ofPattern("MM/dd/yyyy HH:mm:ss");
return dateformat;
}


+ 63
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldChangeResolution.java View File

@@ -0,0 +1,63 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.ui.Button;
import com.vaadin.ui.DateTimeField;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;

public class DateTimeFieldChangeResolution extends AbstractReindeerTestUI {

public static final String DATEFIELD_ID = "datefield";
// The ID of a button is BUTTON_BASE_ID + resolution, e.g. button-month
public static final String BUTTON_BASE_ID = "button-";

@Override
protected void setup(VaadinRequest request) {
final DateTimeField dateField = new DateTimeField("Enter date");
dateField.setResolution(DateTimeResolution.YEAR);
dateField.setId(DATEFIELD_ID);
addComponent(dateField);

Label label = new Label("Select resolution");
addComponent(label);
HorizontalLayout hlayout = new HorizontalLayout();
addComponent(hlayout);
for (final DateTimeResolution value : DateTimeResolution.values()) {
String resolutionString = value.toString().toLowerCase();
Button button = new Button(resolutionString);
button.addClickListener(event -> dateField.setResolution(value));
button.setId(BUTTON_BASE_ID + resolutionString);
hlayout.addComponent(button);
}

}

@Override
protected String getTestDescription() {
return "The calendar should always have the correct resolution and the text field should be empty before selecting a date.";
}

@Override
protected Integer getTicketNumber() {
return 14174;
}

}

+ 24
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldElementUI.java View File

@@ -0,0 +1,24 @@
package com.vaadin.tests.components.datefield;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.ui.DateTimeField;
import com.vaadin.ui.InlineDateTimeField;

public class DateTimeFieldElementUI extends AbstractReindeerTestUI {
@Override
protected void setup(VaadinRequest request) {
addComponent(new DateTimeField());
addComponent(new InlineDateTimeField());
}

@Override
protected Integer getTicketNumber() {
return 17090;
}

@Override
protected String getTestDescription() {
return "DateTimeField should be accessible using TB4 DateTimeFieldElement.";
}
}

+ 39
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldFastForward.java View File

@@ -0,0 +1,39 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.ui.InlineDateTimeField;

public class DateTimeFieldFastForward extends AbstractReindeerTestUI {

@Override
protected void setup(VaadinRequest request) {
addComponent(new InlineDateTimeField());
}

@Override
protected String getTestDescription() {
return "Tests that right-click doesn't interfere with fast-forwarding (holding down left mouse button).";
}

@Override
protected Integer getTicketNumber() {
return 8012;
}

}

+ 53
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldIsValid.java View File

@@ -0,0 +1,53 @@
package com.vaadin.tests.components.datefield;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.DateTimeField;

public class DateTimeFieldIsValid extends AbstractTestUIWithLog {

@Override
protected String getTestDescription() {
return "A dateField with invalid text should return false in isValid both when "
+ "handling ValueChange event and after value is changed.";
}

@Override
protected Integer getTicketNumber() {
return 14487;
}

private String pattern = "dd/MM/yy H.mm";
private DateTimeFormatter format = DateTimeFormatter.ofPattern(pattern);

@Override
protected void setup(VaadinRequest request) {
final DateTimeField dateField = new DateTimeField("Insert Date: ");
dateField.setDateFormat(pattern);

dateField.addValueChangeListener(event -> log("valueChange: value: "
+ format(dateField.getValue()) + ", is valid: "
+ (dateField.getErrorMessage() == null)));
addComponent(dateField);
addButton("check dateField",
event -> log("buttonClick: value: "
+ format(dateField.getValue()) + ", is valid: "
+ (dateField.getErrorMessage() == null)));
}

/**
* @since
* @param value
* @return
*/
protected String format(LocalDateTime value) {
if (value != null) {
return format.format(value);
} else {
return null;
}
}
}

+ 47
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldKeyboardInput.java View File

@@ -0,0 +1,47 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import java.time.LocalDateTime;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.ui.DateTimeField;
import com.vaadin.ui.Label;

public class DateTimeFieldKeyboardInput extends AbstractReindeerTestUI {

@Override
protected void setup(VaadinRequest request) {
final DateTimeField dateField = new DateTimeField("Select date",
LocalDateTime.of(2014, 1, 15, 7, 2));
dateField.setDateFormat("dd.MM.yyyy HH:mm");
addComponent(dateField);
dateField.addValueChangeListener(
event -> addComponent(new Label("Date has been changed.")));
}

@Override
public Integer getTicketNumber() {
return 16677;
}

@Override
public String getTestDescription() {
return "When a new date is entered in the text field using the keyboard, pressing the return key after typing the date, "
+ "a label with the text 'Date has been changed' should appear.";
}
}

+ 45
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldReadOnly.java View File

@@ -0,0 +1,45 @@
package com.vaadin.tests.components.datefield;

import java.time.LocalDateTime;
import java.util.Locale;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.ui.Button;
import com.vaadin.ui.DateTimeField;

public class DateTimeFieldReadOnly extends AbstractReindeerTestUI {

@Override
protected String getTestDescription() {
return "A read-only DateField should not show the popup button and not be editable.";
}

@Override
protected Integer getTicketNumber() {
return 3163;
}

@Override
protected void setup(VaadinRequest request) {
final DateTimeField timeField = new DateTimeField(
"A read-only datefield");
timeField.setCaption(null);
timeField.setIcon(null);
timeField.setWidth("15em");
timeField.addStyleName("timeField");
timeField.setLocale(new Locale("fi"));

// Set date so that testing always has same time
timeField.setValue(LocalDateTime.of(2009, 6, 12, 7, 34));
timeField.setReadOnly(true);

addComponent(timeField);

Button b = new Button("Switch read-only");
b.addClickListener(
event -> timeField.setReadOnly(!timeField.isReadOnly()));

addComponent(b);
}
}

+ 64
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/DateTimeFieldTest.java View File

@@ -0,0 +1,64 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import java.util.LinkedHashMap;

import com.vaadin.ui.DateTimeField;

/**
* @author Vaadin Ltd
*
*/
public class DateTimeFieldTest
extends AbstractDateTimeFieldTest<DateTimeField> {

@Override
protected Class<DateTimeField> getTestClass() {
return DateTimeField.class;
}

@Override
protected void createActions() {
super.createActions();

createInputPromptSelectAction(CATEGORY_FEATURES);
createTextEnabledAction(CATEGORY_FEATURES);
}

private void createInputPromptSelectAction(String category) {
LinkedHashMap<String, String> options = new LinkedHashMap<>();
options.put("<none>", null);
options.put("Please enter date", "Please enter date");
options.put("åäöÅÄÖ", "åäöÅÄÖ");

createSelectAction("Input prompt", category, options, "<none>",
new Command<DateTimeField, String>() {

@Override
public void execute(DateTimeField c, String value,
Object data) {
c.setPlaceholder(value);

}
});
}

private void createTextEnabledAction(String category) {
this.createBooleanAction("Text field enabled", category, true,
(field, value, data) -> field.setTextFieldEnabled(value));
}
}

+ 50
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/DisabledInlineDateTimeField.java View File

@@ -0,0 +1,50 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import java.time.LocalDateTime;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.ui.InlineDateTimeField;

public class DisabledInlineDateTimeField extends AbstractReindeerTestUI {

@Override
protected void setup(VaadinRequest request) {
InlineDateTimeField df = new InlineDateTimeField("Disabled");
LocalDateTime date = LocalDateTime.of(2014, 6, 5, 11, 34);
df.setValue(date);
df.setEnabled(false);
addComponent(df);

df = new InlineDateTimeField("Read-only");
df.setValue(date);
df.setReadOnly(true);
addComponent(df);
}

@Override
protected String getTestDescription() {
return "Testing disabled and read-only modes of InlineDateField.";
}

@Override
protected Integer getTicketNumber() {
return 10262;
}

}

+ 32
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/InlineDateTimeFieldTest.java View File

@@ -0,0 +1,32 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import com.vaadin.ui.InlineDateTimeField;

/**
* @author Vaadin Ltd
*
*/
public class InlineDateTimeFieldTest
extends AbstractDateTimeFieldTest<InlineDateTimeField> {

@Override
protected Class<InlineDateTimeField> getTestClass() {
return InlineDateTimeField.class;
}

}

+ 68
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/PopupDateTimeFieldStates.java View File

@@ -0,0 +1,68 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import java.time.LocalDateTime;
import java.util.Locale;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.DateTimeField;
import com.vaadin.ui.GridLayout;

/**
* @author Vaadin Ltd
*
*/
public class PopupDateTimeFieldStates extends AbstractTestUI {

@Override
protected void setup(VaadinRequest request) {
setLocale(Locale.ENGLISH);
final GridLayout gridLayout = new GridLayout(2, 2);
gridLayout.setSpacing(true);

gridLayout.addComponent(createPopupDateTimeField(true, true));
gridLayout.addComponent(createPopupDateTimeField(true, false));
gridLayout.addComponent(createPopupDateTimeField(false, true));
gridLayout.addComponent(createPopupDateTimeField(false, false));

getLayout().addComponent(gridLayout);
}

@Override
protected String getTestDescription() {
return "Test that PopupDateTimeField is rendered consistently across browsers";
}

@Override
protected Integer getTicketNumber() {
return 14565;
}

private static DateTimeField createPopupDateTimeField(final boolean enabled,
final boolean textFieldEnabled) {
final DateTimeField popupDatefield = new DateTimeField();

popupDatefield.setValue(LocalDateTime.of(2014, 9, 3, 10, 34));
popupDatefield.setCaption("Enabled: " + enabled
+ ", Text field enabled: " + textFieldEnabled);
popupDatefield.setEnabled(enabled);
popupDatefield.setTextFieldEnabled(textFieldEnabled);
return popupDatefield;
}

}

+ 62
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/PopupTimeClosingWithEsc.java View File

@@ -0,0 +1,62 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.tests.components.AbstractReindeerTestUI;
import com.vaadin.ui.DateTimeField;
import com.vaadin.ui.VerticalLayout;

public class PopupTimeClosingWithEsc extends AbstractReindeerTestUI {

@Override
protected void setup(VaadinRequest request) {
DateTimeField secondResolution = new DateTimeField("Second");
secondResolution.setId("second");
secondResolution.setResolution(DateTimeResolution.SECOND);

DateTimeField minuteResolution = new DateTimeField("Minute");
minuteResolution.setId("minute");
minuteResolution.setResolution(DateTimeResolution.MINUTE);

DateTimeField hourResolution = new DateTimeField("Hour");
hourResolution.setId("hour");
hourResolution.setResolution(DateTimeResolution.HOUR);

DateTimeField month = new DateTimeField("Month");
month.setId("month");
month.setResolution(DateTimeResolution.MONTH);

VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
layout.setSpacing(true);
layout.addComponents(secondResolution, minuteResolution, hourResolution,
month);
setContent(layout);
}

@Override
protected String getTestDescription() {
return "Testing that the DateField popup can be closed with ESC key.";
}

@Override
protected Integer getTicketNumber() {
return 12317;
}

}

+ 50
- 0
uitest/src/main/java/com/vaadin/tests/components/datefield/TimePopupSelection.java View File

@@ -0,0 +1,50 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.DateTimeField;

/**
* @author Vaadin Ltd
*
*/
public class TimePopupSelection extends AbstractTestUIWithLog {

private static final DateTimeFormatter FORMATTER = DateTimeFormatter
.ofPattern("dd/MM/yyyy HH:mm:ss");

@Override
protected void setup(VaadinRequest request) {
setLocale(Locale.ENGLISH);
DateTimeField field = new DateTimeField();
field.setResolution(DateTimeResolution.SECOND);

field.setValue(LocalDateTime.of(2017, 1, 13, 1, 0));

field.addValueChangeListener(
event -> log(FORMATTER.format(event.getValue())));

addComponent(field);
}

}

+ 44
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/AriaDateTimeDisabledTest.java View File

@@ -0,0 +1,44 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

import com.vaadin.testbench.By;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class AriaDateTimeDisabledTest extends MultiBrowserTest {

@Test
public void verifyAriaDisabledAttributes() {
openTestURL();

// Expect aria-disabled="false" on the enabled DateField.
String ariaDisabled = driver
.findElement(By
.vaadin("/VVerticalLayout[0]/VPopupTimeCalendar[1]#popupButton"))
.getAttribute("aria-disabled");
assertEquals("false", ariaDisabled);

// Expect aria-disabled="true" on the disabled DateField.
ariaDisabled = driver.findElement(By.cssSelector(".v-disabled button"))
.getAttribute("aria-disabled");
assertEquals("true", ariaDisabled);
}

}

+ 39
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/CustomDateTimeFormatTest.java View File

@@ -0,0 +1,39 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

import com.vaadin.testbench.By;
import com.vaadin.tests.tb3.MultiBrowserTest;

/**
* @author Vaadin Ltd
*
*/
public class CustomDateTimeFormatTest extends MultiBrowserTest {

@Test
public void checkCustomDateFormat() {
openTestURL();

String text = findElement(By.tagName("input")).getAttribute("value");
assertEquals("1. tammikuuta 2010 klo 12.23.45", text);
}

}

+ 1
- 1
uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldDayResolutionOffsetTest.java View File

@@ -21,7 +21,7 @@ public class DateFieldDayResolutionOffsetTest extends MultiBrowserTest {
select2ndOfSeptember();

LabelElement dateValue = $(LabelElement.class).id("dateValue");
assertThat(dateValue.getText(), is("09/02/2014"));
assertThat(dateValue.getText(), is("09/02/2014 00:00:00"));
}

private void select2ndOfSeptember() {

+ 199
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldChangeResolutionTest.java View File

@@ -0,0 +1,199 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import static com.vaadin.tests.components.datefield.DateFieldChangeResolution.BUTTON_BASE_ID;
import static com.vaadin.tests.components.datefield.DateFieldChangeResolution.DATEFIELD_ID;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;

import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.testbench.By;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class DateTimeFieldChangeResolutionTest extends MultiBrowserTest {

private WebElement dateFieldButton, textField;
private WebElement resolutionSecond, resolutionMinute, resolutionHour,
resolutionDay, resolutionMonth, resolutionYear;

@Test
public void changeResolutionBetweenYearAndMonth() throws Exception {
initialize();
click(resolutionMonth);
checkHeaderAndBody(DateTimeResolution.MONTH, true);
click(resolutionYear);
checkHeaderAndBody(DateTimeResolution.YEAR, true);
}

@Test
public void changeResolutionBetweenYearAndSecond() throws Exception {
initialize();
click(resolutionSecond);
checkHeaderAndBody(DateTimeResolution.SECOND, true);
click(resolutionYear);
checkHeaderAndBody(DateTimeResolution.YEAR, true);
}

@Test
public void changeResolutionToDayThenMonth() throws Exception {
initialize();
checkHeaderAndBody(DateTimeResolution.YEAR, true); // check the initial
// state
click(resolutionDay);
checkHeaderAndBody(DateTimeResolution.DAY, true);
click(resolutionMonth);
checkHeaderAndBody(DateTimeResolution.MONTH, true);
}

@Test
public void setDateAndChangeResolution() throws Exception {
initialize();
// Set the date to previous month.
click(resolutionMonth);
openPopupDateField();
click(driver.findElement(By.className("v-button-prevmonth")));
closePopupDateField();
assertFalse(
"The text field of the calendar should not be empty after selecting a date",
textField.getAttribute("value").isEmpty());
// Change resolutions and check that the selected date is not lost and
// that the calendar has the correct resolution.
click(resolutionHour);
checkHeaderAndBody(DateTimeResolution.HOUR, false);
click(resolutionYear);
checkHeaderAndBody(DateTimeResolution.YEAR, false);
click(resolutionMinute);
checkHeaderAndBody(DateTimeResolution.MINUTE, false);
}

private void initialize() {
openTestURL();
WebElement dateField = driver.findElement(By.id(DATEFIELD_ID));
dateFieldButton = dateField
.findElement(By.className("v-datefield-button"));
textField = dateField
.findElement(By.className("v-datefield-textfield"));
resolutionSecond = driver.findElement(By.id(BUTTON_BASE_ID + "second"));
resolutionMinute = driver.findElement(By.id(BUTTON_BASE_ID + "minute"));
resolutionHour = driver.findElement(By.id(BUTTON_BASE_ID + "hour"));
resolutionDay = driver.findElement(By.id(BUTTON_BASE_ID + "day"));
resolutionMonth = driver.findElement(By.id(BUTTON_BASE_ID + "month"));
resolutionYear = driver.findElement(By.id(BUTTON_BASE_ID + "year"));
}

private void checkHeaderAndBody(DateTimeResolution resolution,
boolean textFieldIsEmpty) throws Exception {
// Popup date field has all kinds of strange timers on the
// client side
sleep(100);
// Open the popup calendar, perform checks and close the popup.
openPopupDateField();
if (resolution.compareTo(DateTimeResolution.MONTH) <= 0) {
checkMonthHeader();
} else {
checkYearHeader();
}
if (resolution.compareTo(DateTimeResolution.DAY) <= 0) {
assertTrue(
"A calendar with the chosen resolution should have a body",
calendarHasBody());
} else {
assertFalse(
"A calendar with the chosen resolution should not have a body",
calendarHasBody());
}
if (textFieldIsEmpty) {
assertTrue("The text field of the calendar should be empty",
textField.getAttribute("value").isEmpty());
} else {
assertFalse("The text field of the calendar should not be empty",
textField.getAttribute("value").isEmpty());
}
closePopupDateField();
}

private void checkMonthHeader() {
checkHeaderForYear();
checkHeaderForMonth(true);
}

private void checkYearHeader() {
checkHeaderForYear();
checkHeaderForMonth(false);
}

private boolean calendarHasBody() {
return isElementPresent(By.className("v-datefield-calendarpanel-body"));
}

private void checkHeaderForMonth(boolean buttonsExpected) {
// If buttonsExpected is true, check that there are buttons for changing
// the month. Otherwise check that there are no such buttons.
if (buttonsExpected) {
assertTrue(
"The calendar should have a button for switching to the previous month",
isElementPresent(By.cssSelector(
".v-datefield-calendarpanel-header .v-datefield-calendarpanel-prevmonth .v-button-prevmonth")));
assertTrue(
"The calendar should have a button for switching to the next month",
isElementPresent(By.cssSelector(
".v-datefield-calendarpanel-header .v-datefield-calendarpanel-nextmonth .v-button-nextmonth")));
} else {
assertFalse(
"The calendar should not have a button for switching to the previous month",
isElementPresent(By.cssSelector(
".v-datefield-calendarpanel-header .v-datefield-calendarpanel-prevmonth .v-button-prevmonth")));
assertFalse(
"The calendar should not have a button for switching to the next month",
isElementPresent(By.cssSelector(
".v-datefield-calendarpanel-header .v-datefield-calendarpanel-nextmonth .v-button-nextmonth")));
}
}

private void checkHeaderForYear() {
assertTrue(
"The calendar should have a button for switching to the previous year",
isElementPresent(By.cssSelector(
".v-datefield-calendarpanel-header .v-datefield-calendarpanel-prevyear .v-button-prevyear")));
assertTrue("The calendar header should show the selected year",
isElementPresent(By.cssSelector(
".v-datefield-calendarpanel-header .v-datefield-calendarpanel-month")));
assertTrue(
"The calendar should have a button for switching to the next year",
isElementPresent(By.cssSelector(
".v-datefield-calendarpanel-header .v-datefield-calendarpanel-nextyear .v-button-nextyear")));

}

private void click(WebElement element) {
testBenchElement(element).click(5, 5);
}

private void openPopupDateField() {
click(dateFieldButton);
}

private void closePopupDateField() {
WebElement element = driver
.findElement(By.cssSelector(".v-datefield-calendarpanel"));
element.sendKeys(Keys.ESCAPE);
}
}

+ 26
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldElementTest.java View File

@@ -0,0 +1,26 @@
package com.vaadin.tests.components.datefield;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

import org.junit.Test;

import com.vaadin.testbench.customelements.DateTimeFieldElement;
import com.vaadin.testbench.customelements.InlineDateTimeFieldElement;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class DateTimeFieldElementTest extends SingleBrowserTest {

@Test
public void dateFieldElementIsLocated() {
openTestURL();

assertThat($(DateTimeFieldElement.class).all().size(), is(1));
assertThat($(InlineDateTimeFieldElement.class).all().size(), is(1));
}

@Override
protected Class<?> getUIClass() {
return DateTimeFieldElementUI.class;
}
}

+ 72
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldFastForwardTest.java View File

@@ -0,0 +1,72 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import static org.junit.Assert.assertEquals;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

import com.vaadin.testbench.elements.VerticalLayoutElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class DateTimeFieldFastForwardTest extends MultiBrowserTest {

@Test
public void testFastForwardOnRightMouseClick() throws Exception {
openTestURL();
String firstMonth = getSelectedMonth();
WebElement nextMonthButton = driver
.findElement(By.className("v-button-nextmonth"));

// Click and hold left mouse button to start fast forwarding.
new Actions(driver).clickAndHold(nextMonthButton).perform();
sleep(1000);

// Right click and release the left button.

new Actions(driver).contextClick(nextMonthButton)
.release(nextMonthButton).perform();

// Now the fast forwarding should be ended, get the expected month.
String expectedMonth = getSelectedMonth();

// Make browser context menu disappear, since it will crash IE
$(VerticalLayoutElement.class).first().click();

Assert.assertFalse("Month did not change during fast forward",
firstMonth.equals(expectedMonth));

// Wait for a while.
Thread.sleep(1000);

// Verify that we didn't fast forward any further after the left button
// was released.
String actualMonth = getSelectedMonth();
assertEquals(expectedMonth, actualMonth);
}

private String getSelectedMonth() {
return driver
.findElement(
By.className("v-inline-datefield-calendarpanel-month"))
.getText();
}

}

+ 66
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldIsValidTest.java View File

@@ -0,0 +1,66 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.By;
import com.vaadin.testbench.customelements.AbstractDateFieldElement;
import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

/**
* @author Vaadin Ltd
*/
public class DateTimeFieldIsValidTest extends MultiBrowserTest {

@Test
public void testInvalidText() throws Exception {
openTestURL();

waitForElementVisible(By.id("Log"));
waitForElementVisible(By.className("v-datefield"));
WebElement dateTextbox = $(AbstractDateFieldElement.class).first()
.findElement(By.className("v-textfield"));
ButtonElement button = $(ButtonElement.class).first();

dateTextbox.sendKeys("01/01/01 1.12", Keys.TAB);
assertLogText("1. valueChange: value: 01/01/01 1.12, is valid: true");
button.click();
assertLogText("2. buttonClick: value: 01/01/01 1.12, is valid: true");

dateTextbox.sendKeys("lala", Keys.TAB);
assertLogText("3. valueChange: value: null, is valid: false");
button.click();
assertLogText("4. buttonClick: value: null, is valid: false");

dateTextbox.clear();
dateTextbox.sendKeys("02/02/02 2.34", Keys.TAB);
assertLogText("5. valueChange: value: 02/02/02 2.34, is valid: true");
button.click();
assertLogText("6. buttonClick: value: 02/02/02 2.34, is valid: true");
}

private void assertLogText(String expected) throws Exception {
String text = findElement(By.vaadin("PID_SLog_row_0")).getText();
Assert.assertTrue("Expected '" + expected + "' found '" + text + "'",
text.equals(expected));
}

}

+ 43
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldKeyboardInputTest.java View File

@@ -0,0 +1,43 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.customelements.DateTimeFieldElement;
import com.vaadin.testbench.elements.LabelElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class DateTimeFieldKeyboardInputTest extends MultiBrowserTest {

@Test
public void testValueChangeEvent() {
openTestURL();
WebElement dateFieldText = $(DateTimeFieldElement.class).first()
.findElement(By.tagName("input"));
dateFieldText.clear();
int numLabelsBeforeUpdate = $(LabelElement.class).all().size();
dateFieldText.sendKeys("20.10.2013 7:2", Keys.RETURN);
int numLabelsAfterUpdate = $(LabelElement.class).all().size();
assertTrue("Changing the date failed.",
numLabelsAfterUpdate == numLabelsBeforeUpdate + 1);
}
}

+ 46
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldReadOnlyTest.java View File

@@ -0,0 +1,46 @@
package com.vaadin.tests.components.datefield;

import java.io.IOException;

import org.junit.Test;
import org.openqa.selenium.Keys;

import com.vaadin.testbench.By;
import com.vaadin.testbench.customelements.AbstractDateFieldElement;
import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class DateTimeFieldReadOnlyTest extends MultiBrowserTest {

@Test
public void readOnlyDateFieldPopupShouldNotOpen()
throws IOException, InterruptedException {
openTestURL();

compareScreen("initial-date");
toggleReadOnly();

openPopup();
compareScreen("readwrite-popup-date");

closePopup();
toggleReadOnly();
compareScreen("readonly-date");
}

private void closePopup() {
findElement(By.className("v-datefield-calendarpanel"))
.sendKeys(Keys.RETURN);
}

private void openPopup() {
// waiting for openPopup() in TB4 beta1:
// http://dev.vaadin.com/ticket/13766
$(AbstractDateFieldElement.class).first()
.findElement(By.tagName("button")).click();
}

private void toggleReadOnly() {
$(ButtonElement.class).caption("Switch read-only").first().click();
}
}

uitest/src/test/java/com/vaadin/tests/components/datefield/AbstractDateFieldTestTest.java → uitest/src/test/java/com/vaadin/tests/components/datefield/DateTimeFieldTestTest.java View File

@@ -25,7 +25,11 @@ import org.openqa.selenium.interactions.Actions;
import com.vaadin.testbench.elements.NotificationElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class AbstractDateFieldTestTest extends MultiBrowserTest {
/**
* @author Vaadin Ltd
*
*/
public class DateTimeFieldTestTest extends MultiBrowserTest {

@Test
public void testMakingRequired() throws InterruptedException {

+ 79
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/DisabledInlineDateTimeFieldTest.java View File

@@ -0,0 +1,79 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.vaadin.tests.tb3.MultiBrowserTest;

public class DisabledInlineDateTimeFieldTest extends MultiBrowserTest {

@Test
public void testDisabled() {
openTestURL();
testNextMonthControls(".v-disabled");
testDaySelection(".v-disabled");
}

@Test
public void testReadOnly() {
openTestURL();
testNextMonthControls(".v-readonly");
testDaySelection(".v-readonly");
}

private void testNextMonthControls(String cssClass) {
// Get the currently selected month.
String expectedMonth = getSelectedMonth(cssClass);

// Attempt to click the next month button.
driver.findElement(By.cssSelector(cssClass + " .v-button-nextmonth"))
.click();

// Assert that we did not navigate to next month.
String actualMonth = getSelectedMonth(cssClass);
assertEquals(expectedMonth, actualMonth);
}

private void testDaySelection(String cssClass) {
// We know that the first day element is not selected, because of the
// fixed date in the test.
WebElement nonSelectedDay = driver.findElement(By.cssSelector(
cssClass + " .v-inline-datefield-calendarpanel-day"));

// Assert it is not selected before click.
assertFalse(nonSelectedDay.getAttribute("class").contains("selected"));

// Click on the non-selected day.
nonSelectedDay.click();

// Assert that clicking did not select the day.
assertFalse(nonSelectedDay.getAttribute("class").contains("selected"));
}

private String getSelectedMonth(String selectorPrefix) {
return driver
.findElement(By.cssSelector(selectorPrefix
+ " .v-inline-datefield-calendarpanel-month"))
.getText();
}

}

+ 37
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/InlineDateTimeFieldTestTest.java View File

@@ -0,0 +1,37 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import org.junit.Test;

import com.google.gwt.editor.client.Editor.Ignore;

/**
* Reuse tests from super DateTimeFieldTestTest class.
*
* @author Vaadin Ltd
*
*/
public class InlineDateTimeFieldTestTest extends DateTimeFieldTestTest {

@Override
@Test
@Ignore
public void testValueAfterOpeningPopupInRequiredField()
throws InterruptedException {
// no popup for inline date field
}
}

+ 12
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/PopupDateFieldStatesTest.java View File

@@ -1,8 +1,11 @@
package com.vaadin.tests.components.datefield;

import java.io.IOException;
import java.util.regex.Pattern;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.vaadin.tests.tb3.MultiBrowserTest;

@@ -13,6 +16,15 @@ public class PopupDateFieldStatesTest extends MultiBrowserTest {
throws IOException, InterruptedException {
openTestURL();

// wait until loading indicator becomes invisible
WebElement loadingIndicator = findElement(
By.className("v-loading-indicator"));
Pattern pattern = Pattern.compile("display: *none;");
waitUntil(driver -> {
return pattern.matcher(loadingIndicator.getAttribute("style"))
.find();
});

compareScreen("dateFieldStates");
}


+ 31
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/PopupDateTimeFieldStatesTest.java View File

@@ -0,0 +1,31 @@
package com.vaadin.tests.components.datefield;

import java.io.IOException;
import java.util.regex.Pattern;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.vaadin.tests.tb3.MultiBrowserTest;

public class PopupDateTimeFieldStatesTest extends MultiBrowserTest {

@Test
public void readOnlyDateFieldPopupShouldNotOpen()
throws IOException, InterruptedException {
openTestURL();

// wait until loading indicator becomes invisible
WebElement loadingIndicator = findElement(
By.className("v-loading-indicator"));
Pattern pattern = Pattern.compile("display: *none;");
waitUntil(driver -> {
return pattern.matcher(loadingIndicator.getAttribute("style"))
.find();
});

compareScreen("dateFieldStates");
}

}

+ 63
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/PopupTimeClosingWithEscTest.java View File

@@ -0,0 +1,63 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;

import com.vaadin.testbench.annotations.RunLocally;
import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class PopupTimeClosingWithEscTest extends MultiBrowserTest {

@Test
public void testPopupClosing() {
openTestURL();

testPopupClosing("second");
testPopupClosing("minute");
testPopupClosing("hour");
testPopupClosing("month");
}

private void testPopupClosing(String dateFieldId) {
openPopup(dateFieldId);
assertTrue(isPopupVisible());
sendEscToCalendarPanel();
assertFalse(isPopupVisible());
}

private void openPopup(String dateFieldId) {
driver.findElement(
vaadinLocator("PID_S" + dateFieldId + "#popupButton")).click();
}

private boolean isPopupVisible() {
return !(driver.findElements(By.cssSelector(".v-datefield-popup"))
.isEmpty());
}

private void sendEscToCalendarPanel() {
driver.findElement(By.cssSelector(".v-datefield-calendarpanel"))
.sendKeys(Keys.ESCAPE);
}

}

+ 67
- 0
uitest/src/test/java/com/vaadin/tests/components/datefield/TimePopupSelectionTest.java View File

@@ -0,0 +1,67 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.components.datefield;

import java.util.List;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import com.vaadin.testbench.By;
import com.vaadin.testbench.customelements.DateTimeFieldElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

/**
* @author Vaadin Ltd
*
*/
public class TimePopupSelectionTest extends MultiBrowserTest {

@Test
public void selectDateAndTimeFromPopup() {
openTestURL();

DateTimeFieldElement field = $(DateTimeFieldElement.class).first();
Assert.assertEquals("1/13/17 01:00:00 AM", field.getValue());

field.openPopup();

List<WebElement> timeSelects = findElement(
By.className("v-datefield-calendarpanel-time"))
.findElements(By.tagName("select"));

new Select(timeSelects.get(0)).selectByValue("09");
Assert.assertEquals("1/13/17 09:00:00 AM", field.getValue());

new Select(timeSelects.get(1)).selectByValue("35");
Assert.assertEquals("1/13/17 09:35:00 AM", field.getValue());

new Select(timeSelects.get(2)).selectByValue("41");
Assert.assertEquals("1/13/17 09:35:41 AM", field.getValue());

closePopup();

waitUntil(driver -> getLogRow(0).equals("1. 13/01/2017 09:35:41"));
}

private void closePopup() {
findElement(By.className("v-datefield-calendarpanel"))
.sendKeys(Keys.ENTER);
}
}

Loading…
Cancel
Save