Browse Source

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
tags/8.9.0.alpha1
Anastasia Smirnova 4 years ago
parent
commit
973731763c

+ 14
- 0
client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java View File

@@ -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<R extends Enum<R>>
// 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<R extends Enum<R>>
"<span class=\"" + parent.getStylePrimaryName()
+ "-calendarpanel-month\">" + monthName + " " + year
+ "</span>");
if (!isBelowMonth(getResolution())) {
monthYearElement.addClassName("header-month-year");
}
}

private void updateControlButtonRangeStyles(boolean needsMonth) {

+ 4
- 0
themes/src/main/themes/VAADIN/themes/valo/components/_datefield.scss View File

@@ -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);

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

@@ -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);
}
}

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

@@ -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"));
}
}

Loading…
Cancel
Save