aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Alhroos <john.ahlroos@itmill.com>2010-05-25 13:15:27 +0000
committerJohn Alhroos <john.ahlroos@itmill.com>2010-05-25 13:15:27 +0000
commite6621e121167b7be67141acf09c1a20a5d32e9a5 (patch)
tree0e6a99fce9c2a9f14a9d335bcdc42fc92cc7c821
parent6e82a663398541cfe945fb0819bcda56900b3955 (diff)
downloadvaadin-framework-e6621e121167b7be67141acf09c1a20a5d32e9a5.tar.gz
vaadin-framework-e6621e121167b7be67141acf09c1a20a5d32e9a5.zip
Fix for #4311
svn changeset:13359/svn branch:6.4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java15
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java8
-rw-r--r--src/com/vaadin/ui/DateField.java90
-rw-r--r--tests/src/com/vaadin/tests/components/datefield/DateFieldUnparsableDate.java10
-rw-r--r--tests/src/com/vaadin/tests/components/datefield/DefaultHandleUnparsableDateField.java43
5 files changed, 156 insertions, 10 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java
index 8d5c21c512..b8a004e699 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java
@@ -27,6 +27,7 @@ public class VPopupCalendar extends VTextualDate implements Paintable, Field,
private final VOverlay popup;
private boolean open = false;
+ private boolean parsable = true;
public VPopupCalendar() {
super();
@@ -51,7 +52,10 @@ public class VPopupCalendar extends VTextualDate implements Paintable, Field,
@Override
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
boolean lastReadOnlyState = readonly;
+ parsable = uidl.getBooleanAttribute("parsable");
+
super.updateFromUIDL(uidl, client);
+
popup.setStyleName(VDateField.CLASSNAME + "-popup "
+ VDateField.CLASSNAME + "-"
+ resolutionToString(currentResolution));
@@ -174,4 +178,15 @@ public class VPopupCalendar extends VTextualDate implements Paintable, Field,
return fieldExtraWidth;
}
+ @Override
+ protected void buildDate() {
+ // Save previous value
+ String previousValue = getText();
+ super.buildDate();
+
+ // Restore previous value if the input could not be parsed
+ if (!parsable) {
+ setText(previousValue);
+ }
+ }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java
index 510676b3a4..209c5cabde 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java
@@ -356,4 +356,12 @@ public class VTextualDate extends VDateField implements Paintable, Field,
text.setFocus(true);
}
+ protected String getText() {
+ return text.getText();
+ }
+
+ protected void setText(String text) {
+ this.text.setText(text);
+ }
+
}
diff --git a/src/com/vaadin/ui/DateField.java b/src/com/vaadin/ui/DateField.java
index 45fd45716d..52f6d60a9d 100644
--- a/src/com/vaadin/ui/DateField.java
+++ b/src/com/vaadin/ui/DateField.java
@@ -12,6 +12,7 @@ import java.util.Locale;
import java.util.Map;
import com.vaadin.data.Property;
+import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.event.FieldEvents;
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
@@ -19,6 +20,7 @@ import com.vaadin.event.FieldEvents.FocusEvent;
import com.vaadin.event.FieldEvents.FocusListener;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.UserError;
import com.vaadin.terminal.gwt.client.ui.VDateField;
import com.vaadin.terminal.gwt.client.ui.VPopupCalendar;
@@ -119,6 +121,13 @@ public class DateField extends AbstractField implements
private boolean lenient = false;
+ private String dateString = null;
+
+ /**
+ * Was the last entered string parsable?
+ */
+ private boolean parsingSucceeded = true;
+
/**
* Determines if week numbers are shown in the date selector.
*/
@@ -130,6 +139,7 @@ public class DateField extends AbstractField implements
* Constructs an empty <code>DateField</code> with no caption.
*/
public DateField() {
+ setInvalidAllowed(false);
}
/**
@@ -140,6 +150,7 @@ public class DateField extends AbstractField implements
*/
public DateField(String caption) {
setCaption(caption);
+ setInvalidAllowed(false);
}
/**
@@ -164,6 +175,7 @@ public class DateField extends AbstractField implements
* the Property to be edited with this editor.
*/
public DateField(Property dataSource) throws IllegalArgumentException {
+ setInvalidAllowed(false);
if (!Date.class.isAssignableFrom(dataSource.getType())) {
throw new IllegalArgumentException("Can't use "
+ dataSource.getType().getName()
@@ -186,6 +198,7 @@ public class DateField extends AbstractField implements
* the Date value.
*/
public DateField(String caption, Date value) {
+ setInvalidAllowed(false);
setValue(value);
setCaption(caption);
}
@@ -216,6 +229,7 @@ public class DateField extends AbstractField implements
target.addAttribute("type", type);
target.addAttribute(VDateField.WEEK_NUMBERS, isShowISOWeekNumbers());
+ target.addAttribute("parsable", parsingSucceeded);
// Gets the calendar
final Calendar calendar = getCalendar();
@@ -264,6 +278,7 @@ public class DateField extends AbstractField implements
@Override
public void changeVariables(Object source, Map variables) {
super.changeVariables(source, variables);
+ setComponentError(null);
if (!isReadOnly()
&& (variables.containsKey("year")
@@ -281,7 +296,7 @@ public class DateField extends AbstractField implements
// this enables analyzing invalid input on the server
Object o = variables.get("dateString");
- String dateString = null;
+ dateString = null;
if (o != null) {
dateString = o.toString();
}
@@ -345,7 +360,10 @@ public class DateField extends AbstractField implements
if (newDate == null && dateString != null && !"".equals(dateString)) {
try {
- setValue(handleUnparsableDateString(dateString));
+ Date parsedDate = handleUnparsableDateString(dateString);
+ parsingSucceeded = true;
+ setValue(parsedDate, true);
+
/*
* Ensure the value is sent to the client if the value is
* set to the same as the previous (#4304). Does not repaint
@@ -354,13 +372,25 @@ public class DateField extends AbstractField implements
*/
requestRepaint();
} catch (ConversionException e) {
- // FIXME: Should not throw the exception but set an error
- // message for the field. And should retain the entered
- // value.
- throw e;
+ /*
+ * Sets the component error to the Conversion Exceptions
+ * message. This can be overriden in
+ * handleUnparsableDateString.
+ */
+ setComponentError(new UserError(e.getLocalizedMessage()));
+
+ /*
+ * The value of the DateField should be null if an invalid
+ * value has been given. Not using setValue() since we do
+ * not want to cause the client side value to change.
+ */
+ parsingSucceeded = false;
+ setInternalValue(null);
+ fireValueChange(true);
}
} else if (newDate != oldDate
&& (newDate == null || !newDate.equals(oldDate))) {
+ parsingSucceeded = true;
setValue(newDate, true); // Don't require a repaint, client
// updates itself
}
@@ -392,7 +422,7 @@ public class DateField extends AbstractField implements
*/
protected Date handleUnparsableDateString(String dateString)
throws Property.ConversionException {
- throw new Property.ConversionException();
+ throw new Property.ConversionException("Date format not recognized");
}
/* Property features */
@@ -430,13 +460,25 @@ public class DateField extends AbstractField implements
setValue(newValue, false);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.AbstractField#setValue(java.lang.Object, boolean)
+ */
@Override
public void setValue(Object newValue, boolean repaintIsNotNeeded)
throws Property.ReadOnlyException, Property.ConversionException {
// Allows setting dates directly
if (newValue == null || newValue instanceof Date) {
- super.setValue(newValue, repaintIsNotNeeded);
+ try {
+ super.setValue(newValue, repaintIsNotNeeded);
+ parsingSucceeded = true;
+ } catch (InvalidValueException ive) {
+ // Thrown if validator fails
+ parsingSucceeded = false;
+ throw ive;
+ }
} else {
// Try to parse as string
@@ -444,8 +486,11 @@ public class DateField extends AbstractField implements
final SimpleDateFormat parser = new SimpleDateFormat();
final Date val = parser.parse(newValue.toString());
super.setValue(val, repaintIsNotNeeded);
+ parsingSucceeded = true;
} catch (final ParseException e) {
- throw new Property.ConversionException(e.getMessage());
+ parsingSucceeded = false;
+ throw new Property.ConversionException(
+ "Date format not recognized");
}
}
}
@@ -611,4 +656,31 @@ public class DateField extends AbstractField implements
requestRepaint();
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.AbstractField#isEmpty()
+ */
+ @Override
+ protected boolean isEmpty() {
+ /*
+ * Logically isEmpty() should return false also in the case that the
+ * entered value is invalid.
+ */
+ return dateString == null || dateString.equals("");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.AbstractField#isValid()
+ */
+ @Override
+ public boolean isValid() {
+ /*
+ * For the DateField to be valid it has to be parsable also
+ */
+ boolean parsable = isEmpty() || (!isEmpty() && getValue() != null);
+ return parsable && super.isValid();
+ }
}
diff --git a/tests/src/com/vaadin/tests/components/datefield/DateFieldUnparsableDate.java b/tests/src/com/vaadin/tests/components/datefield/DateFieldUnparsableDate.java
index b0c06acb7a..ef0cbf03e7 100644
--- a/tests/src/com/vaadin/tests/components/datefield/DateFieldUnparsableDate.java
+++ b/tests/src/com/vaadin/tests/components/datefield/DateFieldUnparsableDate.java
@@ -2,20 +2,28 @@ package com.vaadin.tests.components.datefield;
import java.util.Date;
+import com.vaadin.data.Property;
import com.vaadin.tests.components.TestBase;
import com.vaadin.ui.DateField;
public class DateFieldUnparsableDate extends TestBase {
public class MyDateField extends DateField {
+ Date oldDate = null;
public MyDateField(String caption) {
super(caption);
+ addListener(new Property.ValueChangeListener() {
+ public void valueChange(
+ com.vaadin.data.Property.ValueChangeEvent event) {
+ oldDate = (Date) getValue();
+ }
+ });
}
@Override
protected Date handleUnparsableDateString(String dateString)
throws ConversionException {
- return (Date) getValue();
+ return oldDate;
}
}
diff --git a/tests/src/com/vaadin/tests/components/datefield/DefaultHandleUnparsableDateField.java b/tests/src/com/vaadin/tests/components/datefield/DefaultHandleUnparsableDateField.java
new file mode 100644
index 0000000000..bcdc8260b0
--- /dev/null
+++ b/tests/src/com/vaadin/tests/components/datefield/DefaultHandleUnparsableDateField.java
@@ -0,0 +1,43 @@
+package com.vaadin.tests.components.datefield;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.validator.NullValidator;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.DateField;
+
+@SuppressWarnings("serial")
+public class DefaultHandleUnparsableDateField extends TestBase {
+
+ @Override
+ protected void setup() {
+ final DateField date = new DateField("Default DateField");
+ date.setImmediate(true);
+ addComponent(date);
+ date.addListener(new Property.ValueChangeListener() {
+ public void valueChange(ValueChangeEvent event) {
+ if (date.isValid()) {
+ getMainWindow().showNotification(date.toString());
+ }
+
+ }
+ });
+
+ final DateField validated = new DateField("Validated Default DateField");
+ validated.setImmediate(true);
+ validated.addValidator(new NullValidator("Validator: Date is NULL",
+ false));
+ addComponent(validated);
+ }
+
+ @Override
+ protected String getDescription() {
+ return "By default the DateField should handle an unparsable date field without throwing an exception";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 4311;
+ }
+
+}