@@ -38,6 +38,7 @@ import java.util.logging.Logger; | |||
import java.util.stream.Collectors; | |||
import java.util.stream.Stream; | |||
import elemental.json.Json; | |||
import org.jsoup.nodes.Element; | |||
import com.googlecode.gentyref.GenericTypeReflector; | |||
@@ -119,7 +120,17 @@ public abstract class AbstractDateField<T extends Temporal & TemporalAdjuster & | |||
if (resolutions.isEmpty()) { | |||
Result<T> parsedDate = handleUnparsableDateString( | |||
dateString); | |||
parsedDate.ifOk(v -> setValue(v, true)); | |||
// If handleUnparsableDateString returns the same | |||
// date as current, force update state to display | |||
// correct representation | |||
parsedDate.ifOk(v -> { | |||
if (!setValue(v, true) | |||
&& !isDifferentValue(v)) { | |||
updateDiffstate("resolutions", | |||
Json.createObject()); | |||
doSetValue(v); | |||
} | |||
}); | |||
if (parsedDate.isError()) { | |||
dateString = null; | |||
currentParseErrorMessage = parsedDate |
@@ -0,0 +1,83 @@ | |||
package com.vaadin.tests.components.datefield; | |||
import com.vaadin.data.Result; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.DateField; | |||
import org.apache.commons.lang3.StringUtils; | |||
import java.time.LocalDate; | |||
import java.time.Year; | |||
import java.time.format.DateTimeFormatterBuilder; | |||
import java.time.temporal.ChronoField; | |||
public class DateFieldUnparsableDateString extends AbstractTestUI { | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return 10681; | |||
} | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
DateField dateField1 = new ParsableDateField(); | |||
dateField1.setDateFormat("dd.MM.yyyy"); | |||
addComponent(dateField1); | |||
} | |||
public class ParsableDateField extends DateField { | |||
@Override | |||
protected Result<LocalDate> handleUnparsableDateString( | |||
String dateString) { | |||
try { | |||
String parseableString = StringUtils.remove(dateString, ' '); | |||
if (parseableString.length() % 2 == 1) { | |||
parseableString = "0" + parseableString; | |||
} | |||
int cutYear = Year.now().getValue() - 80; | |||
LocalDate today = LocalDate.now(); | |||
switch (parseableString.length()) { | |||
case 2: | |||
// Only day !!! dd | |||
return Result.ok(LocalDate.parse(parseableString, | |||
new DateTimeFormatterBuilder().appendPattern("dd") | |||
.parseDefaulting(ChronoField.MONTH_OF_YEAR, | |||
today.getMonthValue()) | |||
.parseDefaulting(ChronoField.YEAR, | |||
today.getYear()) | |||
.toFormatter())); | |||
case 4: | |||
// Only day + month ddMM | |||
return Result | |||
.ok(LocalDate.parse(parseableString, | |||
new DateTimeFormatterBuilder() | |||
.appendPattern("ddMM") | |||
.parseDefaulting(ChronoField.YEAR, | |||
today.getYear()) | |||
.toFormatter())); | |||
case 6: | |||
// Short year ddMMyy | |||
return Result.ok(LocalDate.parse(parseableString, | |||
new DateTimeFormatterBuilder().appendPattern("ddMM") | |||
.appendValueReduced(ChronoField.YEAR, 2, 2, | |||
cutYear) | |||
.toFormatter())); | |||
case 8: | |||
// Long year ddMMyyyy | |||
parseableString = StringUtils.leftPad(dateString, 8, "0"); | |||
return Result | |||
.ok(LocalDate.parse(parseableString, | |||
new DateTimeFormatterBuilder() | |||
.appendPattern("ddMMyyyy") | |||
.toFormatter())); | |||
default: | |||
break; | |||
} | |||
} catch (Exception e) { | |||
} | |||
return super.handleUnparsableDateString(dateString); | |||
} | |||
} | |||
} |
@@ -0,0 +1,40 @@ | |||
package com.vaadin.tests.components.datefield; | |||
import com.vaadin.testbench.By; | |||
import com.vaadin.testbench.elements.AbstractDateFieldElement; | |||
import com.vaadin.testbench.parallel.Browser; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
import org.junit.Test; | |||
import org.openqa.selenium.Keys; | |||
import org.openqa.selenium.WebElement; | |||
import org.openqa.selenium.remote.DesiredCapabilities; | |||
import java.util.List; | |||
import static org.junit.Assert.assertEquals; | |||
public class DateFieldUnparsableDateStringTest extends MultiBrowserTest { | |||
@Test | |||
public void testInvalidText() throws InterruptedException { | |||
openTestURL(); | |||
waitForElementVisible(By.className("v-datefield")); | |||
WebElement dateTextbox = $(AbstractDateFieldElement.class).first() | |||
.findElement(By.className("v-textfield")); | |||
dateTextbox.sendKeys("0304", Keys.ENTER); | |||
findElement(By.tagName("body")).click(); | |||
assertEquals("03.04.2018", dateTextbox.getAttribute("value")); | |||
dateTextbox.clear(); | |||
dateTextbox.sendKeys("0304", Keys.ENTER); | |||
findElement(By.tagName("body")).click(); | |||
assertEquals("03.04.2018", dateTextbox.getAttribute("value")); | |||
} | |||
@Override | |||
public List<DesiredCapabilities> getBrowsersToTest() { | |||
// Ignoring Phantom JS | |||
return getBrowserCapabilities(Browser.IE11, Browser.FIREFOX, | |||
Browser.CHROME); | |||
} | |||
} |