]> source.dussan.org Git - vaadin-framework.git/commitdiff
fixes #3175, now non-lenient by default, can be changed via setLenient()
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Wed, 4 Nov 2009 12:45:38 +0000 (12:45 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Wed, 4 Nov 2009 12:45:38 +0000 (12:45 +0000)
svn changeset:9624/svn branch:6.2

src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java
src/com/vaadin/ui/DateField.java
tests/src/com/vaadin/tests/components/datefield/LenientMode.java [new file with mode: 0644]

index af0489088181fa496c18649bc5844a0fa975d875..ea91c5eac1fd4e3b7f6587b5f6bdc8698a245115 100644 (file)
-/* \r
-@ITMillApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.terminal.gwt.client.ui;\r
-\r
-import java.util.Date;\r
-\r
-import com.google.gwt.event.dom.client.BlurEvent;\r
-import com.google.gwt.event.dom.client.BlurHandler;\r
-import com.google.gwt.event.dom.client.ChangeEvent;\r
-import com.google.gwt.event.dom.client.ChangeHandler;\r
-import com.google.gwt.event.dom.client.FocusEvent;\r
-import com.google.gwt.event.dom.client.FocusHandler;\r
-import com.google.gwt.i18n.client.DateTimeFormat;\r
-import com.google.gwt.user.client.DOM;\r
-import com.google.gwt.user.client.ui.TextBox;\r
-import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
-import com.vaadin.terminal.gwt.client.BrowserInfo;\r
-import com.vaadin.terminal.gwt.client.ClientExceptionHandler;\r
-import com.vaadin.terminal.gwt.client.ContainerResizedListener;\r
-import com.vaadin.terminal.gwt.client.Focusable;\r
-import com.vaadin.terminal.gwt.client.LocaleNotLoadedException;\r
-import com.vaadin.terminal.gwt.client.LocaleService;\r
-import com.vaadin.terminal.gwt.client.Paintable;\r
-import com.vaadin.terminal.gwt.client.UIDL;\r
-\r
-public class VTextualDate extends VDateField implements Paintable, Field,\r
-        ChangeHandler, ContainerResizedListener, Focusable {\r
-\r
-    private static final String PARSE_ERROR_CLASSNAME = CLASSNAME\r
-            + "-parseerror";\r
-\r
-    private final TextBox text;\r
-\r
-    private String formatStr;\r
-\r
-    private String width;\r
-\r
-    private boolean needLayout;\r
-\r
-    protected int fieldExtraWidth = -1;\r
-\r
-    public VTextualDate() {\r
-        super();\r
-        text = new TextBox();\r
-        // use normal textfield styles as a basis\r
-        text.setStyleName(VTextField.CLASSNAME);\r
-        // add datefield spesific style name also\r
-        text.addStyleName(CLASSNAME + "-textfield");\r
-        text.addChangeHandler(this);\r
-        text.addFocusHandler(new FocusHandler() {\r
-            public void onFocus(FocusEvent event) {\r
-                text.addStyleName(VTextField.CLASSNAME + "-"\r
-                        + VTextField.CLASSNAME_FOCUS);\r
-            }\r
-        });\r
-        text.addBlurHandler(new BlurHandler() {\r
-            public void onBlur(BlurEvent event) {\r
-                text.removeStyleName(VTextField.CLASSNAME + "-"\r
-                        + VTextField.CLASSNAME_FOCUS);\r
-            }\r
-        });\r
-        add(text);\r
-    }\r
-\r
-    @Override\r
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
-\r
-        int origRes = currentResolution;\r
-        super.updateFromUIDL(uidl, client);\r
-        if (origRes != currentResolution) {\r
-            // force recreating format string\r
-            formatStr = null;\r
-        }\r
-        if (uidl.hasAttribute("format")) {\r
-            formatStr = uidl.getStringAttribute("format");\r
-        }\r
-\r
-        buildDate();\r
-        // not a FocusWidget -> needs own tabindex handling\r
-        if (uidl.hasAttribute("tabindex")) {\r
-            text.setTabIndex(uidl.getIntAttribute("tabindex"));\r
-        }\r
-\r
-        if (readonly) {\r
-            text.addStyleDependentName("readonly");\r
-        } else {\r
-            text.removeStyleDependentName("readonly");\r
-        }\r
-    }\r
-\r
-    protected String getFormatString() {\r
-        if (formatStr == null) {\r
-            if (currentResolution == RESOLUTION_YEAR) {\r
-                formatStr = "yyyy"; // force full year\r
-            } else {\r
-\r
-                try {\r
-                    String frmString = LocaleService\r
-                            .getDateFormat(currentLocale);\r
-                    frmString = cleanFormat(frmString);\r
-                    String delim = LocaleService\r
-                            .getClockDelimiter(currentLocale);\r
-\r
-                    if (currentResolution >= RESOLUTION_HOUR) {\r
-                        if (dts.isTwelveHourClock()) {\r
-                            frmString += " hh";\r
-                        } else {\r
-                            frmString += " HH";\r
-                        }\r
-                        if (currentResolution >= RESOLUTION_MIN) {\r
-                            frmString += ":mm";\r
-                            if (currentResolution >= RESOLUTION_SEC) {\r
-                                frmString += ":ss";\r
-                                if (currentResolution >= RESOLUTION_MSEC) {\r
-                                    frmString += ".SSS";\r
-                                }\r
-                            }\r
-                        }\r
-                        if (dts.isTwelveHourClock()) {\r
-                            frmString += " aaa";\r
-                        }\r
-\r
-                    }\r
-\r
-                    formatStr = frmString;\r
-                } catch (LocaleNotLoadedException e) {\r
-                    ClientExceptionHandler.displayError(e);\r
-                }\r
-            }\r
-        }\r
-        return formatStr;\r
-    }\r
-\r
-    /**\r
-     * \r
-     */\r
-    protected void buildDate() {\r
-        removeStyleName(PARSE_ERROR_CLASSNAME);\r
-        // Create the initial text for the textfield\r
-        String dateText;\r
-        if (date != null) {\r
-            dateText = DateTimeFormat.getFormat(getFormatString()).format(date);\r
-        } else {\r
-            dateText = "";\r
-        }\r
-\r
-        text.setText(dateText);\r
-        text.setEnabled(enabled);\r
-        text.setReadOnly(readonly);\r
-\r
-        if (readonly) {\r
-            text.addStyleName("v-readonly");\r
-        } else {\r
-            text.removeStyleName("v-readonly");\r
-        }\r
-\r
-    }\r
-\r
-    public void onChange(ChangeEvent event) {\r
-        if (!text.getText().equals("")) {\r
-            try {\r
-                DateTimeFormat format = DateTimeFormat\r
-                        .getFormat(getFormatString());\r
-                date = format.parse(text.getText());\r
-                long stamp = date.getTime();\r
-                if (stamp == 0) {\r
-                    // If date parsing fails in firefox the stamp will be 0\r
-                    date = null;\r
-                    addStyleName(PARSE_ERROR_CLASSNAME);\r
-                } else {\r
-                    // remove possibly added invalid value indication\r
-                    removeStyleName(PARSE_ERROR_CLASSNAME);\r
-                }\r
-            } catch (final Exception e) {\r
-                ClientExceptionHandler.displayError(e.getMessage());\r
-\r
-                addStyleName(PARSE_ERROR_CLASSNAME);\r
-                // this is a hack that may eventually be removed\r
-                client.updateVariable(id, "lastInvalidDateString", text\r
-                        .getText(), false);\r
-                date = null;\r
-            }\r
-        } else {\r
-            date = null;\r
-            // remove possibly added invalid value indication\r
-            removeStyleName(PARSE_ERROR_CLASSNAME);\r
-        }\r
-        // always send the date string\r
-        client.updateVariable(id, "dateString", text.getText(), false);\r
-\r
-        if (date != null) {\r
-            showingDate = new Date(date.getTime());\r
-        }\r
-\r
-        // Update variables\r
-        // (only the smallest defining resolution needs to be\r
-        // immediate)\r
-        client.updateVariable(id, "year", date != null ? date.getYear() + 1900\r
-                : -1, currentResolution == VDateField.RESOLUTION_YEAR\r
-                && immediate);\r
-        if (currentResolution >= VDateField.RESOLUTION_MONTH) {\r
-            client.updateVariable(id, "month",\r
-                    date != null ? date.getMonth() + 1 : -1,\r
-                    currentResolution == VDateField.RESOLUTION_MONTH\r
-                            && immediate);\r
-        }\r
-        if (currentResolution >= VDateField.RESOLUTION_DAY) {\r
-            client\r
-                    .updateVariable(id, "day", date != null ? date.getDate()\r
-                            : -1,\r
-                            currentResolution == VDateField.RESOLUTION_DAY\r
-                                    && immediate);\r
-        }\r
-        if (currentResolution >= VDateField.RESOLUTION_HOUR) {\r
-            client.updateVariable(id, "hour", date != null ? date.getHours()\r
-                    : -1, currentResolution == VDateField.RESOLUTION_HOUR\r
-                    && immediate);\r
-        }\r
-        if (currentResolution >= VDateField.RESOLUTION_MIN) {\r
-            client.updateVariable(id, "min", date != null ? date.getMinutes()\r
-                    : -1, currentResolution == VDateField.RESOLUTION_MIN\r
-                    && immediate);\r
-        }\r
-        if (currentResolution >= VDateField.RESOLUTION_SEC) {\r
-            client.updateVariable(id, "sec", date != null ? date.getSeconds()\r
-                    : -1, currentResolution == VDateField.RESOLUTION_SEC\r
-                    && immediate);\r
-        }\r
-        if (currentResolution == VDateField.RESOLUTION_MSEC) {\r
-            client.updateVariable(id, "msec", date != null ? getMilliseconds()\r
-                    : -1, immediate);\r
-        }\r
-\r
-    }\r
-\r
-    private String cleanFormat(String format) {\r
-        // Remove unnecessary d & M if resolution is too low\r
-        if (currentResolution < VDateField.RESOLUTION_DAY) {\r
-            format = format.replaceAll("d", "");\r
-        }\r
-        if (currentResolution < VDateField.RESOLUTION_MONTH) {\r
-            format = format.replaceAll("M", "");\r
-        }\r
-\r
-        // Remove unsupported patterns\r
-        // TODO support for 'G', era designator (used at least in Japan)\r
-        format = format.replaceAll("[GzZwWkK]", "");\r
-\r
-        // Remove extra delimiters ('/' and '.')\r
-        while (format.startsWith("/") || format.startsWith(".")\r
-                || format.startsWith("-")) {\r
-            format = format.substring(1);\r
-        }\r
-        while (format.endsWith("/") || format.endsWith(".")\r
-                || format.endsWith("-")) {\r
-            format = format.substring(0, format.length() - 1);\r
-        }\r
-\r
-        // Remove duplicate delimiters\r
-        format = format.replaceAll("//", "/");\r
-        format = format.replaceAll("\\.\\.", ".");\r
-        format = format.replaceAll("--", "-");\r
-\r
-        return format.trim();\r
-    }\r
-\r
-    @Override\r
-    public void setWidth(String newWidth) {\r
-        if (!"".equals(newWidth) && (width == null || !newWidth.equals(width))) {\r
-            if (BrowserInfo.get().isIE6()) {\r
-                // in IE6 cols ~ min-width\r
-                DOM.setElementProperty(text.getElement(), "size", "1");\r
-            }\r
-            needLayout = true;\r
-            width = newWidth;\r
-            super.setWidth(width);\r
-            iLayout();\r
-            if (newWidth.indexOf("%") < 0) {\r
-                needLayout = false;\r
-            }\r
-        } else {\r
-            if ("".equals(newWidth) && width != null && !"".equals(width)) {\r
-                if (BrowserInfo.get().isIE6()) {\r
-                    // revert IE6 hack\r
-                    DOM.setElementProperty(text.getElement(), "size", "");\r
-                }\r
-                super.setWidth("");\r
-                needLayout = true;\r
-                iLayout();\r
-                needLayout = false;\r
-                width = null;\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Returns pixels in x-axis reserved for other than textfield content.\r
-     * \r
-     * @return extra width in pixels\r
-     */\r
-    protected int getFieldExtraWidth() {\r
-        if (fieldExtraWidth < 0) {\r
-            text.setWidth("0");\r
-            fieldExtraWidth = text.getOffsetWidth();\r
-            if (BrowserInfo.get().isFF3()) {\r
-                // Firefox somehow always leaves the INPUT element 2px wide\r
-                fieldExtraWidth -= 2;\r
-            }\r
-        }\r
-        return fieldExtraWidth;\r
-    }\r
-\r
-    public void updateWidth() {\r
-        needLayout = true;\r
-        fieldExtraWidth = -1;\r
-        iLayout();\r
-    }\r
-\r
-    public void iLayout() {\r
-        if (needLayout) {\r
-            text.setWidth((getOffsetWidth() - getFieldExtraWidth()) + "px");\r
-        }\r
-    }\r
-\r
-    public void focus() {\r
-        text.setFocus(true);\r
-    }\r
-}\r
+/* 
+@ITMillApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Date;
+
+import com.google.gwt.event.dom.client.BlurEvent;
+import com.google.gwt.event.dom.client.BlurHandler;
+import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.event.dom.client.ChangeHandler;
+import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.TextBox;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.ClientExceptionHandler;
+import com.vaadin.terminal.gwt.client.ContainerResizedListener;
+import com.vaadin.terminal.gwt.client.Focusable;
+import com.vaadin.terminal.gwt.client.LocaleNotLoadedException;
+import com.vaadin.terminal.gwt.client.LocaleService;
+import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VTextualDate extends VDateField implements Paintable, Field,
+        ChangeHandler, ContainerResizedListener, Focusable {
+
+    private static final String PARSE_ERROR_CLASSNAME = CLASSNAME
+            + "-parseerror";
+
+    private final TextBox text;
+
+    private String formatStr;
+
+    private String width;
+
+    private boolean needLayout;
+
+    protected int fieldExtraWidth = -1;
+
+    private boolean lenient;
+
+    public VTextualDate() {
+
+        super();
+        text = new TextBox();
+        // use normal textfield styles as a basis
+        text.setStyleName(VTextField.CLASSNAME);
+        // add datefield spesific style name also
+        text.addStyleName(CLASSNAME + "-textfield");
+        text.addChangeHandler(this);
+        text.addFocusHandler(new FocusHandler() {
+            public void onFocus(FocusEvent event) {
+                text.addStyleName(VTextField.CLASSNAME + "-"
+                        + VTextField.CLASSNAME_FOCUS);
+            }
+        });
+        text.addBlurHandler(new BlurHandler() {
+            public void onBlur(BlurEvent event) {
+                text.removeStyleName(VTextField.CLASSNAME + "-"
+                        + VTextField.CLASSNAME_FOCUS);
+            }
+        });
+        add(text);
+    }
+
+    @Override
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+
+        int origRes = currentResolution;
+        super.updateFromUIDL(uidl, client);
+        if (origRes != currentResolution) {
+            // force recreating format string
+            formatStr = null;
+        }
+        if (uidl.hasAttribute("format")) {
+            formatStr = uidl.getStringAttribute("format");
+        }
+
+        lenient = !uidl.getBooleanAttribute("strict");
+
+        buildDate();
+        // not a FocusWidget -> needs own tabindex handling
+        if (uidl.hasAttribute("tabindex")) {
+            text.setTabIndex(uidl.getIntAttribute("tabindex"));
+        }
+
+        if (readonly) {
+            text.addStyleDependentName("readonly");
+        } else {
+            text.removeStyleDependentName("readonly");
+        }
+    }
+
+    protected String getFormatString() {
+        if (formatStr == null) {
+            if (currentResolution == RESOLUTION_YEAR) {
+                formatStr = "yyyy"; // force full year
+            } else {
+
+                try {
+                    String frmString = LocaleService
+                            .getDateFormat(currentLocale);
+                    frmString = cleanFormat(frmString);
+                    String delim = LocaleService
+                            .getClockDelimiter(currentLocale);
+
+                    if (currentResolution >= RESOLUTION_HOUR) {
+                        if (dts.isTwelveHourClock()) {
+                            frmString += " hh";
+                        } else {
+                            frmString += " HH";
+                        }
+                        if (currentResolution >= RESOLUTION_MIN) {
+                            frmString += ":mm";
+                            if (currentResolution >= RESOLUTION_SEC) {
+                                frmString += ":ss";
+                                if (currentResolution >= RESOLUTION_MSEC) {
+                                    frmString += ".SSS";
+                                }
+                            }
+                        }
+                        if (dts.isTwelveHourClock()) {
+                            frmString += " aaa";
+                        }
+
+                    }
+
+                    formatStr = frmString;
+                } catch (LocaleNotLoadedException e) {
+                    ClientExceptionHandler.displayError(e);
+                }
+            }
+        }
+        return formatStr;
+    }
+
+    /**
+     * 
+     */
+    protected void buildDate() {
+        removeStyleName(PARSE_ERROR_CLASSNAME);
+        // Create the initial text for the textfield
+        String dateText;
+        if (date != null) {
+            dateText = DateTimeFormat.getFormat(getFormatString()).format(date);
+        } else {
+            dateText = "";
+        }
+
+        text.setText(dateText);
+        text.setEnabled(enabled);
+        text.setReadOnly(readonly);
+
+        if (readonly) {
+            text.addStyleName("v-readonly");
+        } else {
+            text.removeStyleName("v-readonly");
+        }
+
+    }
+
+    public void onChange(ChangeEvent event) {
+        if (!text.getText().equals("")) {
+            try {
+                DateTimeFormat format = DateTimeFormat
+                        .getFormat(getFormatString());
+                if (lenient) {
+                    date = format.parse(text.getText());
+                    if (date != null) {
+                        // if date value was leniently parsed, normalize text
+                        // presentation
+                        text.setValue(DateTimeFormat.getFormat(
+                                getFormatString()).format(date), false);
+                    }
+                } else {
+                    date = format.parseStrict(text.getText());
+                }
+
+                long stamp = date.getTime();
+                if (stamp == 0) {
+                    // If date parsing fails in firefox the stamp will be 0
+                    date = null;
+                    addStyleName(PARSE_ERROR_CLASSNAME);
+                } else {
+                    // remove possibly added invalid value indication
+                    removeStyleName(PARSE_ERROR_CLASSNAME);
+                }
+            } catch (final Exception e) {
+                ClientExceptionHandler.displayError(e.getMessage());
+
+                addStyleName(PARSE_ERROR_CLASSNAME);
+                // this is a hack that may eventually be removed
+                client.updateVariable(id, "lastInvalidDateString", text
+                        .getText(), false);
+                date = null;
+            }
+        } else {
+            date = null;
+            // remove possibly added invalid value indication
+            removeStyleName(PARSE_ERROR_CLASSNAME);
+        }
+        // always send the date string
+        client.updateVariable(id, "dateString", text.getText(), false);
+
+        if (date != null) {
+            showingDate = new Date(date.getTime());
+        }
+
+        // Update variables
+        // (only the smallest defining resolution needs to be
+        // immediate)
+        client.updateVariable(id, "year", date != null ? date.getYear() + 1900
+                : -1, currentResolution == VDateField.RESOLUTION_YEAR
+                && immediate);
+        if (currentResolution >= VDateField.RESOLUTION_MONTH) {
+            client.updateVariable(id, "month",
+                    date != null ? date.getMonth() + 1 : -1,
+                    currentResolution == VDateField.RESOLUTION_MONTH
+                            && immediate);
+        }
+        if (currentResolution >= VDateField.RESOLUTION_DAY) {
+            client
+                    .updateVariable(id, "day", date != null ? date.getDate()
+                            : -1,
+                            currentResolution == VDateField.RESOLUTION_DAY
+                                    && immediate);
+        }
+        if (currentResolution >= VDateField.RESOLUTION_HOUR) {
+            client.updateVariable(id, "hour", date != null ? date.getHours()
+                    : -1, currentResolution == VDateField.RESOLUTION_HOUR
+                    && immediate);
+        }
+        if (currentResolution >= VDateField.RESOLUTION_MIN) {
+            client.updateVariable(id, "min", date != null ? date.getMinutes()
+                    : -1, currentResolution == VDateField.RESOLUTION_MIN
+                    && immediate);
+        }
+        if (currentResolution >= VDateField.RESOLUTION_SEC) {
+            client.updateVariable(id, "sec", date != null ? date.getSeconds()
+                    : -1, currentResolution == VDateField.RESOLUTION_SEC
+                    && immediate);
+        }
+        if (currentResolution == VDateField.RESOLUTION_MSEC) {
+            client.updateVariable(id, "msec", date != null ? getMilliseconds()
+                    : -1, immediate);
+        }
+
+    }
+
+    private String cleanFormat(String format) {
+        // Remove unnecessary d & M if resolution is too low
+        if (currentResolution < VDateField.RESOLUTION_DAY) {
+            format = format.replaceAll("d", "");
+        }
+        if (currentResolution < VDateField.RESOLUTION_MONTH) {
+            format = format.replaceAll("M", "");
+        }
+
+        // Remove unsupported patterns
+        // TODO support for 'G', era designator (used at least in Japan)
+        format = format.replaceAll("[GzZwWkK]", "");
+
+        // Remove extra delimiters ('/' and '.')
+        while (format.startsWith("/") || format.startsWith(".")
+                || format.startsWith("-")) {
+            format = format.substring(1);
+        }
+        while (format.endsWith("/") || format.endsWith(".")
+                || format.endsWith("-")) {
+            format = format.substring(0, format.length() - 1);
+        }
+
+        // Remove duplicate delimiters
+        format = format.replaceAll("//", "/");
+        format = format.replaceAll("\\.\\.", ".");
+        format = format.replaceAll("--", "-");
+
+        return format.trim();
+    }
+
+    @Override
+    public void setWidth(String newWidth) {
+        if (!"".equals(newWidth) && (width == null || !newWidth.equals(width))) {
+            if (BrowserInfo.get().isIE6()) {
+                // in IE6 cols ~ min-width
+                DOM.setElementProperty(text.getElement(), "size", "1");
+            }
+            needLayout = true;
+            width = newWidth;
+            super.setWidth(width);
+            iLayout();
+            if (newWidth.indexOf("%") < 0) {
+                needLayout = false;
+            }
+        } else {
+            if ("".equals(newWidth) && width != null && !"".equals(width)) {
+                if (BrowserInfo.get().isIE6()) {
+                    // revert IE6 hack
+                    DOM.setElementProperty(text.getElement(), "size", "");
+                }
+                super.setWidth("");
+                needLayout = true;
+                iLayout();
+                needLayout = false;
+                width = null;
+            }
+        }
+    }
+
+    /**
+     * Returns pixels in x-axis reserved for other than textfield content.
+     * 
+     * @return extra width in pixels
+     */
+    protected int getFieldExtraWidth() {
+        if (fieldExtraWidth < 0) {
+            text.setWidth("0");
+            fieldExtraWidth = text.getOffsetWidth();
+            if (BrowserInfo.get().isFF3()) {
+                // Firefox somehow always leaves the INPUT element 2px wide
+                fieldExtraWidth -= 2;
+            }
+        }
+        return fieldExtraWidth;
+    }
+
+    public void updateWidth() {
+        needLayout = true;
+        fieldExtraWidth = -1;
+        iLayout();
+    }
+
+    public void iLayout() {
+        if (needLayout) {
+            text.setWidth((getOffsetWidth() - getFieldExtraWidth()) + "px");
+        }
+    }
+
+    public void focus() {
+        text.setFocus(true);
+    }
+}
index 789ae06b48596851c6389a54ace67b4954ba7dc1..425040a01697c0c509bd6ae4194831481c06426a 100644 (file)
@@ -116,6 +116,8 @@ public class DateField extends AbstractField {
      */
     private String dateString;
 
+    private boolean lenient = false;
+
     /* Constructors */
 
     /**
@@ -202,6 +204,10 @@ public class DateField extends AbstractField {
             target.addAttribute("format", dateFormat);
         }
 
+        if (!isLenient()) {
+            target.addAttribute("strict", true);
+        }
+
         target.addAttribute("type", type);
 
         // Gets the calendar
@@ -511,4 +517,32 @@ public class DateField extends AbstractField {
         return dateFormat;
     }
 
+    /**
+     * Specifies whether or not date/time interpretation in component is to be
+     * lenient.
+     * 
+     * @see Calendar#setLenient(boolean)
+     * @see #isLenient()
+     * 
+     * @param lenient
+     *            true if the lenient mode is to be turned on; false if it is to
+     *            be turned off.
+     */
+    public void setLenient(boolean lenient) {
+        this.lenient = lenient;
+        requestRepaint();
+    }
+
+    /**
+     * Specifies whether or not date/time interpretation is to be lenient.
+     * 
+     * @see #setLenient(boolean)
+     * 
+     * @return true if the interpretation mode of this calendar is lenient;
+     *         false otherwise.
+     */
+    public boolean isLenient() {
+        return lenient;
+    }
+
 }
diff --git a/tests/src/com/vaadin/tests/components/datefield/LenientMode.java b/tests/src/com/vaadin/tests/components/datefield/LenientMode.java
new file mode 100644 (file)
index 0000000..96eaa21
--- /dev/null
@@ -0,0 +1,80 @@
+package com.vaadin.tests.components.datefield;
+
+import java.util.Date;
+import java.util.Locale;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.DateField;
+
+public class LenientMode extends TestBase implements ValueChangeListener {
+
+    private static final long serialVersionUID = -9064553409580072387L;
+
+    @Override
+    protected String getDescription() {
+        return "In lenien mode DateField should accept date input from user like '32/12/09'. In normal mode, an exception should be thrown. ";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 3175;
+    }
+
+    @Override
+    protected void setup() {
+
+        Date d = new Date(2009 - 1900, 12 - 1, 31, 23, 59, 59);
+
+        DateField df = new DateField("Lenient ");
+        df.setLocale(new Locale("fi"));
+        df.setResolution(DateField.RESOLUTION_DAY);
+        df.setLenient(true);
+        df.setImmediate(true);
+        df.setValue(d);
+
+        DateField df2 = new DateField("Normal ");
+        df2.setLocale(new Locale("fi"));
+        df2.setResolution(DateField.RESOLUTION_DAY);
+        // df2.setLenient(false);
+        df2.setValue(null);
+        df2.setImmediate(true);
+        df2.setValue(d);
+
+        addComponent(df);
+        addComponent(df2);
+
+        df.addListener(this);
+        df2.addListener(this);
+
+        df = new DateField("Lenient with time");
+        df.setLocale(new Locale("fi"));
+        df.setLenient(true);
+        df.setImmediate(true);
+        df.setValue(d);
+
+        df2 = new DateField("Normal with time");
+        df2.setLocale(new Locale("fi"));
+        // df2.setLenient(false);
+        df2.setValue(null);
+        df2.setImmediate(true);
+        df2.setValue(d);
+
+        addComponent(df);
+        addComponent(df2);
+
+        df.addListener(this);
+        df2.addListener(this);
+
+        addComponent(new Button("Visit server"));
+
+    }
+
+    public void valueChange(ValueChangeEvent event) {
+        getMainWindow().showNotification(
+                "New value" + event.getProperty().getValue());
+
+    }
+}