From 75caa0488dee5b59f37d5691430c01de0b55c2db Mon Sep 17 00:00:00 2001 From: Anna Koskinen Date: Tue, 28 Jan 2020 12:34:22 +0200 Subject: [PATCH] Don't reset date to current at DateField state (e.g. read-only) updates. (#11879) - DateFields with month or year resolution should not get their date reset to current date if the field's state is updated (e.g. by changing read-only status or adding a range). Fixes: #11864, #11605 --- .../client/ui/VAbstractCalendarPanel.java | 28 ++++++++--- .../DateFieldMonthResolutionStatusChange.java | 49 +++++++++++++++++++ ...eFieldMonthResolutionStatusChangeTest.java | 38 ++++++++++++++ 3 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionStatusChange.java create mode 100644 uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionStatusChangeTest.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 c049a25a53..8fde0264e4 100644 --- a/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java +++ b/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java @@ -16,6 +16,8 @@ package com.vaadin.client.ui; +import static com.vaadin.client.DateTimeService.asTwoDigits; + import java.util.Date; import java.util.HashMap; import java.util.List; @@ -30,7 +32,6 @@ 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; @@ -56,14 +57,11 @@ import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.InlineHTML; import com.google.gwt.user.client.ui.Widget; -import com.vaadin.client.BrowserInfo; import com.vaadin.client.DateTimeService; import com.vaadin.client.WidgetUtil; import com.vaadin.client.ui.aria.AriaHelper; import com.vaadin.shared.util.SharedUtil; -import static com.vaadin.client.DateTimeService.asTwoDigits; - /** * Abstract calendar panel to show and select a date using a resolution. The * class is parameterized by the date resolution enumeration type. @@ -963,7 +961,17 @@ public abstract class VAbstractCalendarPanel> * resolution of the calendar is changed and no date has been * selected. */ + @SuppressWarnings("rawtypes") public void renderCalendar(boolean updateDate) { + if (parent instanceof VAbstractPopupCalendar + && !((VAbstractPopupCalendar) parent).popup.isShowing()) { + if (getDate() == null) { + // no date set, cannot pre-render yet + return; + } + // a popup that isn't open cannot possibly need a focus change event + updateDate = false; + } doRenderCalendar(updateDate); initialRenderDone = true; @@ -986,11 +994,15 @@ public abstract class VAbstractCalendarPanel> getDateField().getStylePrimaryName() + "-calendarpanel"); if (focusedDate == null) { - Date now = new Date(); + Date date = getDate(); + if (date == null) { + date = new Date(); + } // focusedDate must have zero hours, mins, secs, millisecs - focusedDate = new FocusedDate(now.getYear(), now.getMonth(), - now.getDate()); - displayedMonth = new FocusedDate(now.getYear(), now.getMonth(), 1); + focusedDate = new FocusedDate(date.getYear(), date.getMonth(), + date.getDate()); + displayedMonth = new FocusedDate(date.getYear(), date.getMonth(), + 1); } if (updateDate && !isDay(getResolution()) diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionStatusChange.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionStatusChange.java new file mode 100644 index 0000000000..55b2823a1d --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionStatusChange.java @@ -0,0 +1,49 @@ +package com.vaadin.tests.components.datefield; + +import java.time.LocalDate; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.datefield.DateResolution; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.DateField; + +public class DateFieldMonthResolutionStatusChange extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + DateField dateField = new DateField(); + dateField.setResolution(DateResolution.MONTH); + dateField.setValue(LocalDate.of(2019, 1, 1)); + dateField.setReadOnly(true); + + Button dateReadOnlySwitch = new Button("Toggle read-only"); + dateReadOnlySwitch.setId("readOnly"); + dateReadOnlySwitch.addClickListener(event -> { + dateField.setReadOnly(!dateField.isReadOnly()); + }); + + Button addRangeButton = new Button("Add range"); + addRangeButton.setId("addRange"); + addRangeButton.addClickListener(event -> { + dateField.setRangeStart(LocalDate.of(2018, 1, 1)); + dateField.setRangeEnd(LocalDate.of(2020, 1, 1)); + }); + + addComponent(dateField); + addComponent(dateReadOnlySwitch); + addComponent(addRangeButton); + } + + @Override + protected String getTestDescription() { + return "Changing any field status (e.g. read-only or range) before " + + "the DateField popup has been opened should not change " + + "the date to current."; + } + + @Override + protected Integer getTicketNumber() { + return 11864; + } +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionStatusChangeTest.java b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionStatusChangeTest.java new file mode 100644 index 0000000000..58a926546c --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldMonthResolutionStatusChangeTest.java @@ -0,0 +1,38 @@ +package com.vaadin.tests.components.datefield; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DateFieldMonthResolutionStatusChangeTest + extends MultiBrowserTest { + + @Test + public void testChangeReadOnly() { + openTestURL(); + DateFieldElement df = $(DateFieldElement.class).first(); + assertEquals("Unexpected initial date.", "1/19", df.getValue()); + + // switch read-only state + $(ButtonElement.class).id("readOnly").click(); + + assertEquals("Unexpected date change.", "1/19", df.getValue()); + } + + @Test + public void testAddRange() { + openTestURL(); + DateFieldElement df = $(DateFieldElement.class).first(); + assertEquals("Unexpected initial date.", "1/19", df.getValue()); + + // add range + $(ButtonElement.class).id("addRange").click(); + + assertEquals("Unexpected date change.", "1/19", df.getValue()); + } + +} -- 2.39.5