You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2014/04/06 21:14:16 UTC

[14/31] git commit: WW-3493 Adds new datetextfield tag

WW-3493 Adds new datetextfield tag


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/9c9d2b5a
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/9c9d2b5a
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/9c9d2b5a

Branch: refs/heads/feature/use-js-to-support-multiple-buttons
Commit: 9c9d2b5a58f13b0b8704a30e3f53078154a9a6b8
Parents: 86813c1
Author: Lukasz Lenart <lu...@apache.org>
Authored: Thu Mar 27 19:42:35 2014 +0100
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Thu Mar 27 19:42:35 2014 +0100

----------------------------------------------------------------------
 .../struts2/components/DateTextField.java       |  51 +++
 .../interceptor/DateTextFieldInterceptor.java   | 128 +++++++
 .../struts2/views/jsp/ui/DateTextFieldTag.java  |  35 ++
 core/src/main/resources/struts-default.xml      |   4 +
 core/src/site/resources/tags/datetextfield.html | 376 +++++++++++++++++++
 .../DateTextFieldInterceptorTest.java           |  58 +++
 .../views/java/simple/DateTextFieldHandler.java |  91 +++++
 .../struts2/views/java/simple/SimpleTheme.java  |   1 +
 .../views/java/simple/DateTextFieldTest.java    |  51 +++
 9 files changed, 795 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/main/java/org/apache/struts2/components/DateTextField.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/components/DateTextField.java b/core/src/main/java/org/apache/struts2/components/DateTextField.java
