From 63e4d9660de3f4c615a8e9444aaf3c3de128e77c Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gmail.com>
Date: Thu, 10 Dec 2015 09:33:30 -0500
Subject: [PATCH] Merge pull request #982 from gitblit/978-milestone-date-selector

---
 src/main/java/com/gitblit/wicket/pages/EditMilestonePage.java      |    8 +
 src/main/java/com/gitblit/wicket/pages/NewMilestonePage.html       |    4 
 src/main/java/com/gitblit/wicket/Html5DateField.java               |  156 +++++++++++++++++++++++++++++++++++++++
 src/main/java/com/gitblit/wicket/pages/EditMilestonePage.html      |    2 
 src/main/java/com/gitblit/wicket/pages/NewMilestonePage.java       |    7 +
 src/main/java/com/gitblit/wicket/pages/scripts/wicketHtml5Patch.js |   13 +++
 6 files changed, 181 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/gitblit/wicket/Html5DateField.java b/src/main/java/com/gitblit/wicket/Html5DateField.java
new file mode 100644
index 0000000..927ee46
--- /dev/null
+++ b/src/main/java/com/gitblit/wicket/Html5DateField.java
@@ -0,0 +1,156 @@
+package com.gitblit.wicket;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.wicket.Session;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.util.convert.IConverter;
+import org.apache.wicket.util.convert.converters.DateConverter;
+
+public class Html5DateField extends TextField<Date> implements ITextFormatProvider {
+
+	private static final long serialVersionUID = 1L;
+
+	private static final String DEFAULT_PATTERN = "MM/dd/yyyy";
+
+	private String datePattern = null;
+
+	private IConverter converter = null;
+
+	/**
+	 * Creates a new Html5DateField, without a specified pattern. This is the same as calling
+	 * <code>new Html5DateField(id, Date.class)</code>
+	 * 
+	 * @param id
+	 *            The id of the date field
+	 */
+	public Html5DateField(String id)
+	{
+		this(id, null, defaultDatePattern());
+	}
+
+	/**
+	 * Creates a new Html5DateField, without a specified pattern. This is the same as calling
+	 * <code>new Html5DateField(id, object, Date.class)</code>
+	 * 
+	 * @param id
+	 *            The id of the date field
+	 * @param model
+	 *            The model
+	 */
+	public Html5DateField(String id, IModel<Date> model)
+	{
+		this(id, model, defaultDatePattern());
+	}
+
+	/**
+	 * Creates a new Html5DateField bound with a specific <code>SimpleDateFormat</code> pattern.
+	 * 
+	 * @param id
+	 *            The id of the date field
+	 * @param datePattern
+	 *            A <code>SimpleDateFormat</code> pattern
+	 * 
+	 */
+	public Html5DateField(String id, String datePattern)
+	{
+		this(id, null, datePattern);
+	}
+
+	/**
+	 * Creates a new DateTextField bound with a specific <code>SimpleDateFormat</code> pattern.
+	 * 
+	 * @param id
+	 *            The id of the date field
+	 * @param model
+	 *            The model
+	 * @param datePattern
+	 *            A <code>SimpleDateFormat</code> pattern
+	 */
+	public Html5DateField(String id, IModel<Date> model, String datePattern)
+	{
+		super(id, model, Date.class);
+		this.datePattern = datePattern;
+		converter = new DateConverter()
+		{
+			private static final long serialVersionUID = 1L;
+
+			/**
+			 * @see org.apache.wicket.util.convert.converters.DateConverter#getDateFormat(java.util.Locale)
+			 */
+			@Override
+			public DateFormat getDateFormat(Locale locale)
+			{
+				if (locale == null)
+				{
+					locale = Locale.getDefault();
+				}
+				return new SimpleDateFormat(Html5DateField.this.datePattern, locale);
+			}
+		};
+	}
+
+	/**
+	 * Returns the default converter if created without pattern; otherwise it returns a
+	 * pattern-specific converter.
+	 * 
+	 * @param type
+	 *            The type for which the converter should work
+	 * 
+	 * @return A pattern-specific converter
+	 */
+	@Override
+	public IConverter getConverter(Class<?> type)
+	{
+		if (converter == null)
+		{
+			return super.getConverter(type);
+		}
+		else
+		{
+			return converter;
+		}
+	}
+
+	/**
+	 * Returns the date pattern.
+	 * 
+	 * @see org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider#getTextFormat()
+	 */
+	public String getTextFormat()
+	{
+		return datePattern;
+	}
+
+	/**
+	 * Try to get datePattern from user session locale. If it is not possible, it will return
+	 * {@link #DEFAULT_PATTERN}
+	 * 
+	 * @return date pattern
+	 */
+	private static String defaultDatePattern()
+	{
+		Locale locale = Session.get().getLocale();
+		if (locale != null)
+		{
+			DateFormat format = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+			if (format instanceof SimpleDateFormat)
+			{
+				return ((SimpleDateFormat)format).toPattern();
+			}
+		}
+		return DEFAULT_PATTERN;
+	}
+	
+	@Override
+	protected String getInputType()
+	{
+		return "date";
+	}
+	
+}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/wicket/pages/EditMilestonePage.html b/src/main/java/com/gitblit/wicket/pages/EditMilestonePage.html
index 0897ebe..13c2638 100644
--- a/src/main/java/com/gitblit/wicket/pages/EditMilestonePage.html
+++ b/src/main/java/com/gitblit/wicket/pages/EditMilestonePage.html
@@ -19,7 +19,7 @@
 		<!-- Edit Milestone Table -->
 		<table class="ticket">
 			<tr><th><wicket:message key="gb.milestone"></wicket:message></th><td class="edit"><input class="input-large" type="text" wicket:id="name" id="name"></input></td></tr>
