1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2.components;
22
23 import java.text.ParseException;
24 import java.text.SimpleDateFormat;
25 import java.util.Date;
26
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletResponse;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.struts2.views.annotations.StrutsTag;
33 import org.apache.struts2.views.annotations.StrutsTagAttribute;
34
35 import com.opensymphony.xwork2.util.ValueStack;
36
37 /***
38 * <!-- START SNIPPET: javadoc -->
39 * <p>
40 * Renders a date/time picker in a dropdown container.
41 * </p>
42 * <p>
43 * A stand-alone DateTimePicker widget that makes it easy to select a date/time, or increment by week, month,
44 * and/or year.
45 * </p>
46 *
47 * <p>
48 * It is possible to customize the user-visible formatting with either the
49 * 'formatLength' (long, short, medium or full) or 'displayFormat' attributes. By defaulty current
50 * locale will be used.</p>
51 * </p>
52 *
53 * Syntax supported by 'displayFormat' is (http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns):-
54 * <table border="1">
55 * <tr>
56 * <td>Format</td>
57 * <td>Description</td>
58 * </tr>
59 * <tr>
60 * <td>d</td>
61 * <td>Day of the month</td>
62 * </tr>
63 * <tr>
64 * <td>D</td>
65 * <td>Day of year</td>
66 * </tr>
67 * <tr>
68 * <td>M</td>
69 * <td>Month - Use one or two for the numerical month, three for the abbreviation, or four for the full name, or 5 for the narrow name.</td>
70 * </tr>
71 * <tr>
72 * <td>h</td>
73 * <td>Hour [1-12].</td>
74 * </tr>
75 * <tr>
76 * <td>H</td>
77 * <td>Hour [0-23].</td>
78 * </tr>
79 * <tr>
80 * <td>m</td>
81 * <td>Minute. Use one or two for zero padding.</td>
82 * </tr>
83 * <tr>
84 * <td>s</td>
85 * <td>Second. Use one or two for zero padding.</td>
86 * </tr>
87 * </table>
88 *
89 * <p>
90 * The value sent to the server is
91 * typically a locale-independent value in a hidden field as defined by the name
92 * attribute. RFC3339 representation is the format used.
93 * </p>
94 *
95 * <p/>
96 *
97 * <!-- END SNIPPET: javadoc -->
98 *
99 * <b>Examples</b>
100 *
101 * <pre>
102 * <!-- START SNIPPET: expl1 -->
103 *
104 * Example 1:
105 * <s:datetimepicker name="order.date" label="Order Date" />
106 * Example 2:
107 * <s:datetimepicker name="delivery.date" label="Delivery Date" format="yyyy-MM-dd" />
108 *
109 * <!-- END SNIPPET: expl1 -->
110 * </pre>
111 * <p/>
112 *
113 * <!-- START SNIPPET: expldesc2 -->
114 *
115 * The css could be changed by using the following :-
116 *
117 * <!-- END SNIPPET: expldesc2 -->
118 *
119 * <pre>
120 * <!-- START SNIPPET: expl2 -->
121 *
122 * <s:datetimepicker name="birthday" label="Birthday" templateCss="...." />
123 *
124 * <!-- END SNIPPET: expl2 -->
125 * </pre>
126 *
127 */
128 @StrutsTag(name="datetimepicker", tldTagClass="org.apache.struts2.views.jsp.ui.DateTimePickerTag", description="Render datetimepicker")
129 public class DateTimePicker extends UIBean {
130
131 final public static String TEMPLATE = "datetimepicker";
132 final private static SimpleDateFormat RFC3339_FORMAT = new SimpleDateFormat(
133 "yyyy-MM-dd'T'HH:mm:ss");
134 final protected static Log LOG = LogFactory.getLog(DateTimePicker.class);
135
136 protected String iconPath;
137 protected String formatLength;
138 protected String displayFormat;
139 protected String toggleType;
140 protected String toggleDuration;
141 protected String type;
142
143 protected String displayWeeks;
144 protected String adjustWeeks;
145 protected String startDate;
146 protected String endDate;
147 protected String weekStartsOn;
148 protected String staticDisplay;
149 protected String dayWidth;
150 protected String language;
151 protected String templateCssPath;
152
153 public DateTimePicker(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
154 super(stack, request, response);
155 }
156
157 protected String getDefaultTemplate() {
158 return TEMPLATE;
159 }
160
161 public void evaluateParams() {
162 super.evaluateParams();
163
164 if(displayWeeks != null)
165 addParameter("displayWeeks", findString(displayWeeks));
166 if(adjustWeeks != null)
167 addParameter("adjustWeeks", findValue(adjustWeeks, Boolean.class));
168 if(startDate != null)
169 addParameter("startDate", findString(startDate));
170 if(endDate != null)
171 addParameter("endDate", findString(endDate));
172 if(weekStartsOn != null)
173 addParameter("weekStartsOn", findString(weekStartsOn));
174 if(staticDisplay != null)
175 addParameter("staticDisplay", findValue(staticDisplay, Boolean.class));
176 if(dayWidth != null)
177 addParameter("dayWidth", findValue(dayWidth, Integer.class));
178 if(language != null)
179 addParameter("language", findString(language));
180 if(value != null)
181 addParameter("value", findString(value));
182 if(iconPath != null)
183 addParameter("iconPath", findString(iconPath));
184 if(formatLength != null)
185 addParameter("formatLength", findString(formatLength));
186 if(displayFormat != null)
187 addParameter("displayFormat", findString(displayFormat));
188 if(toggleType != null)
189 addParameter("toggleType", findString(toggleType));
190 if(toggleDuration != null)
191 addParameter("toggleDuration", findValue(toggleDuration,
192 Integer.class));
193 if(type != null)
194 addParameter("type", findString(type));
195 else
196 addParameter("type", "date");
197 if(templateCssPath != null)
198 addParameter("templateCssPath", findString(templateCssPath));
199
200
201 if(parameters.containsKey("value")) {
202 parameters.put("nameValue", format(parameters.get("value")));
203 } else {
204 if(name != null) {
205 String expr = name;
206 if(altSyntax()) {
207 expr = "%{" + expr + "}";
208 }
209 addParameter("nameValue", format(findValue(expr)));
210 }
211 }
212 }
213
214 @StrutsTagAttribute(description="If true, weekly size of calendar changes to acomodate the month if false," +
215 " 42 day format is used", type="Boolean", defaultValue="false")
216 public void setAdjustWeeks(String adjustWeeks) {
217 this.adjustWeeks = adjustWeeks;
218 }
219
220 @StrutsTagAttribute(description="How to render the names of the days in the header(narrow, abbr or wide)", defaultValue="narrow")
221 public void setDayWidth(String dayWidth) {
222 this.dayWidth = dayWidth;
223 }
224
225 @StrutsTagAttribute(description="Total weeks to display", type="Integer", defaultValue="6")
226 public void setDisplayWeeks(String displayWeeks) {
227 this.displayWeeks = displayWeeks;
228 }
229
230 @StrutsTagAttribute(description="Last available date in the calendar set", type="Date", defaultValue="2941-10-12")
231 public void setEndDate(String endDate) {
232 this.endDate = endDate;
233 }
234
235 @StrutsTagAttribute(description="First available date in the calendar set", type="Date", defaultValue="1492-10-12")
236 public void setStartDate(String startDate) {
237 this.startDate = startDate;
238 }
239
240 @StrutsTagAttribute(description="Disable all incremental controls, must pick a date in the current display", type="Boolean", defaultValue="false")
241 public void setStaticDisplay(String staticDisplay) {
242 this.staticDisplay = staticDisplay;
243 }
244
245 @StrutsTagAttribute(description="Adjusts the first day of the week 0==Sunday..6==Saturday", type="Integer", defaultValue="0")
246 public void setWeekStartsOn(String weekStartsOn) {
247 this.weekStartsOn = weekStartsOn;
248 }
249
250 @StrutsTagAttribute(description="Language to display this widget in", defaultValue="brower's specified preferred language")
251 public void setLanguage(String language) {
252 this.language = language;
253 }
254
255 @StrutsTagAttribute(description="A pattern used for the visual display of the formatted date, e.g. dd/MM/yyyy")
256 public void setDisplayFormat(String displayFormat) {
257 this.displayFormat = displayFormat;
258 }
259
260 @StrutsTagAttribute(description="Type of formatting used for visual display. Possible values are " +
261 "long, short, medium or full", defaultValue="short")
262 public void setFormatLength(String formatLength) {
263 this.formatLength = formatLength;
264 }
265
266 @StrutsTagAttribute(description="Path to icon used for the dropdown")
267 public void setIconPath(String iconPath) {
268 this.iconPath = iconPath;
269 }
270
271 @StrutsTagAttribute(description="Duration of toggle in milliseconds", type="Integer", defaultValue="100")
272 public void setToggleDuration(String toggleDuration) {
273 this.toggleDuration = toggleDuration;
274 }
275
276 @StrutsTagAttribute(description="Defines the type of the picker on the dropdown. Possible values are 'date'" +
277 " for a DateTimePicker, and 'time' for a timePicker", defaultValue="date")
278 public void setType(String type) {
279 this.type = type;
280 }
281
282 @StrutsTagAttribute(description="oggle type of the dropdown. Possible values are plain,wipe,explode,fade", defaultValue="plain")
283 public void setToggleType(String toggleType) {
284 this.toggleType = toggleType;
285 }
286
287 @StrutsTagAttribute(description="Template css path")
288 public void setTemplateCssPath(String templateCssPath) {
289 this.templateCssPath = templateCssPath;
290 }
291
292 private String format(Object obj) {
293 if(obj == null)
294 return null;
295
296 if(obj instanceof Date) {
297 return RFC3339_FORMAT.format((Date) obj);
298 } else {
299
300 String dateStr = obj.toString();
301 if(dateStr.equalsIgnoreCase("today"))
302 return RFC3339_FORMAT.format(new Date());
303
304 try {
305 Date date = null;
306 if(this.displayFormat != null) {
307 SimpleDateFormat format = new SimpleDateFormat(
308 (String) getParameters().get("displayFormat"));
309 date = format.parse(dateStr);
310 return RFC3339_FORMAT.format(date);
311 } else {
312
313 return dateStr;
314 }
315 } catch (ParseException e) {
316 LOG.error("Could not parse date", e);
317 return dateStr;
318 }
319 }
320 }
321
322 }