Repository: wicket Updated Branches: refs/heads/WICKET-6105-java.time 66f8f2aec -> bb86a3e70
Tests and examples are added Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/bb86a3e7 Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/bb86a3e7 Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/bb86a3e7 Branch: refs/heads/WICKET-6105-java.time Commit: bb86a3e70986e0bff9b0681e0ab53e56da8fb6fd Parents: 66f8f2a Author: Maxim Solodovnik <[email protected]> Authored: Tue Oct 3 21:59:29 2017 +0700 Committer: Maxim Solodovnik <[email protected]> Committed: Tue Oct 3 21:59:29 2017 +0700 ---------------------------------------------------------------------- .../wicket/examples/datetime/DateTimePage.html | 20 ++- .../wicket/examples/datetime/DateTimePage.java | 44 +++++ .../html/form/datetime/StyleTimeConverter.java | 12 +- .../markup/html/form/datetime/TimeField.java | 92 ++++++---- .../html/form/datetime/DateTimeFieldTest.java | 172 +++++++++++++++++++ 5 files changed, 295 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/bb86a3e7/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.html ---------------------------------------------------------------------- diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.html index d4e9eaa..eed5878 100644 --- a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.html +++ b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.html @@ -9,18 +9,26 @@ <body> <span wicket:id="mainNavigation" /> - <!-- h3>Demo of Wicket's default: <em>org.apache.wicket.extensions.markup.html.captcha.CaptchaImageResource</em> </h3> - <wicket:container wicket:id="wicket"></wicket:container> + <h3>Demo for short style time</h3> + <span wicket:id="time1"></span><br/> <hr/> - <h3>Demo using <a href="https://github.com/axet/kaptcha">Kaptcha</a> library</h3> - <wicket:container wicket:id="kaptcha"></wicket:container> + <h3>Demo for Full style time</h3> + <span wicket:id="time2"></span><br/> <hr/> - <h3>Demo using <a href="https://github.com/akiraly/cage">Cage</a> library</h3> - <wicket:container wicket:id="cage"></wicket:container--> + <h3>Demo for Short style time with 24-hours</h3> + <span wicket:id="time3"></span><br/> + <hr/> + + <form wicket:id="form"> + <h3>Demo for default Local Date Time in Form</h3> + <span wicket:id="datetime1"></span><br/> + <input wicket:id="submit" type="submit" value="Submit"/> + <div wicket:id="feedback"></div> + </form> </body> </html> http://git-wip-us.apache.org/repos/asf/wicket/blob/bb86a3e7/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.java ---------------------------------------------------------------------- diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.java index 26eaca5..6294863 100644 --- a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.java +++ b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.java @@ -16,7 +16,18 @@ */ package org.apache.wicket.examples.datetime; +import java.time.LocalDateTime; +import java.time.LocalTime; + +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.examples.WicketExamplePage; +import org.apache.wicket.extensions.markup.html.form.datetime.DateTimeField; +import org.apache.wicket.extensions.markup.html.form.datetime.StyleTimeConverter; +import org.apache.wicket.extensions.markup.html.form.datetime.TimeField; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.panel.FeedbackPanel; +import org.apache.wicket.model.Model; /** * DateTime example page. @@ -31,5 +42,38 @@ public class DateTimePage extends WicketExamplePage */ public DateTimePage() { + add(TimeField.forShortStyle("time1", Model.of(LocalTime.of(22, 15)))); + add(TimeField.forTimeStyle("time2", Model.of(LocalTime.of(22, 15)), "F")); + add(new TimeField("time3", Model.of(LocalTime.of(22, 15)), new StyleTimeConverter("S")) { + private static final long serialVersionUID = 1L; + + @Override + protected boolean use12HourFormat() { + return false; + } + }); + final DateTimeField datetime1 = new DateTimeField("datetime1", Model.of(LocalDateTime.now())); + final FeedbackPanel feedback = new FeedbackPanel("feedback"); + Form<String> form = new Form<>("form"); + add(form.add(datetime1) + .add(feedback.setOutputMarkupId(true)) + .add(new AjaxButton("submit") + { + private static final long serialVersionUID = 1L; + + @Override + protected void onSubmit(AjaxRequestTarget target) + { + form.info(String.format("DateTime was just submitted: %s", datetime1.getModelObject())); + target.add(feedback); + } + + @Override + protected void onError(AjaxRequestTarget target) + { + target.add(feedback); + } + }) + ); } } http://git-wip-us.apache.org/repos/asf/wicket/blob/bb86a3e7/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleTimeConverter.java ---------------------------------------------------------------------- diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleTimeConverter.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleTimeConverter.java index 1197f2a..e95725b 100644 --- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleTimeConverter.java +++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleTimeConverter.java @@ -38,12 +38,12 @@ public class StyleTimeConverter extends LocalTimeConverter private static final long serialVersionUID = 1L; /** - * Date style to use. See {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)}. + * Date style to use. See {@link DateTimeFormatter#ofLocalizedTime(FormatStyle)}. */ private final FormatStyle timeStyle; /** - * Construct. The dateStyle 'S-' (which is the same as {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)}) will + * Construct. The dateStyle 'S-' (which is the same as {@link DateTimeFormatter#ofLocalizedTime(FormatStyle)}) will * be used for constructing the date format for the current locale. * */ @@ -54,10 +54,10 @@ public class StyleTimeConverter extends LocalTimeConverter /** * Construct. The provided pattern will be used as the base format (but they will be localized - * for the current locale) and if null, {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)} will be used. + * for the current locale) and if null, {@link DateTimeFormatter#ofLocalizedTime(FormatStyle)} will be used. * * @param timeStyle - * Date style to use. See {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)}. + * Date style to use. See {@link DateTimeFormatter#ofLocalizedTime(FormatStyle)}. * @throws IllegalArgumentException * in case dateStyle is null */ @@ -89,12 +89,12 @@ public class StyleTimeConverter extends LocalTimeConverter @Override public DateTimeFormatter getFormat(Locale locale) { - return timeStyle == null ? null : DateTimeFormatter.ofLocalizedDate(timeStyle).withLocale(locale); + return timeStyle == null ? null : DateTimeFormatter.ofLocalizedTime(timeStyle).withLocale(locale); } public static FormatStyle parseFormatStyle(char style) { - return DateField.parseFormatStyle(style); + return TimeField.parseFormatStyle(style); } @Override http://git-wip-us.apache.org/repos/asf/wicket/blob/bb86a3e7/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.java ---------------------------------------------------------------------- diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.java index cf3cc29..51e63c3 100644 --- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.java +++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.java @@ -27,6 +27,7 @@ import java.time.temporal.ChronoField; import java.util.Arrays; import java.util.Locale; +import org.apache.wicket.AttributeModifier; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider; import org.apache.wicket.markup.html.form.DropDownChoice; @@ -289,9 +290,19 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor * @return a new text field instance */ protected TextField<Integer> newHoursTextField(final String id, IModel<Integer> model, Class<Integer> type) { - TextField<Integer> hoursTextField = new TextField<>(id, model, type); - hoursTextField.add(getMaximumHours() == 24 ? RangeValidator.range(0, 23) : RangeValidator - .range(1, 12)); + TextField<Integer> hoursTextField = new TextField<Integer>(id, model, type) + { + private static final long serialVersionUID = 1L; + + @Override + protected String[] getInputTypes() + { + return new String[] {"number"}; + } + }; + hoursTextField.add(AttributeModifier.append("min", getMaximumHours() == 24 ? 0 : 1)); + hoursTextField.add(AttributeModifier.append("max", getMaximumHours() == 24 ? 23 : 12)); + hoursTextField.add(getMaximumHours() == 24 ? RangeValidator.range(0, 23) : RangeValidator.range(1, 12)); hoursTextField.setLabel(new Model<>(HOURS)); return hoursTextField; } @@ -323,7 +334,15 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor } return null; } + + @Override + protected String[] getInputTypes() + { + return new String[] {"number"}; + } }; + minutesField.add(AttributeModifier.append("min", 0)); + minutesField.add(AttributeModifier.append("max", 59)); minutesField.add(new RangeValidator<>(0, 59)); minutesField.setLabel(new Model<>(MINUTES)); return minutesField; @@ -340,20 +359,24 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor @Override public void convertInput() { - Integer hoursInput = hoursField.getConvertedInput(); - Integer minutesInput = minutesField.getConvertedInput(); + Integer hours = hoursField.getConvertedInput(); + Integer minutes = minutesField.getConvertedInput(); AM_PM amOrPmInput = amOrPmChoice.getConvertedInput(); - // Use the input to create a date object with proper timezone - LocalTime localTime = LocalTime.of(hoursInput, minutesInput); - - // Adjust for halfday if needed - if (use12HourFormat()) + LocalTime localTime = null; + if (hours != null && minutes != null) { - int halfday = (amOrPmInput == AM_PM.PM ? 1 : 0); - localTime = localTime.with(ChronoField.AMPM_OF_DAY, halfday); + // Use the input to create a LocalTime object + localTime = LocalTime.of(hours, minutes); + + // Adjust for halfday if needed + if (use12HourFormat()) + { + int halfday = (amOrPmInput == AM_PM.PM ? 1 : 0); + localTime = localTime.with(ChronoField.AMPM_OF_DAY, halfday); + } } - super.convertInput(); + setConvertedInput(localTime); } @Override @@ -400,7 +423,6 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor return use12HourFormat ? 12 : 24; } - protected class HoursModel implements IModel<Integer> { private static final long serialVersionUID = 1L; @@ -408,18 +430,18 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor @Override public Integer getObject() { - return time.getHour(); + LocalTime t = TimeField.this.getModelObject(); + if (t == null) + { + return null; + } + return getMaximumHours() == 24 ? t.getHour() : t.get(ChronoField.CLOCK_HOUR_OF_AMPM); } @Override public void setObject(Integer hour) { - time = time.with(ChronoField.HOUR_OF_DAY, hour); - } - - @Override - public void detach() - { + time = time.with(getMaximumHours() == 24 ? ChronoField.HOUR_OF_DAY : ChronoField.CLOCK_HOUR_OF_AMPM, hour); } } @@ -430,7 +452,8 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor @Override public Integer getObject() { - return time.getMinute(); + LocalTime t = TimeField.this.getModelObject(); + return t == null ? null : t.getMinute(); } @Override @@ -438,11 +461,6 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor { time = time.with(ChronoField.MINUTE_OF_HOUR, minute); } - - @Override - public void detach() - { - } } protected class AmPmModel implements IModel<AM_PM> @@ -452,7 +470,8 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor @Override public AM_PM getObject() { - int i = time.get(ChronoField.AMPM_OF_DAY); + LocalTime t = TimeField.this.getModelObject(); + int i = t == null ? 0 : t.get(ChronoField.AMPM_OF_DAY); return i == 0 ? AM_PM.AM : AM_PM.PM; } @@ -462,11 +481,6 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor int i = AM_PM.AM == amPm ? 0 : 1; time = time.with(ChronoField.AMPM_OF_DAY, i); } - - @Override - public void detach() - { - } } /** @@ -491,4 +505,16 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor { return converter.getPattern(getLocale()); } + + public static FormatStyle parseFormatStyle(char style) + { + switch (style) + { + case 'M': + return FormatStyle.MEDIUM; + case 'S': + default: + return FormatStyle.SHORT; + } + } } http://git-wip-us.apache.org/repos/asf/wicket/blob/bb86a3e7/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeFieldTest.java ---------------------------------------------------------------------- diff --git a/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeFieldTest.java b/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeFieldTest.java new file mode 100644 index 0000000..3b167e4 --- /dev/null +++ b/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeFieldTest.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.wicket.extensions.markup.html.form.datetime; + +import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Locale; + +import org.apache.wicket.MarkupContainer; +import org.apache.wicket.markup.IMarkupResourceStreamProvider; +import org.apache.wicket.markup.html.WebPage; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.form.FormComponent; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.util.resource.IResourceStream; +import org.apache.wicket.util.resource.StringResourceStream; +import org.apache.wicket.util.tester.FormTester; +import org.apache.wicket.util.tester.WicketTestCase; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class DateTimeFieldTest extends WicketTestCase { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void timeNullTest() { + TestTimePage page = new TestTimePage(null); + tester.startPage(page); + FormTester formTester = tester.newFormTester("form", false); + formTester.submit(); + assertNull(page.field.getModelObject()); + } + + @Test + public void timeNullHoursTest() { + TestTimePage page = new TestTimePage(null); + tester.startPage(page); + FormTester formTester = tester.newFormTester("form", false); + formTester.setValue("field:minutes", "8"); + formTester.submit(); + assertNull(page.field.getModelObject()); + } + + @Test + public void timeNullMinutesTest() { + TestTimePage page = new TestTimePage(null); + tester.startPage(page); + FormTester formTester = tester.newFormTester("form", false); + formTester.setValue("field:hours", "8"); + formTester.submit(); + assertNull(page.field.getModelObject()); + } + + @Test + public void timeNotNullTest() { + TestTimePage page = new TestTimePage(LocalTime.of(6, 15)); + tester.startPage(page); + FormTester formTester = tester.newFormTester("form", false); + formTester.setValue("field:hours", "8"); + formTester.submit(); + LocalTime t = page.field.getModelObject(); + assertNotNull(t); + assertEquals(8, t.getHour()); + assertEquals(15, t.getMinute()); + } + + @Test + public void dateNullTest() { + TestDatePage page = new TestDatePage(null); + tester.startPage(page); + FormTester formTester = tester.newFormTester("form", false); + formTester.submit(); + assertNull(page.field.getModelObject()); + } + + @Test + public void dateNotNullTest() { + LocalDate date = LocalDate.of(2017, 02, 13); + TestDatePage page = new TestDatePage(null); + tester.startPage(page); + FormTester formTester = tester.newFormTester("form", false); + formTester.setValue("field", new StyleDateConverter("F").convertToString(date, Locale.forLanguageTag("en-US"))); + formTester.submit(); + LocalDate d = page.field.getModelObject(); + assertNotNull(d); + assertEquals(date, d); + } + + public static class TestDatePage extends TestPage<LocalDate> + { + private static final long serialVersionUID = 1L; + + TestDatePage(LocalDate val) + { + super(val); + tag = "input type=\"text\""; + } + + @Override + FormComponent<LocalDate> newComponent() + { + return DateField.forDateStyle("field", model, "F"); + } + } + + public static class TestTimePage extends TestPage<LocalTime> + { + private static final long serialVersionUID = 1L; + + TestTimePage(LocalTime val) + { + super(val); + } + + @Override + FormComponent<LocalTime> newComponent() + { + return TimeField.forTimeStyle("field", model, "F"); + } + } + + public abstract static class TestPage<T extends Serializable> extends WebPage implements IMarkupResourceStreamProvider + { + private static final long serialVersionUID = 1L; + Form<Void> form; + FormComponent<T> field; + IModel<T> model = new Model<T>(); + String tag = "span"; + + /** */ + public TestPage(T val) + { + add(form = new Form<>("form")); + model.setObject(val); + form.add(field = newComponent()); + } + + abstract FormComponent<T> newComponent(); + + @Override + public IResourceStream getMarkupResourceStream(MarkupContainer container, Class<?> containerClass) + { + return new StringResourceStream(String.format("<html><body>" + + "<form wicket:id=\"form\"><%s wicket:id=\"field\"/></form></body></html>", tag)); + } + + @Override + protected void onDetach() + { + super.onDetach(); + model.detach(); + } + } +}