-			<tr><th><wicket:message key="gb.due"></wicket:message></th><td class="edit"><input class="input-large" type="text" wicket:id="due"></input> &nbsp;<span class="help-inline" wicket:id="dueFormat"></span></td></tr>
+			<tr><th><wicket:message key="gb.due"></wicket:message></th><td class="edit"><input class="input-large" type="date" wicket:id="due"></input> &nbsp;<span class="help-inline" wicket:id="dueFormat"></span></td></tr>
 			<tr><th><wicket:message key="gb.status"></wicket:message><span style="color:red;">*</span></th><td class="edit"><select class="input-large" wicket:id="status"></select></td></tr>
 			<tr><th></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="notify" /> &nbsp;<span class="help-inline"><wicket:message key="gb.notifyChangedOpenTickets"></wicket:message></span></label></td></tr>
 		</table>
diff --git a/src/main/java/com/gitblit/wicket/pages/EditMilestonePage.java b/src/main/java/com/gitblit/wicket/pages/EditMilestonePage.java
index 6e96526..dc32665 100644
--- a/src/main/java/com/gitblit/wicket/pages/EditMilestonePage.java
+++ b/src/main/java/com/gitblit/wicket/pages/EditMilestonePage.java
@@ -24,7 +24,6 @@
 import org.apache.wicket.RestartResponseException;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
-import org.apache.wicket.extensions.markup.html.form.DateTextField;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.Button;
 import org.apache.wicket.markup.html.form.CheckBox;
@@ -42,6 +41,7 @@
 import com.gitblit.tickets.TicketMilestone;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.GitBlitWebSession;
+import com.gitblit.wicket.Html5DateField;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.panels.BasePanel.JavascriptEventConfirmation;
 
@@ -106,10 +106,12 @@
 		notificationModel = Model.of(true);
 
 		form.add(new TextField<String>("name", nameModel));
-		form.add(new DateTextField("due", dueModel, "yyyy-MM-dd"));
+		form.add(new Html5DateField("due", dueModel, "yyyy-MM-dd"));
 		form.add(new Label("dueFormat", "yyyy-MM-dd"));
 		form.add(new CheckBox("notify", notificationModel));
-
+		addBottomScriptInline("{var e=document.createElement('input');e.type='date';if(e.type=='date'){$('[name=\"due\"]~.help-inline').hide()}}");
+		addBottomScript("scripts/wicketHtml5Patch.js");
+		
 		List<Status> statusChoices = Arrays.asList(Status.Open, Status.Closed);
 		form.add(new DropDownChoice<TicketModel.Status>("status", statusModel, statusChoices));
 