new file mode 100644
index 0000000..0fd3614
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/components/DateTextField.java
@@ -0,0 +1,51 @@
+package org.apache.struts2.components;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.views.annotations.StrutsTag;
+import org.apache.struts2.views.annotations.StrutsTagAttribute;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+@StrutsTag(
+    name="datetextfield",
+    tldTagClass="org.apache.struts2.views.jsp.ui.DateTextFieldTag",
+    description="Render an HTML input fields with the date time",
+    allowDynamicAttributes=true)
+public class DateTextField extends UIBean {
+    /**
+     * The name of the default template for the DateTextFieldTag
+     */
+    final public static String TEMPLATE = "datetextfield";
+    
+    protected String format;
+
+    public DateTextField(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
+        super(stack, request, response);
+    }
+
+    protected String getDefaultTemplate() {
+        return TEMPLATE;
+    }
+
+    protected void evaluateExtraParams() {
+        super.evaluateExtraParams();
+
+        if (format != null) {
+            addParameter("format", findValue(format, String.class));
+        }
+    }
+
+    @StrutsTagAttribute(description="Date format attribute", required=true, type="String")
+    public void setFormat(String format) {
+        this.format = format;
+    }
+
+	@SuppressWarnings("unchecked")
+	@Override
+	protected Class getValueClassType() {
+		return null;
+	}
+    
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java
new file mode 100644
index 0000000..f5bda69
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java
@@ -0,0 +1,128 @@
+package org.apache.struts2.interceptor;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.interceptor.Interceptor;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+public class DateTextFieldInterceptor implements Interceptor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DateTextFieldInterceptor.class);
+
+    public static enum DateWord {
+
+		S("millisecond", 3, "SSS"),
+		s("second", 2, "ss"),
+		m("minute", 2, "mm"),
+		H("hour", 2, "HH"),
+		d("day", 2, "dd"),
+		M("month", 2, "MM"),
+		y("year", 4, "yyyy");
+
+		private String description;
+		private Integer length;
+		private String dateType;
+		
+		private DateWord(String n, Integer l, String t) {
+			description = n;
+			length = l;
+			dateType = t;
+		}
+
+        public String getDescription() {
+            return description;
+        }
+
+        public Integer getLength() {
+            return length;
+        }
+
+        public String getDateType() {
+            return dateType;
+        }
+
+        public static DateWord get(Character c) {
+            return valueOf(DateWord.class, c.toString());
+        }
+
+        public static DateWord[] getAll() {
+            return values();
+        }
+    }
+    
+    public void destroy() {
+    }
+
+    public void init() {
+    }
+
+    public String intercept(ActionInvocation ai) throws Exception {
+        Map<String, Object> parameters = ai.getInvocationContext().getParameters();
+        Set<Entry<String, Object>> entries = parameters.entrySet();
+        Map<String, Map<String, String>> dates = new HashMap<String, Map<String,String>>();
+        
+        DateWord[] dateWords = DateWord.getAll();
+
+        // Get all the values of date type
+        for (Iterator<Entry<String, Object>> iterator = entries.iterator(); iterator.hasNext();) {
+            Entry<String, ?> entry = iterator.next();
+            String key = entry.getKey();
+
+            for (DateWord dateWord : dateWords) {
+            	String dateKey = "__" + dateWord.getDescription() + "_";
+            	if (key.startsWith(dateKey)) {
+                    String name = key.substring(dateKey.length());
+
+                    if (entry.getValue() instanceof String[]) {
+                    	String[] values = (String[])entry.getValue();
+                    	if (values.length > 0 && !"".equals(values[0])) {
+                    		iterator.remove();
+                    		Map<String, String> map = dates.get(name);
+                    		if (map == null) {
+                    			map = new HashMap<String, String>();
+                            	dates.put(name, map);
+                    		}
+                            map.put(dateWord.getDateType(), values[0]);
+                    	}
+                    }
+                    break;
+                }
+            }
+        }
+
+        // Create all the date objects
+        Map<String, Date> newParams = new HashMap<String, Date>();
+        Set<Entry<String, Map<String, String>>> dateEntries = dates.entrySet();
+        for (Entry<String, Map<String, String>> dateEntry : dateEntries) {
+        	Set<Entry<String, String>> dateFormatEntries = dateEntry.getValue().entrySet();
+        	String dateFormat = "";
+        	String dateValue = "";
+        	for (Entry<String, String> dateFormatEntry : dateFormatEntries) {
+        		dateFormat += dateFormatEntry.getKey() + "__";
+        		dateValue += dateFormatEntry.getValue() + "__";
+        	}
+            try {
+            	SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
+            	formatter.setLenient(false);
+                Date value = formatter.parse(dateValue);
+                newParams.put(dateEntry.getKey(), value);
+            } catch (ParseException e) {
+            	LOG.warn("Cannot parse the parameter '" + dateEntry.getKey() 
+            			+ "' with format '" + dateFormat + "' and with value '" + dateValue + "'");
+            }
+        }
+        parameters.putAll(newParams);
+
+        return ai.invoke();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java
new file mode 100644
index 0000000..3b3a673
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/DateTextFieldTag.java
@@ -0,0 +1,35 @@
+package org.apache.struts2.views.jsp.ui;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.components.Component;
+import org.apache.struts2.components.DateTextField;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * @see DateTextField
+ */
+public class DateTextFieldTag extends AbstractUITag {
+
+    private static final long serialVersionUID = 5811285953670562288L;
+
+    protected String format;
+    
+    public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
+        return new DateTextField(stack, req, res);
+    }
+
+    protected void populateParams() {
+        super.populateParams();
+
+        DateTextField textField = ((DateTextField) component);
+        textField.setFormat(format);
+    }
+
+	public void setFormat(String format) {
+		this.format = format;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/main/resources/struts-default.xml
----------------------------------------------------------------------
diff --git a/core/src/main/resources/struts-default.xml b/core/src/main/resources/struts-default.xml
index a99a945..5c446b1 100644
--- a/core/src/main/resources/struts-default.xml
+++ b/core/src/main/resources/struts-default.xml
@@ -186,6 +186,7 @@
             <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
             <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
             <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
+            <interceptor name="datetime" class="org.apache.struts2.interceptor.DateTextFieldInterceptor" />
             <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
             <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
             <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />
@@ -198,6 +199,7 @@
                 <interceptor-ref name="servletConfig"/>
                 <interceptor-ref name="prepare"/>
                 <interceptor-ref name="checkbox"/>
+                <interceptor-ref name="datetime"/>
                 <interceptor-ref name="multiselect"/>
                 <interceptor-ref name="actionMappingParams"/>
                 <interceptor-ref name="params">
@@ -255,6 +257,7 @@
                 <interceptor-ref name="alias"/>
                 <interceptor-ref name="i18n"/>
                 <interceptor-ref name="checkbox"/>
+                <interceptor-ref name="datetime"/>
                 <interceptor-ref name="multiselect"/>
                 <interceptor-ref name="params">
                     <param name="excludeParams">^class\..*,^dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,^parameters\..*,^action:.*,^method:.*</param>
@@ -300,6 +303,7 @@
                 <interceptor-ref name="modelDriven"/>
                 <interceptor-ref name="fileUpload"/>
                 <interceptor-ref name="checkbox"/>
+                <interceptor-ref name="datetime"/>
                 <interceptor-ref name="multiselect"/>
                 <interceptor-ref name="staticParams"/>
                 <interceptor-ref name="actionMappingParams"/>

http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/site/resources/tags/datetextfield.html
----------------------------------------------------------------------
diff --git a/core/src/site/resources/tags/datetextfield.html b/core/src/site/resources/tags/datetextfield.html
new file mode 100644
index 0000000..2bfa1fe
--- /dev/null
+++ b/core/src/site/resources/tags/datetextfield.html
@@ -0,0 +1,376 @@
+<!--
+This file is generated during the build by processing Component class annotations.
+Please do not edit it directly.
+-->
+<html>
+    <head>
+		<title>datetextfield</title>
+	</head>
+
+	<body>
+		<h1>Tag Name: datetextfield</h1>
+		<h2>Description</h2>
+		<p>
+		<!-- START SNIPPET: tagdescription -->
+		Render an HTML input fields with the date time
+		<!-- END SNIPPET: tagdescription -->
+		</p>
+
+		<h2>Attributes</h2>
+		<!-- START SNIPPET: tagattributes -->
+		<table width="100%">
+			<tr>
+				<td colspan="6"><h4>Dynamic Attributes Allowed:</h4> true</td>
+			</tr>
+			<tr>
+				<td colspan="6">&nbsp;</td>
+			</tr>
+			<tr>
+				<th align="left" valign="top"><h4>Name</h4></th>
+				<th align="left" valign="top"><h4>Required</h4></th>
+				<th align="left" valign="top"><h4>Default</h4></th>
+				<th align="left" valign="top"><h4>Evaluated</h4></th>
+				<th align="left" valign="top"><h4>Type</h4></th>
+				<th align="left" valign="top"><h4>Description</h4></th>
+			</tr>
+				<tr>
+					<td align="left" valign="top">accesskey</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html accesskey attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">cssClass</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">The css class to use for element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">cssErrorClass</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">The css error class to use for element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">cssErrorStyle</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">The css error style definitions for element to use</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">cssStyle</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">The css style definitions for element to use</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">disabled</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html disabled attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">errorPosition</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Define error position of form element (top|bottom)</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">format</td>
+					<td align="left" valign="top"><strong>true</strong></td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Date format attribute</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">id</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">HTML id attribute</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">javascriptTooltip</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">Boolean</td>
+					<td align="left" valign="top">Use JavaScript to generate tooltips</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">key</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the key (name, value, label) for this particular component</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">label</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Label expression used for rendering an element specific label</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">labelSeparator</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">:</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">String that will be appended to the label</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">labelposition</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Define label position of form element (top/left)</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">name</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">The name to set for element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onblur</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top"> Set the html onblur attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onchange</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onchange attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onclick</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onclick attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">ondblclick</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html ondblclick attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onfocus</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onfocus attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onkeydown</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onkeydown attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onkeypress</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onkeypress attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onkeyup</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onkeyup attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onmousedown</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onmousedown attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onmousemove</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onmousemove attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onmouseout</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onmouseout attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onmouseover</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onmouseover attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onmouseup</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onmouseup attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">onselect</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html onselect attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">requiredLabel</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">Boolean</td>
+					<td align="left" valign="top">If set to true, the rendered element will indicate that input is required</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">requiredPosition</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Define required position of required form element (left|right)</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">tabindex</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html tabindex attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">template</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">The template (other than default) to use for rendering the element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">templateDir</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">The template directory.</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">theme</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">The theme (other than default) to use for rendering the element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">title</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the html title attribute on rendered html element</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">tooltip</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Set the tooltip of this particular component</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">tooltipConfig</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Deprecated. Use individual tooltip configuration attributes instead.</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">tooltipCssClass</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">StrutsTTClassic</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">CSS class applied to JavaScrip tooltips</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">tooltipDelay</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">Classic</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Delay in milliseconds, before showing JavaScript tooltips </td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">tooltipIconPath</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Icon path used for image that will have the tooltip</td>
+				</tr>
+				<tr>
+					<td align="left" valign="top">value</td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top"></td>
+					<td align="left" valign="top">false</td>
+					<td align="left" valign="top">String</td>
+					<td align="left" valign="top">Preset the value of input element.</td>
+				</tr>
+		</table>
+		<!-- END SNIPPET: tagattributes -->
+	</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java
new file mode 100644
index 0000000..e146239
--- /dev/null
+++ b/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java
@@ -0,0 +1,58 @@
+package org.apache.struts2.interceptor;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.struts2.StrutsInternalTestCase;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.mock.MockActionInvocation;
+
+/**
+ * Unit test for DateTextFieldInterceptor. 
+ */
+public class DateTextFieldInterceptorTest extends StrutsInternalTestCase {
+
+    private DateTextFieldInterceptor interceptor;
+    private MockActionInvocation ai;
+    private Map<String, Object> param;
+    
+    protected void setUp() throws Exception {
+    	super.setUp();
+    	param = new HashMap<String, Object>();
+    	
+    	interceptor = new DateTextFieldInterceptor();
+    	ai = new MockActionInvocation();
+    	ai.setInvocationContext(ActionContext.getContext());
+    	ActionContext.getContext().setParameters(param);
+    }
+	
+	public void testNoParam() throws Exception {
+		interceptor.init();
+		interceptor.intercept(ai);
+		interceptor.destroy();
+
+		assertEquals(0, param.size());
+	}
+
+	public void testOneDateTextField() throws Exception {
+		param.put("__year_name", new String[]{"2000"});
+		param.put("__month_name", new String[]{"06"});
+		param.put("__day_name", new String[]{"15"});
+
+		interceptor.init();
+		interceptor.intercept(ai);
+		interceptor.destroy();
+		
+		assertFalse(param.containsKey("__year_name"));
+		assertFalse(param.containsKey("__month_name"));
+		assertFalse(param.containsKey("__day_name"));
+		assertTrue(param.containsKey("name"));
+		assertEquals(1, param.size());
+		Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2000-06-15"); 
+		assertEquals(date, param.get("name"));
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/DateTextFieldHandler.java
----------------------------------------------------------------------
diff --git a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/DateTextFieldHandler.java b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/DateTextFieldHandler.java
new file mode 100644
index 0000000..80aed25
--- /dev/null
+++ b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/DateTextFieldHandler.java
@@ -0,0 +1,91 @@
+package org.apache.struts2.views.java.simple;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.struts2.interceptor.DateTextFieldInterceptor.DateWord;
+import org.apache.struts2.views.java.Attributes;
+import org.apache.struts2.views.java.TagGenerator;
+
+
+public class DateTextFieldHandler extends AbstractTagHandler implements TagGenerator {
+
+    @SuppressWarnings("unchecked")
+	public void generate() throws IOException {
+        Map<String, Object> params = context.getParameters();
+        Attributes attr = null;
+
+        // Get format
+        String format = (String)params.get("format");
+        String id = (String)params.get("id");
+        String name = (String)params.get("name");
+        if (id == null) {
+        	id = name;
+        }
+        Date date = (Date)params.get("nameValue");
+        
+        if (format != null) {
+        	// Verify if it's correct
+            new SimpleDateFormat(format);
+            
+            attr = new Attributes();
+            attr.addIfExists("id", id);
+            super.start("div", attr);
+            
+            Character antC = null;
+            for (Character c : format.toCharArray()) {
+            	
+            	try {
+            		DateWord dateWord = DateWord.get(c);
+            		if (!c.equals(antC)) {
+            			
+            			String cssClass = "date_" + dateWord.getDescription();
+            			if (params.get("cssClass") != null) {
+            				cssClass += " " + params.get("cssClass");
+            			}
+            			
+            			attr = new Attributes();
+            	        attr.add("type", "text")
+            	                .addIfExists("class", cssClass)
+            	                .addIfExists("size", dateWord.getLength())
+            	                .addIfExists("maxlength", dateWord.getLength())
+            	                .addIfTrue("disabled", params.get("disabled"))
+            	                .addIfTrue("readonly", params.get("readonly"))
+            	                .addIfExists("tabindex", params.get("tabindex"))
+            	                .addIfExists("style", params.get("cssStyle"))
+            	                .addIfExists("title", params.get("title"));
+            	        
+            	        if (id != null && !"".equals(id)) {
+                	        attr.addDefaultToEmpty("id", "__" + dateWord.getDescription() + "_" + id);
+            	        }
+            	        if (name != null && !"".equals(id)) {
+                	        attr.addDefaultToEmpty("name", "__" + dateWord.getDescription() + "_" + name);
+            	        } else {
+                	        attr.addDefaultToEmpty("name", dateWord.getDescription());
+            	        }
+            	        if (date != null) {
+            	        	SimpleDateFormat formatter = new SimpleDateFormat(dateWord.getDateType());
+            	        	attr.addIfExists("value", formatter.format(date), false);
+            	        }
+            	        
+            	        super.start("input", attr);
+            	        super.end("input");
+            	        
+            		}
+            	} catch (IllegalArgumentException e) {
+            		super.characters(c.toString());	
+            	}
+            	antC = c;
+            
+            }
+            super.end("div");
+        }
+        
+    }
+    
+    
+    
+}
+

http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/SimpleTheme.java
----------------------------------------------------------------------
diff --git a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/SimpleTheme.java b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/SimpleTheme.java
index 363717b..4c9ba29 100644
--- a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/SimpleTheme.java
+++ b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/SimpleTheme.java
@@ -36,6 +36,7 @@ public class SimpleTheme extends DefaultTheme {
             {
                 put("text", new FactoryList(TextFieldHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class, DynamicAttributesHandler.class));
                 put("textfield", new FactoryList(TextFieldHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class, DynamicAttributesHandler.class));
+                put("datetextfield", new FactoryList(DateTextFieldHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class));
                 put("select", new FactoryList(SelectHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class, DynamicAttributesHandler.class));
                 put("form", new FactoryList(FormHandler.class, ScriptingEventsHandler.class, CommonAttributesHandler.class, DynamicAttributesHandler.class));
                 put("form-close", new FactoryList(FormHandler.CloseHandler.class));

http://git-wip-us.apache.org/repos/asf/struts/blob/9c9d2b5a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
----------------------------------------------------------------------
diff --git a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
new file mode 100644
index 0000000..7c03a65
--- /dev/null
+++ b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
@@ -0,0 +1,51 @@
+package org.apache.struts2.views.java.simple;
+
+import org.apache.struts2.components.DateTextField;
+import org.apache.struts2.components.UIBean;
+
+public class DateTextFieldTest extends AbstractCommonAttributesTest {
+
+    private DateTextField tag;
+
+    public void testRenderDateTextField() {
+    	tag.setId("id");
+        tag.setName("name");
+        tag.setFormat("yyyy-MM-dd");
+
+        tag.evaluateParams();
+        map.putAll(tag.getParameters());
+        theme.renderTag(getTagName(), context);
+        String output = writer.getBuffer().toString();
+        String expected = s("<div id='id'>" +
+        		"<input type='text' class='date_year' size='4' maxlength='4' id='__year_id' name='__year_name'></input>" +
+        		"-<input type='text' class='date_month' size='2' maxlength='2' id='__month_id' name='__month_name'></input>" +
+        		"-<input type='text' class='date_day' size='2' maxlength='2' id='__day_id' name='__day_name'></input></div>");
+        assertEquals(expected, output);
+    }
+    
+    @Override
+    public void testRenderTextFieldScriptingAttrs() throws Exception { }
+    
+    @Override
+    public void testRenderTextFieldCommonAttrs() throws Exception { }
+
+    @Override
+    public void testRenderTextFieldDynamicAttrs() throws Exception { }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        this.tag = new DateTextField(stack, request, response);
+    }
+
+    @Override
+    protected UIBean getUIBean() {
+        return tag;
+    }
+
+    @Override
+    protected String getTagName() {
+        return "datetextfield";
+    }
+
+}