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/develop Commit: 9c9d2b5a58f13b0b8704a30e3f53078154a9a6b8 Parents: 86813c1 Author: Lukasz Lenart <lukaszlen...@apache.org> Authored: Thu Mar 27 19:42:35 2014 +0100 Committer: Lukasz Lenart <lukaszlen...@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"> </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"; + } + +}