diff --git a/src/main/java/com/gitblit/wicket/pages/NewMilestonePage.html b/src/main/java/com/gitblit/wicket/pages/NewMilestonePage.html
index 2ba5d5c..814aa53 100644
--- a/src/main/java/com/gitblit/wicket/pages/NewMilestonePage.html
+++ b/src/main/java/com/gitblit/wicket/pages/NewMilestonePage.html
@@ -5,6 +5,7 @@
       lang="en"> 
 
 <wicket:extend>
+
 <body onload="document.getElementById('name').focus();">
 	
 <div class="container">
@@ -19,7 +20,7 @@
 		<!-- New Milestone Table -->
 		<table class="ticket">
 			<tr><th><wicket:message key="gb.milestone"></wicket:message></th><td class="edit"><input class="input-large" type="text" wicket:id="name" id="name"></input></td></tr>
-			<tr><th><wicket:message key="gb.due"></wicket:message></th><td class="edit"><input class="input-large" type="text" wicket:id="due"></input> &nbsp;<span class="help-inline" wicket:id="dueFormat"></span></td></tr>
+			<tr><th><wicket:message key="gb.due"></wicket:message></th><td class="edit"><input class="input-large" type="date" wicket:id="due"></input> &nbsp;<span class="help-inline" wicket:id="dueFormat"></span></td></tr>
 		</table>
 	</div>
 	</div>	
@@ -32,6 +33,5 @@
 	</form>
 </div>
 </body>
-
 </wicket:extend>
 </html>
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/wicket/pages/NewMilestonePage.java b/src/main/java/com/gitblit/wicket/pages/NewMilestonePage.java
index b452a91..2250f38 100644
--- a/src/main/java/com/gitblit/wicket/pages/NewMilestonePage.java
+++ b/src/main/java/com/gitblit/wicket/pages/NewMilestonePage.java
@@ -21,7 +21,6 @@
 import org.apache.wicket.RestartResponseException;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
-import org.apache.wicket.extensions.markup.html.form.DateTextField;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.Button;
 import org.apache.wicket.markup.html.form.Form;
@@ -35,6 +34,7 @@
 import com.gitblit.utils.StringUtils;
 import com.gitblit.utils.TimeUtils;
 import com.gitblit.wicket.GitBlitWebSession;
+import com.gitblit.wicket.Html5DateField;
 import com.gitblit.wicket.WicketUtils;
 
 /**
@@ -78,9 +78,10 @@
 		dueModel = Model.of(new Date(System.currentTimeMillis() + TimeUtils.ONEDAY));
 
 		form.add(new TextField<String>("name", nameModel));
-		form.add(new DateTextField("due", dueModel, "yyyy-MM-dd"));
+		form.add(new Html5DateField("due", dueModel, "yyyy-MM-dd"));
 		form.add(new Label("dueFormat", "yyyy-MM-dd"));
-
+		addBottomScriptInline("{var e=document.createElement('input');e.type='date';if(e.type=='date'){$('[name=\"due\"]~.help-inline').hide()}}");
+		addBottomScript("scripts/wicketHtml5Patch.js");
 		form.add(new AjaxButton("create") {
 
 			private static final long serialVersionUID = 1L;
diff --git a/src/main/java/com/gitblit/wicket/pages/scripts/wicketHtml5Patch.js b/src/main/java/com/gitblit/wicket/pages/scripts/wicketHtml5Patch.js
new file mode 100644
index 0000000..49088e1
--- /dev/null
+++ b/src/main/java/com/gitblit/wicket/pages/scripts/wicketHtml5Patch.js
@@ -0,0 +1,13 @@
+//This provides a basic patch/hack to allow Wicket 1.4 to support HTML5 input types
+
+Wicket.Form.serializeInput_original = Wicket.Form.serializeInput;
+
+Wicket.Form.serializeInput = function(input)
+{
+	if (input.type.toLowerCase() == "date")
+	{
+		return Wicket.Form.encode(input.name) + "=" + Wicket.Form.encode(input.value) + "&";
+	}
+	
+	return Wicket.Form.serializeInput_original(input);
+}

--
Gitblit v1.9.1