aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/com/vaadin/client/ui/VCalendarPanel.java20
-rw-r--r--client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java6
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java72
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java197
4 files changed, 291 insertions, 4 deletions
diff --git a/client/src/com/vaadin/client/ui/VCalendarPanel.java b/client/src/com/vaadin/client/ui/VCalendarPanel.java
index eaa2292c69..6fc06bb153 100644
--- a/client/src/com/vaadin/client/ui/VCalendarPanel.java
+++ b/client/src/com/vaadin/client/ui/VCalendarPanel.java
@@ -786,6 +786,21 @@ public class VCalendarPanel extends FocusableFlexTable implements
* Updates the calendar and text field with the selected dates.
*/
public void renderCalendar() {
+ renderCalendar(true);
+ }
+
+ /**
+ * For internal use only. May be removed or replaced in the future.
+ *
+ * Updates the calendar and text field with the selected dates.
+ *
+ * @param updateDate
+ * The value false prevents setting the selected date of the
+ * calendar based on focusedDate. That can be used when only the
+ * resolution of the calendar is changed and no date has been
+ * selected.
+ */
+ public void renderCalendar(boolean updateDate) {
super.setStylePrimaryName(parent.getStylePrimaryName()
+ "-calendarpanel");
@@ -798,8 +813,9 @@ public class VCalendarPanel extends FocusableFlexTable implements
displayedMonth = new FocusedDate(now.getYear(), now.getMonth(), 1);
}
- if (getResolution().getCalendarField() <= Resolution.MONTH
- .getCalendarField() && focusChangeListener != null) {
+ if (updateDate
+ && getResolution().getCalendarField() <= Resolution.MONTH
+ .getCalendarField() && focusChangeListener != null) {
focusChangeListener.focusChanged(new Date(focusedDate.getTime()));
}
diff --git a/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java b/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java
index a349eb2993..6f059a7c16 100644
--- a/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java
+++ b/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java
@@ -87,15 +87,17 @@ public class PopupDateFieldConnector extends TextualDateConnector {
.isShowISOWeekNumbers());
if (getWidget().calendar.getResolution() != getWidget()
.getCurrentResolution()) {
+ boolean hasSelectedDate = false;
getWidget().calendar.setResolution(getWidget()
.getCurrentResolution());
if (getWidget().calendar.getDate() != null
&& getWidget().getCurrentDate() != null) {
+ hasSelectedDate = true;
getWidget().calendar.setDate((Date) getWidget()
.getCurrentDate().clone());
- // force re-render when changing resolution only
- getWidget().calendar.renderCalendar();
}
+ // force re-render when changing resolution only
+ getWidget().calendar.renderCalendar(hasSelectedDate);
}
// Force re-render of calendar if locale has changed (#12153)
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java
new file mode 100644
index 0000000000..9dbd8fa6dc
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2014 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.Resolution;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.DateField;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.PopupDateField;
+
+public class DateFieldChangeResolution extends AbstractTestUI {
+
+ 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 DateField dateField = new PopupDateField("Enter date");
+ dateField.setResolution(Resolution.YEAR);
+ dateField.setId(DATEFIELD_ID);
+ dateField.setImmediate(true);
+ addComponent(dateField);
+
+ Label l = new Label("Select resolution");
+ addComponent(l);
+ HorizontalLayout hlayout = new HorizontalLayout();
+ addComponent(hlayout);
+ for (final Resolution value : Resolution.values()) {
+ String resolutionString = value.toString().toLowerCase();
+ Button b = new Button(resolutionString);
+ b.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ dateField.setResolution(value);
+ }
+ });
+ b.setId(BUTTON_BASE_ID + resolutionString);
+ hlayout.addComponent(b);
+ }
+
+ }
+
+ @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;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java
new file mode 100644
index 0000000000..6820410059
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2000-2014 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.Resolution;
+import com.vaadin.testbench.By;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class DateFieldChangeResolutionTest extends MultiBrowserTest {
+
+ private WebElement dateFieldButton, textField;
+ private WebElement resolutionSecond, resolutionMinute, resolutionHour,
+ resolutionDay, resolutionMonth, resolutionYear;
+
+ @Test
+ public void changeResolutionBetweenYearAndMonth() throws Exception {
+ initialize();
+ click(resolutionMonth);
+ checkHeaderAndBody(Resolution.MONTH, true);
+ click(resolutionYear);
+ checkHeaderAndBody(Resolution.YEAR, true);
+ }
+
+ @Test
+ public void changeResolutionBetweenYearAndSecond() throws Exception {
+ initialize();
+ click(resolutionSecond);
+ checkHeaderAndBody(Resolution.SECOND, true);
+ click(resolutionYear);
+ checkHeaderAndBody(Resolution.YEAR, true);
+ }
+
+ @Test
+ public void changeResolutionToDayThenMonth() throws Exception {
+ initialize();
+ checkHeaderAndBody(Resolution.YEAR, true); // check the initial state
+ click(resolutionDay);
+ checkHeaderAndBody(Resolution.DAY, true);
+ click(resolutionMonth);
+ checkHeaderAndBody(Resolution.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(Resolution.HOUR, false);
+ click(resolutionYear);
+ checkHeaderAndBody(Resolution.YEAR, false);
+ click(resolutionMinute);
+ checkHeaderAndBody(Resolution.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(Resolution resolution,
+ boolean textFieldIsEmpty) {
+ // Open the popup calendar, perform checks and close the popup.
+ openPopupDateField();
+ if (resolution.getCalendarField() >= Resolution.MONTH
+ .getCalendarField()) {
+ checkMonthHeader();
+ } else {
+ checkYearHeader();
+ }
+ if (resolution.getCalendarField() >= Resolution.DAY.getCalendarField()) {
+ 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);
+ }
+}