From: Patrik Lindström Date: Thu, 23 Jun 2016 13:00:52 +0000 (+0300) Subject: Discard for DateField when the data source contains null (#8069) X-Git-Tag: 7.7.1~13 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=3faa43ff39ecda56587b93f0c5e262a2907871a7;p=vaadin-framework.git Discard for DateField when the data source contains null (#8069) Earlier discard did not work (#8069) if the data source contained null and the user entered an invalid value for date fields. The discard logic has been changed such that the error indicators and internal state of the date field is cleared also if the value entered by the user is invalid and the data source is null. attach() updates the value from the data source in the same way as discard. The old logic in attach is retained. Change-Id: I5d798a2fdc3d2f0e82a037ea3cb2f57b6432039e --- diff --git a/server/src/main/java/com/vaadin/ui/DateField.java b/server/src/main/java/com/vaadin/ui/DateField.java index 052539cd28..82bd10178a 100644 --- a/server/src/main/java/com/vaadin/ui/DateField.java +++ b/server/src/main/java/com/vaadin/ui/DateField.java @@ -634,6 +634,24 @@ public class DateField extends AbstractField implements } } + @Override + public void discard() { + Property prop = getPropertyDataSource(); + if (prop != null) { + Object value = prop.getValue(); + if (!isValid() && value == null) { + // If the user entered an invalid value in the date field + // getInternalValue() returns null. + // If the datasource also contains null, then + // updateValueFromDataSource() will then not clear the internal state + // and error indicators (ticket #8069). + setInternalValue(null); + } else { + super.discard(); + } + } + } + /* * only fires the event if preventValueChangeEvent flag is false */ diff --git a/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldDiscardValue.java b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldDiscardValue.java new file mode 100644 index 0000000000..4839d02f3b --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/datefield/DateFieldDiscardValue.java @@ -0,0 +1,99 @@ +package com.vaadin.tests.components.datefield; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.DateField; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.VerticalLayout; + +/** + * Test to demonstrate how discarding of field value works with various valid + * and invalid data sources. Previously (Ticket #8069) the case where the + * content of the datasource was null was not handled correctly. This value + * is a valid data source value for the field, but discard did not actually discard + * the value or remove error markers in this cases. + * + * @author Vaadin Ltd + * + */ +public class DateFieldDiscardValue extends AbstractTestUI { + + public static final String PROP_NONULL = "A field with a valid date in the data source property"; + public static final String PROP_NULL_VALUE = "A field with a null value in the data source property"; + public static final String PROP_NULL = "A field with a null datasource property"; + + @Override + protected void setup(VaadinRequest request) { + String dateFormat = "dd/MM/yy"; + + final DateField df = new DateField(PROP_NONULL); + df.setDateFormat(dateFormat); + df.setBuffered(true); + Date date = null; + try { + date = new SimpleDateFormat(dateFormat).parse("25/07/16"); + } catch (ParseException e1) { + //This cannot happen + } + ObjectProperty prop = new ObjectProperty(date, Date.class); + df.setPropertyDataSource(prop); + Button button = new Button("Discard 1"); + button.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + df.discard(); + } + + }); + VerticalLayout layout = new VerticalLayout(); + HorizontalLayout hLayout = new HorizontalLayout(df, button); + layout.addComponent(hLayout); + + final DateField df1 = new DateField(PROP_NULL_VALUE); + df1.setDateFormat(dateFormat); + df1.setBuffered(true); + + prop = new ObjectProperty(null, Date.class); + df1.setPropertyDataSource(prop); + button = new Button("Discard 2"); + button.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + df1.discard(); + } + + }); + hLayout = new HorizontalLayout(df1, button); + layout.addComponent(hLayout); + + final DateField df2 = new DateField(PROP_NULL); + df2.setDateFormat(dateFormat); + df2.setBuffered(true); + df2.setPropertyDataSource(null); + button = new Button("Discard 3"); + button.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + df2.discard(); + } + + }); + hLayout = new HorizontalLayout(df2, button); + layout.addComponent(hLayout); + + setContent(layout); + + } + +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldDiscardValueTest.java b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldDiscardValueTest.java new file mode 100644 index 0000000000..142730a9a3 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/datefield/DateFieldDiscardValueTest.java @@ -0,0 +1,81 @@ +package com.vaadin.tests.components.datefield; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class DateFieldDiscardValueTest extends SingleBrowserTest { + + @Test + public void discardWhenDatasourceContentNonNullInvalidValue() { + discardWorks(DateFieldDiscardValue.PROP_NONULL, "1", "123", "25/07/16"); + } + + @Test + public void discardWhenDatasourceContentNonNullValidValue() { + discardWorks(DateFieldDiscardValue.PROP_NONULL, "1", "24/07/16", "25/07/16"); + } + + @Test + public void discardWhenDatasourceContentNullInvalidValue() { + discardWorks(DateFieldDiscardValue.PROP_NULL_VALUE, "2", "123", ""); + } + + @Test + public void discardWhenDatasourceContentNullValidValue() { + discardWorks(DateFieldDiscardValue.PROP_NULL_VALUE, "2", "24/07/16", ""); + } + + @Test + public void discardWhenDatasourceNull() { + //If the data source is null, discard should do nothing. + discardDoesntWork(DateFieldDiscardValue.PROP_NULL, "3", "123"); + } + + private void discardWorks(String caption, String id, String dateValue, String resultValue) { + openTestURL(); + + ButtonElement discardButton = $(ButtonElement.class).caption( + "Discard " + id).first(); + DateFieldElement dateField = $(DateFieldElement.class).caption( + caption).first(); + dateField.setValue(dateValue); + + discardButton.click(); + + assertEquals(resultValue, dateField.getValue()); + + List elements = driver.findElements(By + .className("v-errorindicator")); + + assertEquals(0, elements.size()); + } + + private void discardDoesntWork(String caption, String id, String dateValue) { + openTestURL(); + + ButtonElement discardButton = $(ButtonElement.class).caption( + "Discard " + id).first(); + DateFieldElement dateField = $(DateFieldElement.class).caption( + caption).first(); + dateField.setValue(dateValue); + + discardButton.click(); + + assertEquals(dateValue, dateField.getValue()); + + List elements = driver.findElements(By + .className("v-errorindicator")); + + assertEquals(1, elements.size()); + } + +}