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