summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmed Ashour <asashour@yahoo.com>2017-10-13 08:53:17 +0200
committerTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>2017-10-13 09:53:17 +0300
commitdd5597d9014032cc366d4b70405e007b1876c350 (patch)
treea408b26413b91db0a48a87a95dfa6304c3552205
parent569072dccd09a018850abb3a7f9d39373c082d4f (diff)
downloadvaadin-framework-dd5597d9014032cc366d4b70405e007b1876c350.tar.gz
vaadin-framework-dd5597d9014032cc366d4b70405e007b1876c350.zip
Convert AbstractDateField not to be a LegacyComponent (#10148)
-rw-r--r--all/src/main/templates/release-notes.html1
-rw-r--r--client/src/main/java/com/vaadin/client/ApplicationConnection.java3
-rw-r--r--client/src/main/java/com/vaadin/client/DateTimeService.java29
-rw-r--r--client/src/main/java/com/vaadin/client/LocaleService.java2
-rw-r--r--client/src/main/java/com/vaadin/client/ui/CalendarEntry.java12
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java3
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java42
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java38
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VDateField.java57
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java23
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java28
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java53
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java32
-rw-r--r--client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java109
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/AbstractDateFieldConnector.java147
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java45
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java63
-rw-r--r--client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java135
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractDateField.java314
-rw-r--r--server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java24
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldServerRpc.java55
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldState.java52
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/datefield/DateFieldConstants.java26
23 files changed, 691 insertions, 602 deletions
diff --git a/all/src/main/templates/release-notes.html b/all/src/main/templates/release-notes.html
index f2c9a6523e..d9d006d23f 100644
--- a/all/src/main/templates/release-notes.html
+++ b/all/src/main/templates/release-notes.html
@@ -123,6 +123,7 @@
<li><tt>Notification</tt> method <tt>show</tt> returns <tt>Notification</tt>, instead of <tt>void</tt>.</li>
<li><tt>SharedState</tt> field <tt>registeredEventListeners</tt> is a <tt>Map</tt> instead of <tt>Set</tt>.</li>
<li>The client side <tt>SelectionModel</tt> interface has a new method <tt>isMultiSelectionAllowed</tt>.</li>
+ <li><tt>AbstractDateField</tt> is not a <tt>LegacyComponent</tt> anymore.</li>
<h2>For incompatible or behavior-altering changes in 8.1, please see <a href="https://vaadin.com/download/release/8.1/8.1.0/release-notes.html#incompatible">8.1 release notes</a></h2>
diff --git a/client/src/main/java/com/vaadin/client/ApplicationConnection.java b/client/src/main/java/com/vaadin/client/ApplicationConnection.java
index 15a36315b0..79432fb0a2 100644
--- a/client/src/main/java/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/main/java/com/vaadin/client/ApplicationConnection.java
@@ -1358,8 +1358,7 @@ public class ApplicationConnection implements HasHandlers {
return false;
}
- return hasEventListeners(getConnectorMap().getConnector(widget),
- eventIdentifier);
+ return hasEventListeners(connector, eventIdentifier);
}
LayoutManager getLayoutManager() {
diff --git a/client/src/main/java/com/vaadin/client/DateTimeService.java b/client/src/main/java/com/vaadin/client/DateTimeService.java
index 577b079ce2..c1f6d70815 100644
--- a/client/src/main/java/com/vaadin/client/DateTimeService.java
+++ b/client/src/main/java/com/vaadin/client/DateTimeService.java
@@ -35,7 +35,7 @@ import com.vaadin.shared.ui.datefield.DateResolution;
@SuppressWarnings("deprecation")
public class DateTimeService {
- private String currentLocale;
+ private String locale;
private static int[] maxDaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30,
31, 30, 31 };
@@ -44,7 +44,7 @@ public class DateTimeService {
* Creates a new date time service with the application default locale.
*/
public DateTimeService() {
- currentLocale = LocaleService.getDefaultLocale();
+ locale = LocaleService.getDefaultLocale();
}
/**
@@ -59,20 +59,19 @@ public class DateTimeService {
}
public void setLocale(String locale) throws LocaleNotLoadedException {
- if (LocaleService.getAvailableLocales().contains(locale)) {
- currentLocale = locale;
- } else {
+ if (!LocaleService.getAvailableLocales().contains(locale)) {
throw new LocaleNotLoadedException(locale);
}
+ this.locale = locale;
}
public String getLocale() {
- return currentLocale;
+ return locale;
}
public String getMonth(int month) {
try {
- return LocaleService.getMonthNames(currentLocale)[month];
+ return LocaleService.getMonthNames(locale)[month];
} catch (final LocaleNotLoadedException e) {
getLogger().log(Level.SEVERE, "Error in getMonth", e);
return null;
@@ -81,7 +80,7 @@ public class DateTimeService {
public String getShortMonth(int month) {
try {
- return LocaleService.getShortMonthNames(currentLocale)[month];
+ return LocaleService.getShortMonthNames(locale)[month];
} catch (final LocaleNotLoadedException e) {
getLogger().log(Level.SEVERE, "Error in getShortMonth", e);
return null;
@@ -90,7 +89,7 @@ public class DateTimeService {
public String getDay(int day) {
try {
- return LocaleService.getDayNames(currentLocale)[day];
+ return LocaleService.getDayNames(locale)[day];
} catch (final LocaleNotLoadedException e) {
getLogger().log(Level.SEVERE, "Error in getDay", e);
return null;
@@ -99,7 +98,7 @@ public class DateTimeService {
public String getShortDay(int day) {
try {
- return LocaleService.getShortDayNames(currentLocale)[day];
+ return LocaleService.getShortDayNames(locale)[day];
} catch (final LocaleNotLoadedException e) {
getLogger().log(Level.SEVERE, "Error in getShortDay", e);
return null;
@@ -108,7 +107,7 @@ public class DateTimeService {
public int getFirstDayOfWeek() {
try {
- return LocaleService.getFirstDayOfWeek(currentLocale);
+ return LocaleService.getFirstDayOfWeek(locale);
} catch (final LocaleNotLoadedException e) {
getLogger().log(Level.SEVERE, "Error in getFirstDayOfWeek", e);
return 0;
@@ -117,7 +116,7 @@ public class DateTimeService {
public boolean isTwelveHourClock() {
try {
- return LocaleService.isTwelveHourClock(currentLocale);
+ return LocaleService.isTwelveHourClock(locale);
} catch (final LocaleNotLoadedException e) {
getLogger().log(Level.SEVERE, "Error in isTwelveHourClock", e);
return false;
@@ -126,7 +125,7 @@ public class DateTimeService {
public String getClockDelimeter() {
try {
- return LocaleService.getClockDelimiter(currentLocale);
+ return LocaleService.getClockDelimiter(locale);
} catch (final LocaleNotLoadedException e) {
getLogger().log(Level.SEVERE, "Error in getClockDelimiter", e);
return ":";
@@ -137,7 +136,7 @@ public class DateTimeService {
public String[] getAmPmStrings() {
try {
- return LocaleService.getAmPmStrings(currentLocale);
+ return LocaleService.getAmPmStrings(locale);
} catch (final LocaleNotLoadedException e) {
// TODO can this practically even happen? Should die instead?
getLogger().log(Level.SEVERE,
@@ -151,7 +150,7 @@ public class DateTimeService {
date.getMonth(), 1);
int firstDay;
try {
- firstDay = LocaleService.getFirstDayOfWeek(currentLocale);
+ firstDay = LocaleService.getFirstDayOfWeek(locale);
} catch (final LocaleNotLoadedException e) {
getLogger().log(Level.SEVERE, "Locale not loaded, using fallback 0",
e);
diff --git a/client/src/main/java/com/vaadin/client/LocaleService.java b/client/src/main/java/com/vaadin/client/LocaleService.java
index b877bca7c5..88d07ee836 100644
--- a/client/src/main/java/com/vaadin/client/LocaleService.java
+++ b/client/src/main/java/com/vaadin/client/LocaleService.java
@@ -42,7 +42,7 @@ public class LocaleService {
if (cache.containsKey(key)) {
cache.remove(key);
}
- getLogger().fine("Received locale data for " + localeData.name);
+ getLogger().fine("Received locale data for " + key);
cache.put(key, localeData);
if (cache.size() == 1) {
setDefaultLocale(key);
diff --git a/client/src/main/java/com/vaadin/client/ui/CalendarEntry.java b/client/src/main/java/com/vaadin/client/ui/CalendarEntry.java
index 16e3a15a97..d7bea84758 100644
--- a/client/src/main/java/com/vaadin/client/ui/CalendarEntry.java
+++ b/client/src/main/java/com/vaadin/client/ui/CalendarEntry.java
@@ -113,10 +113,10 @@ public class CalendarEntry {
+ "." + start.getDate() + " ";
}
int i = start.getHours();
- s += (i < 10 ? "0" : "") + i;
+ s += asTwoDigits(i);
s += ":";
i = start.getMinutes();
- s += (i < 10 ? "0" : "") + i;
+ s += asTwoDigits(i);
if (!start.equals(end)) {
s += " - ";
if (!DateTimeService.isSameDay(start, end)) {
@@ -124,10 +124,10 @@ public class CalendarEntry {
+ "." + end.getDate() + " ";
}
i = end.getHours();
- s += (i < 10 ? "0" : "") + i;
+ s += asTwoDigits(i);
s += ":";
i = end.getMinutes();
- s += (i < 10 ? "0" : "") + i;
+ s += asTwoDigits(i);
}
s += " ";
}
@@ -137,4 +137,8 @@ public class CalendarEntry {
return s;
}
+ private static String asTwoDigits(int i) {
+ return (i < 10 ? "0" : "") + i;
+ }
+
}
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 383d67ce70..7ac882f9e4 100644
--- a/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java
+++ b/client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java
@@ -1153,9 +1153,6 @@ public abstract class VAbstractCalendarPanel<R extends Enum<R>>
*
* @param sender
* The component that was clicked
- * @param updateVariable
- * Should the value field be updated
- *
*/
private void processClickEvent(Widget sender) {
if (!isEnabled() || isReadonly()) {
diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java b/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java
index 69da64a86c..85594484b3 100644
--- a/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java
+++ b/client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java
@@ -79,16 +79,16 @@ public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPane
/** For internal use only. May be removed or replaced in the future. */
public boolean parsable = true;
- private boolean open = false;
+ private boolean open;
/*
* #14857: If calendarToggle button is clicked when calendar popup is
* already open we should prevent calling openCalendarPanel() in onClick,
* since we don't want to reopen it again right after it closes.
*/
- private boolean preventOpenPopupCalendar = false;
- private boolean cursorOverCalendarToggleButton = false;
- private boolean toggleButtonClosesWithGuarantee = false;
+ private boolean preventOpenPopupCalendar;
+ private boolean cursorOverCalendarToggleButton;
+ private boolean toggleButtonClosesWithGuarantee;
private boolean textFieldEnabled = true;
@@ -217,25 +217,31 @@ public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPane
closeCalendarPanel();
}
+ /**
+ * Changes the current date, and updates the
+ * {@link VDateField#bufferedResolutions}, possibly
+ * {@link VDateField#sendBufferedValues()} to the server if needed
+ *
+ * @param newDate
+ * the new {@code Date} to update
+ */
@SuppressWarnings("deprecation")
public void updateValue(Date newDate) {
Date currentDate = getCurrentDate();
+ R resolution = getCurrentResolution();
if (currentDate == null || newDate.getTime() != currentDate.getTime()) {
setCurrentDate((Date) newDate.clone());
- getClient().updateVariable(getId(),
- getResolutionVariable(
- calendar.getResolution(calendar::isYear)),
- newDate.getYear() + 1900, false);
- if (!calendar.isYear(getCurrentResolution())) {
- getClient().updateVariable(getId(),
- getResolutionVariable(
- calendar.getResolution(calendar::isMonth)),
- newDate.getMonth() + 1, false);
- if (!calendar.isMonth(getCurrentResolution())) {
- getClient().updateVariable(getId(),
- getResolutionVariable(
- calendar.getResolution(calendar::isDay)),
- newDate.getDate(), false);
+ bufferedResolutions.put(
+ calendar.getResolution(calendar::isYear).name(),
+ newDate.getYear() + 1900);
+ if (!calendar.isYear(resolution)) {
+ bufferedResolutions.put(
+ calendar.getResolution(calendar::isMonth).name(),
+ newDate.getMonth() + 1);
+ if (!calendar.isMonth(resolution)) {
+ bufferedResolutions.put(
+ calendar.getResolution(calendar::isDay).name(),
+ newDate.getDate());
}
}
}
diff --git a/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java b/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java
index d466677419..edbc863188 100644
--- a/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java
+++ b/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java
@@ -66,7 +66,7 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
/** For internal use only. May be removed or replaced in the future. */
public boolean lenient;
- private final String TEXTFIELD_ID = "field";
+ private static final String TEXTFIELD_ID = "field";
/** For internal use only. May be removed or replaced in the future. */
private String formatStr;
@@ -104,7 +104,7 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
*
* @return the format string
*/
- protected String getFormatString() {
+ public String getFormatString() {
if (formatStr == null) {
setFormatString(createFormatString());
}
@@ -138,8 +138,8 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
* Sets the date format string to use for the text field.
*
* @param formatString
- * the format string to use, or null to force re-creating the
- * format string from the locale the next time it is needed
+ * the format string to use, or {@code null} to force re-creating
+ * the format string from the locale the next time it is needed
* @since 8.1
*/
public void setFormatString(String formatString) {
@@ -244,8 +244,7 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
addStyleName(getStylePrimaryName() + PARSE_ERROR_CLASSNAME);
// this is a hack that may eventually be removed
- getClient().updateVariable(getId(), "lastInvalidDateString",
- text.getText(), false);
+ bufferedInvalidDateString = true;
setDate(null);
}
} else {
@@ -253,10 +252,9 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
// remove possibly added invalid value indication
removeStyleName(getStylePrimaryName() + PARSE_ERROR_CLASSNAME);
}
- // always send the date string
- getClient().updateVariable(getId(), "dateString", text.getText(),
- false);
+ // always send the date string
+ bufferedDateString = text.getText();
updateDateVariables();
}
@@ -266,17 +264,20 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
* The method can be overridden by subclasses to provide a custom logic for
* date variables to avoid overriding the {@link #onChange(ChangeEvent)}
* method.
+ *
+ * @since
*/
protected void updateDateVariables() {
// Update variables
// (only the smallest defining resolution needs to be
// immediate)
Date currentDate = getDate();
- getClient().updateVariable(getId(),
- getResolutionVariable(getResolutions().filter(this::isYear)
- .findFirst().get()),
- currentDate != null ? currentDate.getYear() + 1900 : -1,
- isYear(getCurrentResolution()));
+ bufferedResolutions.put(
+ getResolutions().filter(this::isYear).findFirst().get().name(),
+ currentDate != null ? currentDate.getYear() + 1900 : null);
+ if (isYear(getCurrentResolution())) {
+ sendBufferedValues();
+ }
}
/**
@@ -390,7 +391,14 @@ public abstract class VAbstractTextualDate<R extends Enum<R>>
}
if (getClient() != null && getClient()
.hasEventListeners(VAbstractTextualDate.this, eventId)) {
- getClient().updateVariable(getId(), eventId, "", true);
+ // may excessively send events if if focus went to another
+ // sub-component
+ if (EventId.FOCUS.equals(eventId)) {
+ rpc.focus();
+ } else {
+ rpc.blur();
+ }
+ sendBufferedValues();
}
// Needed for tooltip event handling
diff --git a/client/src/main/java/com/vaadin/client/ui/VDateField.java b/client/src/main/java/com/vaadin/client/ui/VDateField.java
index 772f72c897..558ddaa494 100644
--- a/client/src/main/java/com/vaadin/client/ui/VDateField.java
+++ b/client/src/main/java/com/vaadin/client/ui/VDateField.java
@@ -17,6 +17,7 @@
package com.vaadin.client.ui;
import java.util.Date;
+import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Stream;
@@ -25,6 +26,7 @@ import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasEnabled;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.DateTimeService;
+import com.vaadin.shared.ui.datefield.AbstractDateFieldServerRpc;
/**
* A very base widget class for a date field.
@@ -54,21 +56,56 @@ public abstract class VDateField<R extends Enum<R>> extends FlowPanel
protected boolean enabled;
/**
+ * The RPC send calls to the server.
+ *
+ * @since
+ */
+ public AbstractDateFieldServerRpc rpc;
+
+ /**
+ * A temporary holder of the time units (resolutions), which would be sent
+ * to the server through {@link #sendBufferedValues()}.
+ *
+ * The key is the resolution name e.g. "HOUR", "MINUTE".
+ *
+ * The value can be {@code null}.
+ *
+ * @since
+ */
+ protected Map<String, Integer> bufferedResolutions = new HashMap<>();
+
+ /**
+ * A temporary holder of the date string, which would be sent to the server
+ * through {@link #sendBufferedValues()}.
+ *
+ * @since
+ */
+ protected String bufferedDateString;
+
+ /**
+ * A temporary holder of whether the date string was invalid or not, which
+ * would be sent to the server through {@link #sendBufferedValues()}.
+ *
+ * @since
+ */
+ protected boolean bufferedInvalidDateString;
+
+ /**
* The date that is displayed the date field before a value is selected. If
* null, display the current date.
*/
- private Date defaultDate = null;
+ private Date defaultDate;
/**
* The date that is selected in the date field. Null if an invalid date is
* specified.
*/
- private Date date = null;
+ private Date date;
/** For internal use only. May be removed or replaced in the future. */
public DateTimeService dts;
- protected boolean showISOWeekNumbers = false;
+ protected boolean showISOWeekNumbers;
public VDateField(R resolution) {
setStyleName(CLASSNAME);
@@ -232,6 +269,20 @@ public abstract class VDateField<R extends Enum<R>> extends FlowPanel
}
/**
+ * Sends the {@link #bufferedDateString}, {@link #bufferedInvalidDateString}
+ * and {@link #bufferedResolutions} to the server, and clears their values.
+ *
+ * @since
+ */
+ public void sendBufferedValues() {
+ rpc.update(bufferedDateString, bufferedInvalidDateString,
+ new HashMap<>(bufferedResolutions));
+ bufferedDateString = null;
+ bufferedInvalidDateString = false;
+ bufferedResolutions.clear();
+ }
+
+ /**
* Returns all available resolutions for the field in the ascending order
* (which is the same as order of enumeration ordinals).
* <p>
diff --git a/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java b/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java
index ada512c8b1..69e6d923ce 100644
--- a/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java
+++ b/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java
@@ -50,25 +50,22 @@ public class VDateFieldCalendar
Date date2 = calendarPanel.getDate();
Date currentDate = getCurrentDate();
+ DateResolution resolution = getCurrentResolution();
if (currentDate == null || date2.getTime() != currentDate.getTime()) {
setCurrentDate((Date) date2.clone());
- getClient().updateVariable(getId(),
- getResolutionVariable(DateResolution.YEAR),
+ bufferedResolutions.put(DateResolution.YEAR.name(),
// Java Date uses the year aligned to 1900 (no to zero).
// So we should add 1900 to get a correct year aligned to 0.
- date2.getYear() + 1900, false);
- if (getCurrentResolution().compareTo(DateResolution.YEAR) < 0) {
- getClient().updateVariable(getId(),
- getResolutionVariable(DateResolution.MONTH),
- date2.getMonth() + 1, false);
- if (getCurrentResolution()
- .compareTo(DateResolution.MONTH) < 0) {
- getClient().updateVariable(getId(),
- getResolutionVariable(DateResolution.DAY),
- date2.getDate(), false);
+ date2.getYear() + 1900);
+ if (resolution.compareTo(DateResolution.YEAR) < 0) {
+ bufferedResolutions.put(DateResolution.MONTH.name(),
+ date2.getMonth() + 1);
+ if (resolution.compareTo(DateResolution.MONTH) < 0) {
+ bufferedResolutions.put(DateResolution.DAY.name(),
+ date2.getDate());
}
}
- getClient().sendPendingVariableChanges();
+ sendBufferedValues();
}
}
diff --git a/client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java b/client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java
index 55922e4825..8f27c920cc 100644
--- a/client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java
+++ b/client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java
@@ -91,11 +91,11 @@ public class VDateTimeCalendarPanel
if (getDateTimeService().isTwelveHourClock()) {
hours.addItem("12");
for (int i = 1; i < 12; i++) {
- hours.addItem((i < 10) ? "0" + i : "" + i);
+ hours.addItem(asTwoDigits(i));
}
} else {
for (int i = 0; i < 24; i++) {
- hours.addItem((i < 10) ? "0" + i : "" + i);
+ hours.addItem(asTwoDigits(i));
}
}
@@ -111,14 +111,14 @@ public class VDateTimeCalendarPanel
if (getResolution().compareTo(DateTimeResolution.MINUTE) <= 0) {
mins = createListBox();
for (int i = 0; i < 60; i++) {
- mins.addItem((i < 10) ? "0" + i : "" + i);
+ mins.addItem(asTwoDigits(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.addItem(asTwoDigits(i));
}
sec.addChangeHandler(this);
}
@@ -132,7 +132,7 @@ public class VDateTimeCalendarPanel
if (getDateTimeService().isTwelveHourClock()) {
h -= h < 12 ? 0 : 12;
}
- add(new VLabel(h < 10 ? "0" + h : "" + h));
+ add(new VLabel(asTwoDigits(h)));
} else {
add(hours);
}
@@ -141,7 +141,7 @@ public class VDateTimeCalendarPanel
add(new VLabel(delimiter));
if (isReadonly()) {
final int m = mins.getSelectedIndex();
- add(new VLabel(m < 10 ? "0" + m : "" + m));
+ add(new VLabel(asTwoDigits(m)));
} else {
add(mins);
}
@@ -150,7 +150,7 @@ public class VDateTimeCalendarPanel
add(new VLabel(delimiter));
if (isReadonly()) {
final int s = sec.getSelectedIndex();
- add(new VLabel(s < 10 ? "0" + s : "" + s));
+ add(new VLabel(asTwoDigits(s)));
} else {
add(sec);
}
@@ -193,7 +193,6 @@ public class VDateTimeCalendarPanel
}
}
});
-
}
private ListBox getLastDropDown() {
@@ -243,14 +242,16 @@ public class VDateTimeCalendarPanel
if (ampm != null) {
ampm.setEnabled(isEnabled());
}
-
}
private DateTimeService getDateTimeService() {
- if (VDateTimeCalendarPanel.this.getDateTimeService() == null) {
- setDateTimeService(new DateTimeService());
+ DateTimeService dts = VDateTimeCalendarPanel.this
+ .getDateTimeService();
+ if (dts == null) {
+ dts = new DateTimeService();
+ setDateTimeService(dts);
}
- return VDateTimeCalendarPanel.this.getDateTimeService();
+ return dts;
}
/*
@@ -312,7 +313,10 @@ public class VDateTimeCalendarPanel
event.stopPropagation();
}
}
+ }
+ private static String asTwoDigits(int i) {
+ return (i < 10 ? "0" : "") + i;
}
/**
diff --git a/client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java b/client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java
index 3d2b13becb..6e74bf45e7 100644
--- a/client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java
+++ b/client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java
@@ -46,46 +46,41 @@ public class VDateTimeFieldCalendar extends
Date date2 = calendarPanel.getDate();
Date currentDate = getCurrentDate();
+ DateTimeResolution resolution = getCurrentResolution();
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()
+ addBufferedResolution(DateTimeResolution.YEAR,
+ date2.getYear() + 1900);
+ if (resolution.compareTo(DateTimeResolution.YEAR) < 0) {
+ addBufferedResolution(DateTimeResolution.MONTH,
+ date2.getMonth() + 1);
+ if (resolution.compareTo(DateTimeResolution.MONTH) < 0) {
+ addBufferedResolution(DateTimeResolution.DAY,
+ date2.getDate());
+ if (resolution.compareTo(DateTimeResolution.DAY) < 0) {
+ addBufferedResolution(DateTimeResolution.HOUR,
+ date2.getHours());
+ if (resolution.compareTo(DateTimeResolution.HOUR) < 0) {
+ addBufferedResolution(DateTimeResolution.MINUTE,
+ date2.getMinutes());
+ if (resolution
.compareTo(DateTimeResolution.MINUTE) < 0) {
- getClient().updateVariable(getId(),
- getResolutionVariable(
- DateTimeResolution.SECOND),
- date2.getSeconds(), false);
+ addBufferedResolution(DateTimeResolution.SECOND,
+ date2.getSeconds());
}
}
}
}
}
- getClient().sendPendingVariableChanges();
+ sendBufferedValues();
}
}
+ private void addBufferedResolution(DateTimeResolution resolution,
+ Integer value) {
+ bufferedResolutions.put(resolution.name(), value);
+ }
+
@Override
public String resolutionAsString() {
if (getCurrentResolution().compareTo(DateTimeResolution.DAY) >= 0) {
diff --git a/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java b/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java
index 9237014423..65c47f8c6c 100644
--- a/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java
+++ b/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java
@@ -52,20 +52,20 @@ public class VPopupCalendar
}
public static Date makeDate(Map<DateResolution, Integer> dateValues) {
- if (dateValues.get(DateResolution.YEAR) == -1) {
+ if (dateValues.get(DateResolution.YEAR) == null) {
return null;
}
Date date = new Date(2000 - 1900, 0, 1);
- int year = dateValues.get(DateResolution.YEAR);
- if (year >= 0) {
+ Integer year = dateValues.get(DateResolution.YEAR);
+ if (year != null) {
date.setYear(year - 1900);
}
- int month = dateValues.get(DateResolution.MONTH);
- if (month >= 0) {
+ Integer month = dateValues.get(DateResolution.MONTH);
+ if (month != null) {
date.setMonth(month - 1);
}
- int day = dateValues.get(DateResolution.DAY);
- if (day >= 0) {
+ Integer day = dateValues.get(DateResolution.DAY);
+ if (day != null) {
date.setDate(day);
}
return date;
@@ -84,22 +84,20 @@ public class VPopupCalendar
@Override
protected void updateDateVariables() {
super.updateDateVariables();
+ DateResolution resolution = getCurrentResolution();
// Update variables
// (only the smallest defining resolution needs to be
// immediate)
Date currentDate = getDate();
- if (getCurrentResolution().compareTo(DateResolution.MONTH) <= 0) {
- getClient().updateVariable(getId(),
- getResolutionVariable(DateResolution.MONTH),
- currentDate != null ? currentDate.getMonth() + 1 : -1,
- getCurrentResolution() == DateResolution.MONTH);
+ if (resolution.compareTo(DateResolution.MONTH) <= 0) {
+ bufferedResolutions.put(DateResolution.MONTH.name(),
+ currentDate != null ? currentDate.getMonth() + 1 : null);
}
- if (getCurrentResolution().compareTo(DateResolution.DAY) <= 0) {
- getClient().updateVariable(getId(),
- getResolutionVariable(DateResolution.DAY),
- currentDate != null ? currentDate.getDate() : -1,
- getCurrentResolution() == DateResolution.DAY);
+ if (resolution.compareTo(DateResolution.DAY) <= 0) {
+ bufferedResolutions.put(DateResolution.DAY.name(),
+ currentDate != null ? currentDate.getDate() : null);
}
+ sendBufferedValues();
}
@Override
diff --git a/client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java b/client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java
index 2805a4e7a6..ff740efbca 100644
--- a/client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java
+++ b/client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java
@@ -61,32 +61,32 @@ public class VPopupTimeCalendar extends
}
public static Date makeDate(Map<DateTimeResolution, Integer> dateValues) {
- if (dateValues.get(DateTimeResolution.YEAR) == -1) {
+ if (dateValues.get(DateTimeResolution.YEAR) == null) {
return null;
}
Date date = new Date(2000 - 1900, 0, 1);
- int year = dateValues.get(DateTimeResolution.YEAR);
- if (year >= 0) {
+ Integer year = dateValues.get(DateTimeResolution.YEAR);
+ if (year != null) {
date.setYear(year - 1900);
}
- int month = dateValues.get(DateTimeResolution.MONTH);
- if (month >= 0) {
+ Integer month = dateValues.get(DateTimeResolution.MONTH);
+ if (month != null) {
date.setMonth(month - 1);
}
- int day = dateValues.get(DateTimeResolution.DAY);
- if (day >= 0) {
+ Integer day = dateValues.get(DateTimeResolution.DAY);
+ if (day != null) {
date.setDate(day);
}
- int hour = dateValues.get(DateTimeResolution.HOUR);
- if (hour >= 0) {
+ Integer hour = dateValues.get(DateTimeResolution.HOUR);
+ if (hour != null) {
date.setHours(hour);
}
- int minute = dateValues.get(DateTimeResolution.MINUTE);
- if (minute >= 0) {
+ Integer minute = dateValues.get(DateTimeResolution.MINUTE);
+ if (minute != null) {
date.setMinutes(minute);
}
- int second = dateValues.get(DateTimeResolution.SECOND);
- if (second >= 0) {
+ Integer second = dateValues.get(DateTimeResolution.SECOND);
+ if (second != null) {
date.setSeconds(second);
}
return date;
@@ -105,40 +105,36 @@ public class VPopupTimeCalendar extends
@Override
protected void updateDateVariables() {
super.updateDateVariables();
- // Update variables
+ DateTimeResolution resolution = getCurrentResolution();
// (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);
+ if (resolution.compareTo(DateTimeResolution.MONTH) <= 0) {
+ addBufferedResolution(DateTimeResolution.MONTH,
+ currentDate != null ? currentDate.getMonth() + 1 : null);
}
+ if (resolution.compareTo(DateTimeResolution.DAY) <= 0) {
+ addBufferedResolution(DateTimeResolution.DAY,
+ currentDate != null ? currentDate.getDate() : null);
+ }
+ if (resolution.compareTo(DateTimeResolution.HOUR) <= 0) {
+ addBufferedResolution(DateTimeResolution.HOUR,
+ currentDate != null ? currentDate.getHours() : null);
+ }
+ if (resolution.compareTo(DateTimeResolution.MINUTE) <= 0) {
+ addBufferedResolution(DateTimeResolution.MINUTE,
+ currentDate != null ? currentDate.getMinutes() : null);
+ }
+ if (resolution.compareTo(DateTimeResolution.SECOND) <= 0) {
+ addBufferedResolution(DateTimeResolution.SECOND,
+ currentDate != null ? currentDate.getSeconds() : null);
+ }
+ sendBufferedValues();
+ }
+
+ private void addBufferedResolution(DateTimeResolution resolutionToAdd,
+ Integer value) {
+ bufferedResolutions.put(resolutionToAdd.name(), value);
}
@Override
@@ -146,22 +142,18 @@ public class VPopupTimeCalendar extends
public void updateValue(Date newDate) {
Date currentDate = getCurrentDate();
super.updateValue(newDate);
+ DateTimeResolution resolution = getCurrentResolution();
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);
+ if (resolution.compareTo(DateTimeResolution.DAY) < 0) {
+ bufferedResolutions.put(DateTimeResolution.HOUR.name(),
+ newDate.getHours());
+ if (resolution.compareTo(DateTimeResolution.HOUR) < 0) {
+ bufferedResolutions.put(DateTimeResolution.MINUTE.name(),
+ newDate.getMinutes());
+ if (resolution.compareTo(DateTimeResolution.MINUTE) < 0) {
+ bufferedResolutions.put(
+ DateTimeResolution.SECOND.name(),
+ newDate.getSeconds());
}
}
}
@@ -197,7 +189,6 @@ public class VPopupTimeCalendar extends
if (dts.isTwelveHourClock()) {
frmString += " aaa";
}
-
}
return frmString;
diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractDateFieldConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractDateFieldConnector.java
index 21e85773de..2aad416343 100644
--- a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractDateFieldConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractDateFieldConnector.java
@@ -21,101 +21,61 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.LocaleNotLoadedException;
-import com.vaadin.client.Paintable;
-import com.vaadin.client.UIDL;
import com.vaadin.client.VConsole;
+import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractFieldConnector;
import com.vaadin.client.ui.VDateField;
-import com.vaadin.shared.ui.datefield.DateFieldConstants;
+import com.vaadin.shared.ui.datefield.AbstractDateFieldServerRpc;
+import com.vaadin.shared.ui.datefield.AbstractDateFieldState;
public abstract class AbstractDateFieldConnector<R extends Enum<R>>
- extends AbstractFieldConnector implements Paintable {
+ extends AbstractFieldConnector {
@Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- if (!isRealUpdate(uidl)) {
- return;
- }
-
- // Save details
- getWidget().client = client;
- getWidget().paintableId = uidl.getId();
-
- getWidget().setReadonly(isReadOnly());
- getWidget().setEnabled(isEnabled());
-
- if (uidl.hasAttribute("locale")) {
- final String locale = uidl.getStringAttribute("locale");
- try {
- getWidget().dts.setLocale(locale);
- getWidget().setCurrentLocale(locale);
- } catch (final LocaleNotLoadedException e) {
- getWidget().setCurrentLocale(getWidget().dts.getLocale());
- VConsole.error("Tried to use an unloaded locale \"" + locale
- + "\". Using default locale ("
- + getWidget().getCurrentLocale() + ").");
- VConsole.error(e);
- }
- }
-
- // We show week numbers only if the week starts with Monday, as ISO 8601
- // specifies
- getWidget().setShowISOWeekNumbers(
- uidl.getBooleanAttribute(DateFieldConstants.ATTR_WEEK_NUMBERS)
- && getWidget().dts.getFirstDayOfWeek() == 1);
-
- // Remove old stylename that indicates current resolution
- setWidgetStyleName(getWidget().getStylePrimaryName() + "-"
- + getWidget().resolutionAsString(), false);
-
- updateResolution(uidl);
-
- // Add stylename that indicates current resolution
- setWidgetStyleName(getWidget().getStylePrimaryName() + "-"
- + getWidget().resolutionAsString(), true);
-
- getWidget().setCurrentDate(getTimeValues(uidl));
- getWidget().setDefaultDate(getDefaultValues(uidl));
+ protected void init() {
+ super.init();
+ getWidget().rpc = getRpcProxy(AbstractDateFieldServerRpc.class);
}
- private void updateResolution(UIDL uidl) {
- Optional<R> newResolution = getWidget().getResolutions().filter(
- res -> uidl.hasVariable(getWidget().getResolutionVariable(res)))
+ private void updateResolution() {
+ VDateField<R> widget = getWidget();
+ Map<String, Integer> stateResolutions = getState().resolutions;
+ Optional<R> newResolution = widget.getResolutions()
+ .filter(res -> stateResolutions.containsKey(res.name()))
.findFirst();
- getWidget().setCurrentResolution(newResolution.orElse(null));
+ widget.setCurrentResolution(newResolution.orElse(null));
}
- protected Map<R, Integer> getTimeValues(UIDL uidl) {
- Stream<R> resolutions = getWidget().getResolutions();
- R resolution = getWidget().getCurrentResolution();
- return resolutions
- .collect(Collectors.toMap(Function.identity(),
- res -> (resolution.compareTo(res) <= 0)
- ? uidl.getIntVariable(
- getWidget().getResolutionVariable(res))
- : -1));
+ private Map<R, Integer> getTimeValues() {
+ VDateField<R> widget = getWidget();
+ Map<String, Integer> stateResolutions = getState().resolutions;
+ Stream<R> resolutions = widget.getResolutions();
+ R resolution = widget.getCurrentResolution();
+ return resolutions.collect(Collectors.toMap(Function.identity(),
+ res -> res == null ? null
+ : (resolution.compareTo(res) <= 0)
+ ? stateResolutions.get(res.name())
+ : null));
}
/**
* Returns the default date (when no date is selected) components as a map
* from Resolution to the corresponding value.
*
- * @param uidl
- * UIDL with corresponding variables
* @return default date component map
- * @since 8.1.2
+ * @since
*/
- protected Map<R, Integer> getDefaultValues(UIDL uidl) {
+ protected Map<R, Integer> getDefaultValues() {
+ Map<String, Integer> stateResolutions = getState().resolutions;
Stream<R> resolutions = getWidget().getResolutions();
R resolution = getWidget().getCurrentResolution();
return resolutions.collect(Collectors.toMap(Function.identity(),
- res -> (resolution.compareTo(res) <= 0)
- ? uidl.getIntVariable("default-"
- + getWidget().getResolutionVariable(res))
- : -1));
+ res -> res == null ? null
+ : (resolution.compareTo(res) <= 0)
+ ? stateResolutions.get("default-" + res.name())
+ : null));
}
@SuppressWarnings("unchecked")
@@ -124,4 +84,51 @@ public abstract class AbstractDateFieldConnector<R extends Enum<R>>
return (VDateField<R>) super.getWidget();
}
+ @Override
+ public AbstractDateFieldState getState() {
+ return (AbstractDateFieldState) super.getState();
+ }
+
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ super.onStateChanged(stateChangeEvent);
+ VDateField<R> widget = getWidget();
+
+ // Save details
+ widget.client = getConnection();
+ widget.paintableId = getConnectorId();
+
+ widget.setReadonly(isReadOnly());
+ widget.setEnabled(isEnabled());
+
+ final String locale = getState().locale;
+ try {
+ widget.dts.setLocale(locale);
+ widget.setCurrentLocale(locale);
+ } catch (final LocaleNotLoadedException e) {
+ widget.setCurrentLocale(widget.dts.getLocale());
+ VConsole.error("Tried to use an unloaded locale \"" + locale
+ + "\". Using default locale (" + widget.getCurrentLocale()
+ + ").");
+ VConsole.error(e);
+ }
+
+ // We show week numbers only if the week starts with Monday, as ISO 8601
+ // specifies
+ widget.setShowISOWeekNumbers(getState().showISOWeekNumbers
+ && widget.dts.getFirstDayOfWeek() == 1);
+
+ // Remove old stylename that indicates current resolution
+ setWidgetStyleName(widget.getStylePrimaryName() + "-"
+ + widget.resolutionAsString(), false);
+
+ updateResolution();
+
+ // Add stylename that indicates current resolution
+ setWidgetStyleName(widget.getStylePrimaryName() + "-"
+ + widget.resolutionAsString(), true);
+
+ widget.setCurrentDate(getTimeValues());
+ widget.setDefaultDate(getDefaultValues());
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java
index 3d12956247..b98452966f 100644
--- a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractInlineDateFieldConnector.java
@@ -39,33 +39,6 @@ import com.vaadin.shared.ui.datefield.InlineDateFieldState;
public abstract class AbstractInlineDateFieldConnector<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>>
extends AbstractDateFieldConnector<R> {
- @Override
- @SuppressWarnings("deprecation")
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- super.updateFromUIDL(uidl, client);
- if (!isRealUpdate(uidl)) {
- return;
- }
-
- getWidget().calendarPanel
- .setShowISOWeekNumbers(getWidget().isShowISOWeekNumbers());
- getWidget().calendarPanel
- .setDateTimeService(getWidget().getDateTimeService());
- getWidget().calendarPanel
- .setResolution(getWidget().getCurrentResolution());
- Date currentDate = getWidget().getCurrentDate();
- if (currentDate != null) {
- getWidget().calendarPanel.setDate(new Date(currentDate.getTime()));
- } else {
- getWidget().calendarPanel.setDate(null);
- }
-
- updateListeners();
-
- // Update possible changes
- getWidget().calendarPanel.renderCalendar();
- }
-
/**
* Updates listeners registered (or register them) for the widget based on
* the current resolution.
@@ -108,6 +81,24 @@ public abstract class AbstractInlineDateFieldConnector<PANEL extends VAbstractCa
getWidget().setTabIndex(getState().tabIndex);
getWidget().calendarPanel.setRangeStart(getState().rangeStart);
getWidget().calendarPanel.setRangeEnd(getState().rangeEnd);
+
+ getWidget().calendarPanel
+ .setShowISOWeekNumbers(getWidget().isShowISOWeekNumbers());
+ getWidget().calendarPanel
+ .setDateTimeService(getWidget().getDateTimeService());
+ getWidget().calendarPanel
+ .setResolution(getWidget().getCurrentResolution());
+ Date currentDate = getWidget().getCurrentDate();
+ if (currentDate != null) {
+ getWidget().calendarPanel.setDate(new Date(currentDate.getTime()));
+ } else {
+ getWidget().calendarPanel.setDate(null);
+ }
+
+ updateListeners();
+
+ // Update possible changes
+ getWidget().calendarPanel.renderCalendar();
}
@Override
diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java
index 81eea0e71e..856e9948a8 100644
--- a/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/datefield/AbstractTextualDateConnector.java
@@ -18,9 +18,8 @@ package com.vaadin.client.ui.datefield;
import com.google.gwt.i18n.client.TimeZone;
import com.google.gwt.i18n.client.TimeZoneInfo;
-import com.vaadin.client.ApplicationConnection;
-import com.vaadin.client.UIDL;
import com.vaadin.client.annotations.OnStateChange;
+import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.VAbstractTextualDate;
import com.vaadin.shared.ui.datefield.AbstractTextualDateFieldState;
@@ -37,34 +36,6 @@ public abstract class AbstractTextualDateConnector<R extends Enum<R>>
extends AbstractDateFieldConnector<R> {
@Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- R origRes = getWidget().getCurrentResolution();
- String oldLocale = getWidget().getCurrentLocale();
- super.updateFromUIDL(uidl, client);
- if (origRes != getWidget().getCurrentResolution()
- || oldLocale != getWidget().getCurrentLocale()) {
- // force recreating format string
- getWidget().setFormatString(null);
- }
- if (uidl.hasAttribute("format")) {
- getWidget().setFormatString(uidl.getStringAttribute("format"));
- }
-
- getWidget().lenient = !uidl.getBooleanAttribute("strict");
-
- getWidget().buildDate();
- // not a FocusWidget -> needs own tabindex handling
- getWidget().text.setTabIndex(getState().tabIndex);
-
- if (getWidget().isReadonly()) {
- getWidget().text.addStyleDependentName("readonly");
- } else {
- getWidget().text.removeStyleDependentName("readonly");
- }
-
- }
-
- @Override
public VAbstractTextualDate<R> getWidget() {
return (VAbstractTextualDate<R>) super.getWidget();
}
@@ -88,4 +59,36 @@ public abstract class AbstractTextualDateConnector<R extends Enum<R>>
getWidget().setTimeZone(timeZone);
}
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ VAbstractTextualDate<R> widget = getWidget();
+ AbstractTextualDateFieldState state = getState();
+
+ R origRes = widget.getCurrentResolution();
+ String oldLocale = widget.getCurrentLocale();
+
+ super.onStateChanged(stateChangeEvent);
+
+ if (origRes != widget.getCurrentResolution()
+ || oldLocale != widget.getCurrentLocale()) {
+ // force recreating format string
+ widget.setFormatString(null);
+ }
+ if (state.format != widget.getFormatString()) {
+ widget.setFormatString(state.format);
+ }
+
+ widget.lenient = state.lenient;
+
+ // may be excessively called on every state change
+ widget.buildDate();
+ // not a FocusWidget -> needs own tabindex handling
+ widget.text.setTabIndex(state.tabIndex);
+
+ if (widget.isReadonly()) {
+ widget.text.addStyleDependentName("readonly");
+ } else {
+ widget.text.removeStyleDependentName("readonly");
+ }
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java b/client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java
index 0c61f3860e..f2957efc3e 100644
--- a/client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java
+++ b/client/src/main/java/com/vaadin/client/ui/datefield/TextualDateConnector.java
@@ -48,6 +48,7 @@ public abstract class TextualDateConnector<PANEL extends VAbstractCalendarPanel<
@Override
protected void init() {
+ super.init();
getWidget().popup.addCloseHandler(new CloseHandler<PopupPanel>() {
@Override
@@ -55,28 +56,77 @@ public abstract class TextualDateConnector<PANEL extends VAbstractCalendarPanel<
/*
* FIXME This is a hack so we do not have to rewrite half of the
* datefield so values are not sent while selecting a date
- * (#6252).
+ * (#1399).
*
- * The datefield will now only set the date UIDL variables while
- * the user is selecting year/month/date/time and not send them
+ * The datefield will now only set the date variables while the
+ * user is selecting year/month/date/time and not send them
* directly. Only when the user closes the popup (by clicking on
* a day/enter/clicking outside of popup) then the new value is
* communicated to the server.
*/
- getConnection().getServerRpcQueue().flush();
+ getWidget().sendBufferedValues();
}
});
}
+ /**
+ * Updates listeners registered (or register them) for the widget based on
+ * the current resolution.
+ * <p>
+ * Subclasses may override this method to keep the common logic inside the
+ * {@link #updateFromUIDL(UIDL, ApplicationConnection)} method as is and
+ * customizing only listeners logic.
+ */
+ protected void updateListeners() {
+ FocusChangeListener listener;
+ if (isResolutionMonthOrHigher()) {
+ listener = new FocusChangeListener() {
+ @Override
+ public void focusChanged(Date date) {
+ if (isResolutionMonthOrHigher()) {
+ getWidget().updateValue(date);
+ getWidget().buildDate();
+ Date date2 = getWidget().calendar.getDate();
+ date2.setYear(date.getYear());
+ date2.setMonth(date.getMonth());
+ }
+ }
+ };
+ } else {
+ listener = null;
+ }
+ getWidget().calendar.setFocusChangeListener(listener);
+ }
+
+ /**
+ * 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<PANEL, R> getWidget() {
+ return (VAbstractPopupCalendar<PANEL, R>) super.getWidget();
+ }
+
@Override
- @SuppressWarnings("deprecation")
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ public TextualDateFieldState getState() {
+ return (TextualDateFieldState) super.getState();
+ }
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
String oldLocale = getWidget().getCurrentLocale();
- getWidget().parsable = uidl.getBooleanAttribute("parsable");
+ getWidget().parsable = getState().parsable;
- super.updateFromUIDL(uidl, client);
+ super.onStateChanged(stateChangeEvent);
+
+ getWidget().setTextFieldEnabled(getState().textFieldEnabled);
+ getWidget().setRangeStart(nullSafeDateClone(getState().rangeStart));
+ getWidget().setRangeEnd(nullSafeDateClone(getState().rangeEnd));
getWidget().calendar
.setDateTimeService(getWidget().getDateTimeService());
@@ -118,66 +168,11 @@ public abstract class TextualDateConnector<PANEL extends VAbstractCalendarPanel<
getWidget().setTextFieldTabIndex();
}
- /**
- * Updates listeners registered (or register them) for the widget based on
- * the current resolution.
- * <p>
- * Subclasses may override this method to keep the common logic inside the
- * {@link #updateFromUIDL(UIDL, ApplicationConnection)} method as is and
- * customizing only listeners logic.
- */
- protected void updateListeners() {
- if (isResolutionMonthOrHigher()) {
- getWidget().calendar
- .setFocusChangeListener(new FocusChangeListener() {
- @Override
- public void focusChanged(Date date) {
- if (isResolutionMonthOrHigher()) {
- getWidget().updateValue(date);
- getWidget().buildDate();
- Date date2 = getWidget().calendar.getDate();
- date2.setYear(date.getYear());
- date2.setMonth(date.getMonth());
- }
- }
- });
- } else {
- getWidget().calendar.setFocusChangeListener(null);
- }
- }
-
- /**
- * 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<PANEL, R> getWidget() {
- return (VAbstractPopupCalendar<PANEL, R>) super.getWidget();
- }
-
- @Override
- public TextualDateFieldState getState() {
- return (TextualDateFieldState) super.getState();
- }
-
- @Override
- public void onStateChanged(StateChangeEvent stateChangeEvent) {
- super.onStateChanged(stateChangeEvent);
- getWidget().setTextFieldEnabled(getState().textFieldEnabled);
- getWidget().setRangeStart(nullSafeDateClone(getState().rangeStart));
- getWidget().setRangeEnd(nullSafeDateClone(getState().rangeEnd));
- }
-
private Date nullSafeDateClone(Date date) {
- if (date == null) {
- return null;
- } else {
+ if (date != null) {
return (Date) date.clone();
}
+ return null;
}
@Override
@@ -196,14 +191,10 @@ public abstract class TextualDateConnector<PANEL extends VAbstractCalendarPanel<
// update the style change to popup calendar widget with the correct
// prefix
if (!styleName.startsWith("-")) {
- getWidget().popup.setStyleName(
- getWidget().getStylePrimaryName() + "-popup-" + styleName,
- add);
- } else {
- getWidget().popup.setStyleName(
- getWidget().getStylePrimaryName() + "-popup" + styleName,
- add);
+ styleName = "-" + styleName;
}
+ getWidget().popup.setStyleName(
+ getWidget().getStylePrimaryName() + "-popup" + styleName, add);
}
}
diff --git a/server/src/main/java/com/vaadin/ui/AbstractDateField.java b/server/src/main/java/com/vaadin/ui/AbstractDateField.java
index b5f11f7122..bfe3119f26 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractDateField.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractDateField.java
@@ -48,12 +48,10 @@ import com.vaadin.event.FieldEvents.BlurNotifier;
import com.vaadin.event.FieldEvents.FocusEvent;
import com.vaadin.event.FieldEvents.FocusListener;
import com.vaadin.event.FieldEvents.FocusNotifier;
-import com.vaadin.server.PaintException;
-import com.vaadin.server.PaintTarget;
import com.vaadin.server.UserError;
import com.vaadin.shared.Registration;
+import com.vaadin.shared.ui.datefield.AbstractDateFieldServerRpc;
import com.vaadin.shared.ui.datefield.AbstractDateFieldState;
-import com.vaadin.shared.ui.datefield.DateFieldConstants;
import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;
@@ -73,8 +71,86 @@ import com.vaadin.util.TimeZoneUtil;
*
*/
public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & Serializable & Comparable<? super T>, R extends Enum<R>>
- extends AbstractField<T>
- implements LegacyComponent, FocusNotifier, BlurNotifier {
+ extends AbstractField<T> implements FocusNotifier, BlurNotifier {
+
+ private AbstractDateFieldServerRpc rpc = new AbstractDateFieldServerRpc() {
+
+ @Override
+ public void update(String newDateString, boolean invalidDateString,
+ Map<String, Integer> resolutions) {
+ Set<String> resolutionNames = getResolutions()
+ .map(AbstractDateField.this::getResolutionVariable)
+ .collect(Collectors.toSet());
+ resolutionNames.retainAll(resolutions.keySet());
+ if (!isReadOnly()
+ && (!resolutionNames.isEmpty() || newDateString != null)) {
+
+ // Old and new dates
+ final T oldDate = getValue();
+
+ T newDate;
+
+ boolean hasChanges = false;
+
+ if ("".equals(newDateString)) {
+
+ newDate = null;
+ // TODO check if the following 3 lines are necessary
+ hasChanges = !getState(false).parsable;
+ getState().parsable = true;
+ currentParseErrorMessage = null;
+ } else {
+ newDate = reconstructDateFromFields(resolutions, oldDate);
+ }
+
+ hasChanges |= !Objects.equals(dateString, newDateString)
+ || !Objects.equals(oldDate, newDate);
+
+ if (hasChanges) {
+ dateString = newDateString;
+ if (newDateString == null || newDateString.isEmpty()) {
+ getState().parsable = true;
+ currentParseErrorMessage = null;
+ setComponentError(null);
+ setValue(newDate, true);
+ } else {
+ if (invalidDateString) {
+ Result<T> parsedDate = handleUnparsableDateString(
+ dateString);
+ parsedDate.ifOk(v -> {
+ getState().parsable = true;
+ currentParseErrorMessage = null;
+ setValue(v, true);
+ });
+ if (parsedDate.isError()) {
+ dateString = null;
+ getState().parsable = false;
+ currentParseErrorMessage = parsedDate
+ .getMessage().orElse("Parsing error");
+ setComponentError(
+ new UserError(getParseErrorMessage()));
+ setValue(null, true);
+ }
+ } else {
+ getState().parsable = true;
+ currentParseErrorMessage = null;
+ setValue(newDate, true);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void focus() {
+ fireEvent(new FocusEvent(AbstractDateField.this));
+ }
+
+ @Override
+ public void blur() {
+ fireEvent(new BlurEvent(AbstractDateField.this));
+ }
+ };
/**
* Value of the field.
@@ -86,36 +162,19 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
*
* @since 8.1.2
*/
- private T defaultValue = null;
+ private T defaultValue;
+
/**
* Specified smallest modifiable unit for the date field.
*/
private R resolution;
- /**
- * Overridden format string
- */
- private String dateFormat;
-
private ZoneId zoneId;
- private boolean lenient = false;
-
private String dateString = "";
private String currentParseErrorMessage;
- /**
- * Was the last entered string parsable? If this flag is false, datefields
- * internal validator does not pass.
- */
- private boolean uiHasValidDateString = true;
-
- /**
- * Determines if week numbers are shown in the date selector.
- */
- private boolean showISOWeekNumbers = false;
-
private String defaultParseErrorMessage = "Date format not recognized";
private String dateOutOfRangeMessage = "Date is out of allowed range";
@@ -127,10 +186,11 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
* specified {@code resolution}.
*
* @param resolution
- * initial resolution for the field
+ * initial resolution for the field, not {@code null}
*/
public AbstractDateField(R resolution) {
- this.resolution = resolution;
+ registerRpc(rpc);
+ setResolution(resolution);
}
/**
@@ -139,7 +199,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
* @param caption
* the caption of the datefield.
* @param resolution
- * initial resolution for the field
+ * initial resolution for the field, not {@code null}
*/
public AbstractDateField(String caption, R resolution) {
this(resolution);
@@ -155,7 +215,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
* @param value
* the date/time value.
* @param resolution
- * initial resolution for the field
+ * initial resolution for the field, not {@code null}
*/
public AbstractDateField(String caption, T value, R resolution) {
this(caption, resolution);
@@ -164,141 +224,21 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
/* Component basic features */
- /*
- * Paints this component. Don't add a JavaDoc comment here, we use the
- * default documentation from implemented interface.
- */
@Override
- public void paintContent(PaintTarget target) throws PaintException {
+ public void beforeClientResponse(boolean initial) {
+ super.beforeClientResponse(initial);
- // Adds the locale as attribute
- final Locale l = getLocale();
- if (l != null) {
- target.addAttribute("locale", l.toString());
- }
-
- if (getDateFormat() != null) {
- target.addAttribute("format", getDateFormat());
- }
-
- if (!isLenient()) {
- target.addAttribute("strict", true);
- }
-
- target.addAttribute(DateFieldConstants.ATTR_WEEK_NUMBERS,
- isShowISOWeekNumbers());
- target.addAttribute("parsable", uiHasValidDateString);
- final T currentDate = getValue();
-
- // Only paint variables for the resolution and up, e.g. Resolution DAY
- // paints DAY,MONTH,YEAR
- for (R res : getResolutionsHigherOrEqualTo(getResolution())) {
- int value = -1;
- if (currentDate != null) {
- value = getDatePart(currentDate, res);
- }
- String variableName = getResolutionVariable(res);
- target.addVariable(this, variableName, value);
- if (defaultValue != null) {
- int defaultValuePart = getDatePart(defaultValue, res);
- target.addVariable(this, "default-" + variableName,
- defaultValuePart);
- } else {
- target.addVariable(this, "default-" + variableName, -1);
- }
- }
- }
-
- /*
- * Invoked when a variable of the component changes. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- Set<String> resolutionNames = getResolutions()
- .map(this::getResolutionVariable).collect(Collectors.toSet());
- resolutionNames.retainAll(variables.keySet());
- if (!isReadOnly() && (!resolutionNames.isEmpty()
- || variables.containsKey("dateString"))) {
-
- // Old and new dates
- final T oldDate = getValue();
-
- // this enables analyzing invalid input on the server
- // this variable is null if the date was chosen with popup calendar
- // or contains user-typed string
- final String newDateString = (String) variables.get("dateString");
-
- T newDate;
-
- boolean hasChanges = false;
-
- if ("".equals(newDateString)) {
-
- newDate = null;
- // TODO check if the following 3 lines are necessary
- hasChanges = !uiHasValidDateString;
- uiHasValidDateString = true;
- currentParseErrorMessage = null;
- } else {
- newDate = reconstructDateFromFields(variables, oldDate);
- }
-
- hasChanges |= !Objects.equals(dateString, newDateString)
- || !Objects.equals(oldDate, newDate);
-
- if (hasChanges) {
- dateString = newDateString;
- if (newDateString == null || newDateString.isEmpty()) {
- uiHasValidDateString = true;
- currentParseErrorMessage = null;
- setComponentError(null);
- setValue(newDate, true);
- } else {
- if (variables.get("lastInvalidDateString") != null) {
- Result<T> parsedDate = handleUnparsableDateString(
- dateString);
- parsedDate.ifOk(v -> {
- uiHasValidDateString = true;
- currentParseErrorMessage = null;
- setValue(v, true);
- });
- if (parsedDate.isError()) {
- dateString = null;
- uiHasValidDateString = false;
- currentParseErrorMessage = parsedDate.getMessage()
- .orElse("Parsing error");
- setComponentError(
- new UserError(getParseErrorMessage()));
- setValue(null, true);
- }
- } else {
- uiHasValidDateString = true;
- currentParseErrorMessage = null;
- setValue(newDate, true);
- }
- }
- markAsDirty();
- }
- }
-
- if (variables.containsKey(FocusEvent.EVENT_ID)) {
- fireEvent(new FocusEvent(this));
- }
-
- if (variables.containsKey(BlurEvent.EVENT_ID)) {
- fireEvent(new BlurEvent(this));
- }
+ Locale locale = getLocale();
+ getState().locale = locale == null ? null : locale.toString();
}
/**
* Construct a date object from the individual field values received from
* the client.
*
- * @since 8.1.1
+ * @since
*/
- protected T reconstructDateFromFields(Map<String, Object> variables,
+ protected T reconstructDateFromFields(Map<String, Integer> variables,
T oldDate) {
Map<R, Integer> calendarFields = new HashMap<>();
@@ -307,8 +247,8 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
// resolutions that are painted
String variableName = getResolutionVariable(resolution);
- Integer newValue = (Integer) variables.get(variableName);
- if (newValue != null && newValue >= 0) {
+ Integer newValue = variables.get(variableName);
+ if (newValue != null) {
calendarFields.put(resolution, newValue);
} else {
calendarFields.put(resolution,
@@ -378,7 +318,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
*/
public void setResolution(R resolution) {
this.resolution = resolution;
- markAsDirty();
+ updateResolutions();
}
/**
@@ -429,23 +369,23 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
* override formatting. See Vaadin issue #2200.
*
* @param dateFormat
- * the dateFormat to set
+ * the dateFormat to set, can be {@code null}
*
* @see com.vaadin.ui.AbstractComponent#setLocale(Locale))
*/
public void setDateFormat(String dateFormat) {
- this.dateFormat = dateFormat;
- markAsDirty();
+ getState().format = dateFormat;
}
/**
- * Returns a format string used to format date value on client side or null
- * if default formatting from {@link Component#getLocale()} is used.
+ * Returns a format string used to format date value on client side or
+ * {@code null} if default formatting from {@link Component#getLocale()} is
+ * used.
*
* @return the dateFormat
*/
public String getDateFormat() {
- return dateFormat;
+ return getState(false).format;
}
/**
@@ -484,6 +424,32 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
super.setLocale(locale);
}
+ private void updateResolutions() {
+ final T currentDate = getValue();
+
+ Map<String, Integer> resolutions = getState().resolutions;
+ resolutions.clear();
+
+ // Only paint variables for the resolution and up, e.g. Resolution DAY
+ // paints DAY,MONTH,YEAR
+ for (R res : getResolutionsHigherOrEqualTo(getResolution())) {
+ String variableName = getResolutionVariable(res);
+
+ Integer value = getValuePart(currentDate, res);
+ resolutions.put(variableName, value);
+
+ Integer defaultValuePart = getValuePart(defaultValue, res);
+ resolutions.put("default-" + variableName, defaultValuePart);
+ }
+ }
+
+ private Integer getValuePart(T date, R resolution) {
+ if (date == null) {
+ return null;
+ }
+ return getDatePart(date, resolution);
+ }
+
/**
* Returns the {@link ZoneId}, which is used when {@code z} is included
* inside the {@link #setDateFormat(String)}.
@@ -507,20 +473,19 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
* be turned off.
*/
public void setLenient(boolean lenient) {
- this.lenient = lenient;
- markAsDirty();
+ getState().lenient = lenient;
}
/**
- * Returns whether date/time interpretation is to be lenient.
+ * Returns whether date/time interpretation is lenient.
*
* @see #setLenient(boolean)
*
- * @return true if the interpretation mode of this calendar is lenient;
- * false otherwise.
+ * @return {@code true} if the interpretation mode of this calendar is
+ * lenient; {@code false} otherwise.
*/
public boolean isLenient() {
- return lenient;
+ return getState(false).lenient;
}
@Override
@@ -549,6 +514,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
*/
public void setDefaultValue(T defaultValue) {
this.defaultValue = defaultValue;
+ updateResolutions();
}
/**
@@ -566,7 +532,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
* user). No value changes should happen, but we need to do some
* internal housekeeping.
*/
- if (value == null && !uiHasValidDateString) {
+ if (value == null && !getState(false).parsable) {
/*
* Side-effects of doSetValue clears possible previous strings and
* flags about invalid input.
@@ -585,7 +551,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
* @return true if week numbers are shown, false otherwise.
*/
public boolean isShowISOWeekNumbers() {
- return showISOWeekNumbers;
+ return getState(false).showISOWeekNumbers;
}
/**
@@ -597,8 +563,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
* true if week numbers should be shown, false otherwise.
*/
public void setShowISOWeekNumbers(boolean showWeekNumbers) {
- showISOWeekNumbers = showWeekNumbers;
- markAsDirty();
+ getState().showISOWeekNumbers = showWeekNumbers;
}
/**
@@ -745,6 +710,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
} else {
setComponentError(new UserError(currentParseErrorMessage));
}
+ updateResolutions();
}
/**
@@ -800,7 +766,7 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster &
protected abstract Date convertToDate(T date);
private String getResolutionVariable(R resolution) {
- return resolution.name().toLowerCase(Locale.ENGLISH);
+ return resolution.name();
}
@SuppressWarnings("unchecked")
diff --git a/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java
index cab1addf58..4edc2a30df 100644
--- a/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/component/datefield/DateFieldListenersTest.java
@@ -1,8 +1,6 @@
package com.vaadin.tests.server.component.datefield;
-import java.io.Serializable;
-import java.time.temporal.Temporal;
-import java.time.temporal.TemporalAdjuster;
+import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;
@@ -13,43 +11,45 @@ import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.FieldEvents.FocusEvent;
import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase;
import com.vaadin.ui.AbstractDateField;
public class DateFieldListenersTest extends AbstractListenerMethodsTestBase {
- public static class TestDateField<T extends Temporal & TemporalAdjuster & Serializable & Comparable<? super T>, R extends Enum<R>>
- extends AbstractDateField<T, R> {
+ public static class TestDateField
+ extends AbstractDateField<LocalDateTime, DateTimeResolution> {
public TestDateField() {
- super(null);
+ super(DateTimeResolution.DAY);
}
@Override
- protected int getDatePart(T date, R resolution) {
+ protected int getDatePart(LocalDateTime date,
+ DateTimeResolution resolution) {
return 0;
}
@Override
- protected T buildDate(Map<R, Integer> resolutionValues) {
+ protected LocalDateTime buildDate(
+ Map<DateTimeResolution, Integer> resolutionValues) {
return null;
}
@Override
- protected RangeValidator<T> getRangeValidator() {
+ protected RangeValidator<LocalDateTime> getRangeValidator() {
return null;
}
@Override
- protected T convertFromDate(Date date) {
+ protected LocalDateTime convertFromDate(Date date) {
return null;
}
@Override
- protected Date convertToDate(T date) {
+ protected Date convertToDate(LocalDateTime date) {
return null;
}
-
}
@Test
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldServerRpc.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldServerRpc.java
new file mode 100644
index 0000000000..2ef8993fb6
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldServerRpc.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+import com.vaadin.shared.communication.ServerRpc;
+
+/**
+ * RPC interface for calls from client to server.
+ *
+ * @since
+ */
+public interface AbstractDateFieldServerRpc extends ServerRpc {
+
+ /**
+ * Updates the typed data string and resolution names and values.
+ *
+ * @param newDateString
+ * the value of the text field part. It enables analyzing invalid
+ * input on the server. {@code null} if the date was chosen with
+ * popup calendar or contains user-typed string
+ * @param invalidDateString
+ * Whether the last date string is invalid or not
+ * @param resolutions
+ * map of time unit (resolution) name and value, name is the
+ * lower-case resolution name e.g. "hour", "minute", and value
+ * can be {@code null}
+ */
+ void update(String newDateString, boolean invalidDateString,
+ Map<String, Integer> resolutions);
+
+ /**
+ * Indicates to the server that the client-side has lost focus.
+ */
+ void blur();
+
+ /**
+ * Indicates to the server that the client-side has acquired focus.
+ */
+ void focus();
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldState.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldState.java
index 5bd920389e..cd1791464c 100644
--- a/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldState.java
+++ b/shared/src/main/java/com/vaadin/shared/ui/datefield/AbstractDateFieldState.java
@@ -16,6 +16,8 @@
package com.vaadin.shared.ui.datefield;
import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
import com.vaadin.shared.AbstractFieldState;
import com.vaadin.shared.annotations.NoLayout;
@@ -54,4 +56,54 @@ public class AbstractDateFieldState extends AbstractFieldState {
* @since 8.2
*/
public String timeZoneJSON;
+
+ /**
+ * The used Locale, can be {@code null}.
+ *
+ * @since
+ */
+ public String locale;
+
+ /**
+ * Overridden date format string, can be {@code null} if default formatting
+ * of the components locale is used.
+ *
+ * @since
+ */
+ public String format;
+
+ /**
+ * Whether the date/time interpretation is lenient.
+ *
+ * @since
+ */
+ public boolean lenient;
+
+ /**
+ * The map of {@code Resolution}s which are currently used by the component.
+ *
+ * The key is the resolution name e.g. "HOUR", "MINUTE", with possibly
+ * prefixed by "default-".
+ *
+ * The value can be {@code null}
+ *
+ * @since
+ */
+ public Map<String, Integer> resolutions = new HashMap<>();
+
+ /**
+ * Determines if week numbers are shown in the date selector.
+ *
+ * @since
+ */
+ public boolean showISOWeekNumbers;
+
+ /**
+ * Was the last entered string parsable? If this flag is false, datefields
+ * internal validator does not pass.
+ *
+ * @since
+ */
+ public boolean parsable = true;
+
}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/datefield/DateFieldConstants.java b/shared/src/main/java/com/vaadin/shared/ui/datefield/DateFieldConstants.java
deleted file mode 100644
index b9cc88d708..0000000000
--- a/shared/src/main/java/com/vaadin/shared/ui/datefield/DateFieldConstants.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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;
-
-import java.io.Serializable;
-
-@Deprecated
-public class DateFieldConstants implements Serializable {
-
- @Deprecated
- public static final String ATTR_WEEK_NUMBERS = "wn";
-
-}