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();
+               }
+       }
+}

Reply via email to