From daaa16baacd6e9d08d2e8f8388b5a959325a3667 Mon Sep 17 00:00:00 2001 From: Anastasia Smirnova Date: Tue, 25 Jun 2019 08:37:08 +0300 Subject: [PATCH] Clicking on DateField pop-up should select Month/Year (#11531) * Clicking on DateField pop-up should select Month/Year In Year/Month Resolution DateField should select the value, when user clicks on pop-up Fixes #8447 --- .../client/ui/VAbstractCalendarPanel.java | 14 +++ .../themes/valo/components/_datefield.scss | 4 + .../DateFieldMonthResolutionClick.java | 56 ++++++++++++ .../DateFieldMonthResolutionClickTest.java | 85 +++++++++++++++++++ 4 files changed, 159 insertions(+) create mode 100644 uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionClick.java create mode 100644 uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionClickTest.java diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java b/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java index 8f32d35acb..c049a25a53 100644 --- a/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java +++ b/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java @@ -30,6 +30,7 @@ import com.google.gwt.aria.client.Roles; import com.google.gwt.aria.client.SelectedValue; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; +import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickHandler; @@ -49,6 +50,7 @@ import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlexTable; @@ -580,6 +582,15 @@ public abstract class VAbstractCalendarPanel> // Set ID to be referenced from focused date or calendar panel Element monthYearElement = getFlexCellFormatter().getElement(0, 2); AriaHelper.ensureHasId(monthYearElement); + Event.sinkEvents(monthYearElement, Event.ONCLICK); + Event.setEventListener(monthYearElement, event -> { + // Don't handle header clicks if resolution in below month + if (!isEnabled() || isReadonly() || isBelowMonth(getResolution())) { + return; + } + selectFocused(); + onSubmit(); + }); if (!needsBody) { Roles.getGridRole().setAriaLabelledbyProperty(getElement(), Id.of(monthYearElement)); @@ -591,6 +602,9 @@ public abstract class VAbstractCalendarPanel> "" + monthName + " " + year + ""); + if (!isBelowMonth(getResolution())) { + monthYearElement.addClassName("header-month-year"); + } } private void updateControlButtonRangeStyles(boolean needsMonth) { diff --git a/themes/src/main/themes/VAADIN/themes/valo/components/_datefield.scss b/themes/src/main/themes/VAADIN/themes/valo/components/_datefield.scss index e92c9ce436..58baa5d6f7 100644 --- a/themes/src/main/themes/VAADIN/themes/valo/components/_datefield.scss +++ b/themes/src/main/themes/VAADIN/themes/valo/components/_datefield.scss @@ -477,8 +477,12 @@ td.#{$primary-stylename}-month { width: round($v-unit-size * 4); + cursor:default; @include valo-datefield-calendarpanel-month-style; } + td.#{$primary-stylename}-month.header-month-year{ + cursor:pointer; + } .#{$primary-stylename}-year td.#{$primary-stylename}-month { width: round($v-unit-size * 2); diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionClick.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionClick.java new file mode 100644 index 0000000000..1db41257b6 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionClick.java @@ -0,0 +1,56 @@ +package com.vaadin.tests.components.datefield; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.datefield.DateResolution; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.DateField; +import com.vaadin.ui.Button; + +import java.time.LocalDate; +import java.time.ZoneId; + +@Widgetset("com.vaadin.DefaultWidgetSet") +public class DateFieldMonthResolutionClick extends AbstractTestUIWithLog { + @Override + protected void setup(VaadinRequest request) { + DateField dyf = new DateField(); + dyf.setDateFormat("yyyy"); + dyf.setRangeStart(LocalDate.of(2012, 01, 31)); + dyf.setZoneId(ZoneId.of("Europe/Paris")); + dyf.setResolution(DateResolution.YEAR); + dyf.setCaption("Resolution : year"); + dyf.setId("yearResolutionDF"); + dyf.addValueChangeListener(event -> { + log("Current value for the 1.st DF: " + event.getValue() + + " isUserOriginated: " + event.isUserOriginated()); + }); + addComponent(dyf); + DateField dmf = new DateField(); + dmf.setDateFormat("M/yyyy"); + dmf.setCaption("Resolution : month"); + dmf.setResolution(DateResolution.MONTH); + dmf.setId("monthResolutionDF"); + dmf.setRangeStart(LocalDate.now()); + dmf.addValueChangeListener(event -> { + log("Current value for the 2.st DF: " + event.getValue() + + " isUserOriginated: " + event.isUserOriginated()); + }); + addComponent(dmf); + + DateField dyDay = new DateField( + "Header is not clickable, when resolution in less than MONTH"); + dyDay.setResolution(DateResolution.DAY); + dyDay.setId("resolutionDayDF"); + addComponent(dyDay); + Button button = new Button("Change Resolution", e -> { + if (dyDay.getResolution().equals(DateResolution.DAY)) { + dyDay.setResolution(DateResolution.YEAR); + } else { + dyDay.setResolution(DateResolution.DAY); + } + }); + button.setId("buttonChangeResolution"); + addComponent(button); + } +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionClickTest.java b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionClickTest.java new file mode 100644 index 0000000000..7f636acadb --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionClickTest.java @@ -0,0 +1,85 @@ +package com.vaadin.tests.components.datefield; + +import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; + +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import static org.junit.Assert.assertTrue; + +public class DateFieldMonthResolutionClickTest extends MultiBrowserTest { + + @Before + public void setUp() throws Exception { + super.setup(); + openTestURL(); + } + + @Test + public void testClickChangeValueYear() { + DateFieldElement yearResolutionDF = $(DateFieldElement.class) + .id("yearResolutionDF"); + yearResolutionDF.openPopup(); + assertTrue("Initially there should be no value", + yearResolutionDF.getValue() == null + || yearResolutionDF.getValue().isEmpty()); + findElement(By.className("v-datefield-calendarpanel-month")).click(); + waitForElementNotPresent(By.className("v-datefield-popup")); + assertTrue("The selected year should be the current one", + getZonedDateTimeAtECT().getYear() == Integer + .valueOf(yearResolutionDF.getValue())); + } + + @Test + public void testClickChangeValueMonth() { + DateFieldElement monthResolutionDF = $(DateFieldElement.class) + .id("monthResolutionDF"); + monthResolutionDF.openPopup(); + assertTrue( + String.format("Initially there should be no value, but was %s", + monthResolutionDF.getValue()), + monthResolutionDF.getValue() == null + || monthResolutionDF.getValue().isEmpty()); + findElement(By.className("v-datefield-calendarpanel-month")).click(); + waitForElementNotPresent(By.className("v-datefield-popup")); + String dateValue = new StringBuilder() + .append(getZonedDateTimeAtECT().getMonth().getValue()) + .append("/").append(getZonedDateTimeAtECT().getYear()) + .toString(); + assertTrue("The selected year should be the current one", + dateValue.equals(monthResolutionDF.getValue())); + } + + @Test + public void testResolutionDayHeaderNotClickable() { + DateFieldElement dayResolutionDF = $(DateFieldElement.class) + .id("resolutionDayDF"); + dayResolutionDF.openPopup(); + waitForElementPresent(By.className("v-datefield-popup")); + findElement(By.className("v-datefield-calendarpanel-month")).click(); + // Click should have no effect + assertElementPresent(By.className("v-datefield-popup")); + + } + + @Test + public void setResoultionToYearAndClick() { + // Switch the resolution to verify clicking is now enabled + findElement(By.id("buttonChangeResolution")).click(); + waitForElementPresent(By.id("resolutionDayDF")); + $(DateFieldElement.class).id("resolutionDayDF").openPopup(); + waitForElementPresent(By.className("v-datefield-popup")); + findElement(By.className("v-datefield-calendarpanel-month")).click(); + waitForElementNotPresent(By.className("v-datefield-popup")); + // Set Back to month + findElement(By.id("buttonChangeResolution")).click(); + } + + private ZonedDateTime getZonedDateTimeAtECT() { + return ZonedDateTime.now(ZoneId.of("Europe/Paris")); + } +} -- 2.39.5