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 RFC3399_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
150 public DateTimePicker(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
151 super(stack, request, response);
152 }
153
154 protected String getDefaultTemplate() {
155 return TEMPLATE;
156 }
157
158 public void evaluateParams() {
159 super.evaluateParams();
160
161 if(displayWeeks != null)
162 addParameter("displayWeeks", findString(displayWeeks));
163 if(adjustWeeks != null)
164 addParameter("adjustWeeks", findValue(adjustWeeks, Boolean.class));
165 if(startDate != null)
166 addParameter("startDate", findString(startDate));
167 if(endDate != null)
168 addParameter("endDate", findString(endDate));
169 if(weekStartsOn != null)
170 addParameter("weekStartsOn", findString(weekStartsOn));
171 if(staticDisplay != null)
172 addParameter("staticDisplay", findValue(staticDisplay, Boolean.class));
173 if(dayWidth != null)
174 addParameter("dayWidth", findValue(dayWidth, Integer.class));
175 if(language != null)
176 addParameter("language", findString(language));
177 if(value != null)
178 addParameter("value", findString(value));
179 if(iconPath != null)
180 addParameter("iconPath", iconPath);
181 if(formatLength != null)
182 addParameter("formatLength", findString(formatLength));
183 if(displayFormat != null)
184 addParameter("displayFormat", findString(displayFormat));
185 if(toggleType != null)
186 addParameter("toggleType", findString(toggleType));
187 if(toggleDuration != null)
188 addParameter("toggleDuration", findValue(toggleDuration,
189 Integer.class));
190 if(type != null)
191 addParameter("type", findString(type));
192 else
193 addParameter("type", "date");
194
195
196 if(parameters.containsKey("value")) {
197 parameters.put("nameValue", format(parameters.get("value")));
198 } else {
199 if(name != null) {
200 String expr = name;
201 if(altSyntax()) {
202 expr = "%{" + expr + "}";
203 }
204 addParameter("nameValue", format(findValue(expr)));
205 }
206 }
207 }
208
209 @StrutsTagAttribute(description="If true, weekly size of calendar changes to acomodate the month if false," +
210 " 42 day format is used", type="Boolean", defaultValue="false")
211 public void setAdjustWeeks(String adjustWeeks) {
212 this.adjustWeeks = adjustWeeks;
213 }
214
215 @StrutsTagAttribute(description="How to render the names of the days in the header(narrow, abbr or wide)", defaultValue="narrow")
216 public void setDayWidth(String dayWidth) {
217 this.dayWidth = dayWidth;
218 }
219
220 @StrutsTagAttribute(description="Total weeks to display", type="Integer", defaultValue="6")
221 public void setDisplayWeeks(String displayWeeks) {
222 this.displayWeeks = displayWeeks;
223 }
224
225 @StrutsTagAttribute(description="Last available date in the calendar set", type="Date", defaultValue="2941-10-12")
226 public void setEndDate(String endDate) {
227 this.endDate = endDate;
228 }
229
230 @StrutsTagAttribute(description="First available date in the calendar set", type="Date", defaultValue="1492-10-12")
231 public void setStartDate(String startDate) {
232 this.startDate = startDate;
233 }
234
235 @StrutsTagAttribute(description="Disable all incremental controls, must pick a date in the current display", type="Boolean", defaultValue="false")
236 public void setStaticDisplay(String staticDisplay) {
237 this.staticDisplay = staticDisplay;
238 }
239
240 @StrutsTagAttribute(description="Adjusts the first day of the week 0==Sunday..6==Saturday", type="Integer", defaultValue="0")
241 public void setWeekStartsOn(String weekStartsOn) {
242 this.weekStartsOn = weekStartsOn;
243 }
244
245 @StrutsTagAttribute(description="Language to display this widget in", defaultValue="brower's specified preferred language")
246 public void setLanguage(String language) {
247 this.language = language;
248 }
249
250 @StrutsTagAttribute(description="A pattern used for the visual display of the formatted date, e.g. dd/MM/yyyy")
251 public void setDisplayFormat(String displayFormat) {
252 this.displayFormat = displayFormat;
253 }
254
255 @StrutsTagAttribute(description="Type of formatting used for visual display. Possible values are " +
256 "long, short, medium or full", defaultValue="short")
257 public void setFormatLength(String formatLength) {
258 this.formatLength = formatLength;
259 }
260
261 @StrutsTagAttribute(description=" Path to icon used for the dropdown")
262 public void setIconPath(String iconPath) {
263 this.iconPath = iconPath;
264 }
265
266 @StrutsTagAttribute(description="Duration of toggle in milliseconds", type="Integer", defaultValue="100")
267 public void setToggleDuration(String toggleDuration) {
268 this.toggleDuration = toggleDuration;
269 }
270
271 @StrutsTagAttribute(description="Defines the type of the picker on the dropdown. Possible values are 'date'" +
272 " for a DateTimePicker, and 'time' for a timePicker", defaultValue="date")
273 public void setType(String type) {
274 this.type = type;
275 }
276
277 @StrutsTagAttribute(description="oggle type of the dropdown. Possible values are plain,wipe,explode,fade", defaultValue="plain")
278 public void setToggleType(String toggleType) {
279 this.toggleType = toggleType;
280 }
281
282 private String format(Object obj) {
283 if(obj == null)
284 return null;
285
286 if(obj instanceof Date) {
287 return RFC3399_FORMAT.format((Date) obj);
288 } else {
289
290 String dateStr = obj.toString();
291 if(dateStr.equalsIgnoreCase("today"))
292 return RFC3399_FORMAT.format(new Date());
293
294 try {
295 Date date = null;
296 if(this.displayFormat != null) {
297 SimpleDateFormat format = new SimpleDateFormat(
298 this.displayFormat);
299 date = format.parse(dateStr);
300 return RFC3399_FORMAT.format(date);
301 } else {
302
303 return dateStr;
304 }
305 } catch (ParseException e) {
306 LOG.error("Could not parse date", e);
307 return dateStr;
308 }
309 }
310 }
311
312 }