From 2f5e484a12f25d10ac6034d8ee9176b553b96c2d Mon Sep 17 00:00:00 2001 From: Artur Date: Mon, 12 Jun 2017 16:44:05 +0300 Subject: Add methods for setting the date as an ISO value for date fields --- .../com/vaadin/client/ui/VAbstractTextualDate.java | 125 ++++++++++++++++++--- .../main/java/com/vaadin/client/ui/VDateField.java | 31 +++-- .../com/vaadin/client/ui/VDateFieldCalendar.java | 7 +- .../vaadin/client/ui/VDateTimeFieldCalendar.java | 7 +- .../java/com/vaadin/client/ui/VPopupCalendar.java | 7 +- .../com/vaadin/client/ui/VPopupTimeCalendar.java | 72 ++++++------ .../ui/datefield/AbstractTextualDateConnector.java | 4 +- 7 files changed, 184 insertions(+), 69 deletions(-) (limited to 'client/src/main') 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 2db5cb5bc5..0c33eb7e41 100644 --- a/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java +++ b/client/src/main/java/com/vaadin/client/ui/VAbstractTextualDate.java @@ -19,12 +19,14 @@ package com.vaadin.client.ui; import java.util.Date; import com.google.gwt.aria.client.Roles; +import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.DomEvent; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; +import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.ui.TextBox; import com.vaadin.client.BrowserInfo; import com.vaadin.client.Focusable; @@ -54,6 +56,8 @@ public abstract class VAbstractTextualDate> HandlesAriaRequired, KeyDownHandler { private static final String PARSE_ERROR_CLASSNAME = "-parseerror"; + private static final String ISO_DATE_TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss"; + private static final String ISO_DATE_PATTERN = "yyyy-MM-dd"; /** For internal use only. May be removed or replaced in the future. */ public final TextBox text; @@ -64,7 +68,7 @@ public abstract class VAbstractTextualDate> private final String TEXTFIELD_ID = "field"; /** For internal use only. May be removed or replaced in the future. */ - public String formatStr; + private String formatStr; public VAbstractTextualDate(R resoluton) { super(resoluton); @@ -78,6 +82,7 @@ public abstract class VAbstractTextualDate> addDomHandler(this, KeyDownEvent.getType()); } add(text); + publishJSHelpers(getElement()); } /** @@ -97,26 +102,46 @@ public abstract class VAbstractTextualDate> */ protected String getFormatString() { if (formatStr == null) { - if (isYear(getCurrentResolution())) { - formatStr = "yyyy"; // force full year - } else { - - try { - String frmString = LocaleService - .getDateFormat(currentLocale); - frmString = cleanFormat(frmString); - - formatStr = frmString; - } catch (LocaleNotLoadedException e) { - // TODO should die instead? Can the component survive - // without format string? - VConsole.error(e); - } - } + setFormatString(createFormatString()); } return formatStr; } + /** + * Create a format string suitable for the widget in its current state. + * + * @return a date format string to use when formatting and parsing the text + * in the input field + * @since + */ + protected String createFormatString() { + if (isYear(getCurrentResolution())) { + return "yyyy"; // force full year + } else { + try { + String frmString = LocaleService.getDateFormat(currentLocale); + return cleanFormat(frmString); + } catch (LocaleNotLoadedException e) { + // TODO should die instead? Can the component survive + // without format string? + VConsole.error(e); + return null; + } + } + } + + /** + * 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 + * @since + */ + public void setFormatString(String formatString) { + this.formatStr = formatString; + } + @Override public void bindAriaCaption( com.google.gwt.user.client.Element captionElement) { @@ -148,9 +173,11 @@ public abstract class VAbstractTextualDate> // Create the initial text for the textfield String dateText; Date currentDate = getDate(); + // Always call this to ensure the format ends up in the element + String formatString = getFormatString(); if (currentDate != null) { dateText = getDateTimeService().formatDate(currentDate, - getFormatString()); + formatString); } else { dateText = ""; } @@ -355,4 +382,66 @@ public abstract class VAbstractTextualDate> // Needed for tooltip event handling fireEvent(event); } + + /** + * Publish methods/properties on the element to be used from JavaScript. + * + * @since + */ + private native void publishJSHelpers(Element root) + /*-{ + var self = this; + root.setISOValue = $entry(function (value) { + self.@VAbstractTextualDate::setISODate(*)(value); + }); + root.getISOValue = $entry(function () { + return self.@VAbstractTextualDate::getISODate()(); + }); + }-*/; + + /** + * Sets the value of the date field as a locale independent ISO date + * (yyyy-MM-dd'T'HH:mm:ss or yyyy-MM-dd depending on whether this is a date + * field or a date and time field). + * + * @param isoDate + * the date to set in ISO8601 format, or null to clear the date + * value + * @since + */ + public void setISODate(String isoDate) { + if (isoDate == null) { + setDate(null); + } else { + Date date = getIsoFormatter().parse(isoDate); + setDate(date); + } + updateDateVariables(); + } + + /** + * Gets the value of the date field as a locale independent ISO date + * (yyyy-MM-dd'T'HH:mm:ss or yyyy-MM-dd depending on whether this is a date + * field or a date and time field). + * + * @return the current date in ISO8601 format, or null if no date is set + * + * @since + */ + public String getISODate() { + Date date = getDate(); + if (date == null) { + return null; + } else { + return getIsoFormatter().format(date); + } + } + + private DateTimeFormat getIsoFormatter() { + if (supportsTime()) { + return DateTimeFormat.getFormat(ISO_DATE_TIME_PATTERN); + } else { + return DateTimeFormat.getFormat(ISO_DATE_PATTERN); + } + } } 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 25529fb583..bf4c074d89 100644 --- a/client/src/main/java/com/vaadin/client/ui/VDateField.java +++ b/client/src/main/java/com/vaadin/client/ui/VDateField.java @@ -28,7 +28,7 @@ import com.vaadin.client.DateTimeService; /** * A very base widget class for a date field. - * + * * @author Vaadin Ltd * * @param @@ -100,7 +100,7 @@ public abstract class VDateField> extends FlowPanel * The map contains integer representation of values per resolution. The * method should construct a date based on the map and set it via * {@link #setCurrentDate(Date)} - * + * * @param dateValues * a map with date values to convert into a date */ @@ -183,7 +183,7 @@ public abstract class VDateField> extends FlowPanel /** * Returns a resolution variable name for the given {@code resolution}. - * + * * @param resolution * the given resolution * @return the resolution variable name @@ -198,9 +198,9 @@ public abstract class VDateField> extends FlowPanel *

* The method uses {@link #doGetResolutions()} to make sure that the order * is the correct one. - * + * * @see #doGetResolutions() - * + * * @return stream of all available resolutions in the ascending order. */ public Stream getResolutions() { @@ -211,25 +211,34 @@ public abstract class VDateField> extends FlowPanel * Returns a current resolution as a string. *

* The method is used to generate a style name for the current resolution. - * + * * @return the current resolution as a string */ public abstract String resolutionAsString(); /** * Checks whether the given {@code resolution} represents an year. - * + * * @param resolution * the given resolution * @return {@code true} if the {@code resolution} represents an year */ public abstract boolean isYear(R resolution); + /** + * Checks whether time is supported by this widget. + * + * @return true if time is supported in addition to date, + * false if only dates are supported + * @since + */ + protected abstract boolean supportsTime(); + /** * Returns a date based on the provided date values map. - * + * * @see #setCurrentDate(Map) - * + * * @param dateValues * a map with date values to convert into a date * @return the date based on the dateValues map @@ -240,9 +249,9 @@ public abstract class VDateField> extends FlowPanel * Returns all available resolutions as an array. *

* No any order is required (in contrary to {@link #getResolutions()}. - * + * * @see #getResolutions() - * + * * @return all available resolutions */ protected abstract R[] doGetResolutions(); 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 ec0f71c72d..ada512c8b1 100644 --- a/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java +++ b/client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java @@ -23,7 +23,7 @@ import com.vaadin.shared.ui.datefield.DateResolution; /** * A client side implementation for InlineDateField. - * + * * @author Vaadin Ltd * */ @@ -98,4 +98,9 @@ public class VDateFieldCalendar return VPopupCalendar.makeDate(dateVaules); } + @Override + protected boolean supportsTime() { + return false; + } + } 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 53becf60d6..3d2b13becb 100644 --- a/client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java +++ b/client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java @@ -23,7 +23,7 @@ import com.vaadin.shared.ui.datefield.DateTimeResolution; /** * A client side implementation for inline date/time field. - * + * * @author Vaadin Ltd * @since 8.0 * @@ -110,4 +110,9 @@ public class VDateTimeFieldCalendar extends return DateTimeResolution.values(); } + @Override + protected boolean supportsTime() { + return true; + } + } 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 b05224f07e..9237014423 100644 --- a/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java +++ b/client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java @@ -24,7 +24,7 @@ import com.vaadin.shared.ui.datefield.DateResolution; /** * Represents a date selection component with a text field and a popup date * selector. - * + * * @author Vaadin Ltd * */ @@ -114,4 +114,9 @@ public class VPopupCalendar return super.cleanFormat(format); } + @Override + protected boolean supportsTime() { + return false; + } + } 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 af56e1101d..2805a4e7a6 100644 --- a/client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java +++ b/client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java @@ -27,7 +27,7 @@ import com.vaadin.shared.ui.datefield.DateTimeResolution; /** * Represents a date-time selection component with a text field and a popup date * selector. - * + * * @author Vaadin Ltd * * @since 8.0 @@ -169,48 +169,45 @@ public class VPopupTimeCalendar extends } @Override - protected String getFormatString() { - if (formatStr == null) { - if (isYear(getCurrentResolution())) { - formatStr = "yyyy"; // force full year - } else { - - try { - String frmString = LocaleService - .getDateFormat(currentLocale); - frmString = cleanFormat(frmString); - // String delim = LocaleService - // .getClockDelimiter(currentLocale); + protected String createFormatString() { + if (isYear(getCurrentResolution())) { + return "yyyy"; // force full year + } else { + + try { + String frmString = LocaleService.getDateFormat(currentLocale); + frmString = cleanFormat(frmString); + // String delim = LocaleService + // .getClockDelimiter(currentLocale); + if (getCurrentResolution() + .compareTo(DateTimeResolution.HOUR) <= 0) { + if (dts.isTwelveHourClock()) { + frmString += " hh"; + } else { + frmString += " HH"; + } if (getCurrentResolution() - .compareTo(DateTimeResolution.HOUR) <= 0) { - if (dts.isTwelveHourClock()) { - frmString += " hh"; - } else { - frmString += " HH"; - } + .compareTo(DateTimeResolution.MINUTE) <= 0) { + frmString += ":mm"; if (getCurrentResolution() - .compareTo(DateTimeResolution.MINUTE) <= 0) { - frmString += ":mm"; - if (getCurrentResolution().compareTo( - DateTimeResolution.SECOND) <= 0) { - frmString += ":ss"; - } - } - if (dts.isTwelveHourClock()) { - frmString += " aaa"; + .compareTo(DateTimeResolution.SECOND) <= 0) { + frmString += ":ss"; } - + } + if (dts.isTwelveHourClock()) { + frmString += " aaa"; } - formatStr = frmString; - } catch (LocaleNotLoadedException e) { - // TODO should die instead? Can the component survive - // without format string? - VConsole.error(e); } + + return frmString; + } catch (LocaleNotLoadedException e) { + // TODO should die instead? Can the component survive + // without format string? + VConsole.error(e); + return null; } } - return formatStr; } @Override @@ -225,4 +222,9 @@ public class VPopupTimeCalendar extends return super.cleanFormat(format); } + @Override + protected boolean supportsTime() { + return true; + } + } 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 87b8d047f9..fb3351ea4f 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 @@ -41,10 +41,10 @@ public abstract class AbstractTextualDateConnector> if (origRes != getWidget().getCurrentResolution() || oldLocale != getWidget().getCurrentLocale()) { // force recreating format string - getWidget().formatStr = null; + getWidget().setFormatString(null); } if (uidl.hasAttribute("format")) { - getWidget().formatStr = uidl.getStringAttribute("format"); + getWidget().setFormatString(uidl.getStringAttribute("format")); } getWidget().lenient = !uidl.getBooleanAttribute("strict"); -- cgit v1.2.3