1 package org.apache.turbine.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.text.DateFormatSymbols;
23 import java.util.Calendar;
24 import java.util.Date;
25
26 import org.apache.ecs.ConcreteElement;
27 import org.apache.ecs.ElementContainer;
28 import org.apache.ecs.html.Input;
29 import org.apache.ecs.html.Option;
30 import org.apache.ecs.html.Select;
31
32 /***
33 * DateSelector is a utility class to handle the creation of a set of
34 * date popup menus. The code is broken into a set of static methods
35 * for quick and easy access to the individual select objects:
36 *
37 * <pre>
38 * ElementContainer ec dateSelect = new ElementContainer();
39 * String myName = "mydate";
40 * ec.addElement(DateSelector.getMonthSelector(myName));
41 * ec.addElement(DateSelector.getDaySelector(myName));
42 * ec.addElement(DateSelector.getYearSelector(myName));
43 * </pre>
44 *
45 * There are also methods which will use attributes to build a
46 * complete month,day,year selector:
47 *
48 * <pre>
49 * DateSelector ds = new DateSelector(myName);
50 * dateSelect = ds.ecsOutput();
51 * </pre>
52 *
53 * The above element container would use the onChange setting and may
54 * hide the selected day if set via showDays().<br>
55 *
56 * @author <a href="mailto:ekkerbj@netscape.net">Jeffrey D. Brekke</a>
57 * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
58 * @author <a href="mailto:leon@clearink.com">Leon Atkinson</a>
59 * @version $Id: DateSelector.java 534527 2007-05-02 16:10:59Z tv $
60 */
61 public class DateSelector
62 {
63 /*** Prefix for date names. */
64 public static final String DEFAULT_PREFIX = "DateSelector";
65
66 /*** Suffix for day parameter. */
67 public static final String DAY_SUFFIX = "_day";
68
69 /*** Suffix for month parameter. */
70 public static final String MONTH_SUFFIX = "_month";
71
72 /*** Suffix for year parameter. */
73 public static final String YEAR_SUFFIX = "_year";
74
75 private Calendar useDate = null;
76 private String selName = null;
77 private static final String[] monthName =
78 new DateFormatSymbols().getMonths();
79 private String onChange = null;
80 private boolean onChangeSet = false;
81 private boolean showDays = true;
82 private int setDay = 0;
83 private boolean useYears = false;
84 private int firstYear = 0;
85 private int lastYear = 0;
86 private int selectedYear = 0;
87
88 /***
89 * Constructor defaults to current date and uses the default
90 * prefix: <pre>DateSelector.DEFAULT</pre>
91 */
92 public DateSelector()
93 {
94 this.selName = DEFAULT_PREFIX;
95 this.useDate = Calendar.getInstance();
96 this.useDate.setTime(new Date());
97 }
98
99 /***
100 * Constructor, uses the date set in a calendar that has been
101 * already passed in (with the date set correctly).
102 *
103 * @param selName A String with the selector name.
104 * @param useDate A Calendar with a date.
105 */
106 public DateSelector(String selName, Calendar useDate)
107 {
108 this.useDate = useDate;
109 this.selName = selName;
110 }
111
112 /***
113 * Constructor defaults to current date.
114 *
115 * @param selName A String with the selector name.
116 */
117 public DateSelector(String selName)
118 {
119 this.selName = selName;
120 this.useDate = Calendar.getInstance();
121 this.useDate.setTime(new Date());
122 }
123
124 /***
125 * Adds the onChange to all of <SELECT> tags. This is limited to
126 * one function for all three popups and is only used when the
127 * output() methods are used. Individual getMonth, getDay,
128 * getYear static methods will not use this setting.
129 *
130 * @param string A String to use for onChange attribute. If null,
131 * then nothing will be set.
132 * @return A DateSelector (self).
133 */
134 public DateSelector setOnChange(String onChange)
135 {
136 if (onChange != null)
137 {
138 this.onChange = onChange;
139 this.onChangeSet = true;
140 }
141 else
142 {
143 this.onChange = null;
144 this.onChangeSet = false;
145 }
146 return this;
147 }
148
149 /***
150 * Select the day to be selected if the showDays(false) behavior
151 * is used. Individual getMonth, getDay, getYear static methods
152 * will not use this setting.
153 *
154 * @param day The day.
155 * @return A DateSelector (self).
156 */
157 public DateSelector setDay(int day)
158 {
159 this.setDay = day;
160 this.showDays = false;
161 return this;
162 }
163
164 /***
165 * Whether or not to show the days as a popup menu. The days will
166 * be a hidden parameter and the value set with setDay is used.
167 * Individual getMonth, getDay, getYear static methods will not
168 * use this setting.
169 *
170 * @param show True if the day should be shown.
171 * @return A DateSelector (self).
172 */
173 public DateSelector setShowDay(boolean show)
174 {
175 this.showDays = false;
176 return this;
177 }
178
179 /***
180 * Set the selector name prefix. Individual getMonth, getDay,
181 * getYear static methods will not use this setting.
182 *
183 * @param selname A String with the select name prefix.
184 */
185 public void setSelName(String selName)
186 {
187 this.selName = selName;
188 }
189
190 /***
191 * Get the selector name prefix.
192 *
193 * @return A String with the select name prefix.
194 */
195 public String getSelName()
196 {
197 return selName;
198 }
199
200 /***
201 * Return a month selector.
202 *
203 * @param name The name to use for the selected month.
204 * @return A select object with all the months.
205 */
206 public static Select getMonthSelector(String name)
207 {
208 return (getMonthSelector(name, Calendar.getInstance()));
209 }
210
211 /***
212 * Return a month selector.
213 *
214 * Note: The values of the month placed into the select list are
215 * the month integers starting at 0 (ie: if the user selects
216 * February, the selected value will be 1).
217 *
218 * @param name The name to use for the selected month.
219 * @param now Calendar to start with.
220 * @return A select object with all the months.
221 */
222 public static Select getMonthSelector(String name, Calendar now)
223 {
224 Select monthSelect = new Select().setName(name);
225
226 for (int curMonth = 0; curMonth <= 11; curMonth++)
227 {
228 Option o = new Option();
229 o.addElement(monthName[curMonth]);
230 o.setValue(curMonth);
231 if ((now.get(Calendar.MONTH)) == curMonth)
232 {
233 o.setSelected(true);
234 }
235 monthSelect.addElement(o);
236 }
237 return (monthSelect);
238 }
239
240 /***
241 * Return a day selector.
242 *
243 * @param name The name to use for the selected day.
244 * @return A select object with all the days in a month.
245 */
246 public static Select getDaySelector(String name)
247 {
248 return (getDaySelector(name, Calendar.getInstance()));
249 }
250
251 /***
252 * Return a day selector.
253 *
254 * @param name The name to use for the selected day.
255 * @param now Calendar to start with.
256 * @return A select object with all the days in a month.
257 */
258 public static Select getDaySelector(String name, Calendar now)
259 {
260 Select daySelect = new Select().setName(name);
261
262 for (int currentDay = 1; currentDay <= 31; currentDay++)
263 {
264 Option o = new Option();
265 o.addElement(Integer.toString(currentDay));
266 o.setValue(currentDay);
267 if (now.get(Calendar.DAY_OF_MONTH) == currentDay)
268 {
269 o.setSelected(true);
270 }
271 daySelect.addElement(o);
272 }
273 return (daySelect);
274 }
275
276 /***
277 * Return a year selector.
278 *
279 * @param name The name to use for the selected year.
280 * @return A select object with all the years starting five years
281 * from now and five years before this year.
282 */
283 public static Select getYearSelector(String name)
284 {
285 return (getYearSelector(name, Calendar.getInstance()));
286 }
287
288 /***
289 * Return a year selector.
290 *
291 * @param name The name to use for the selected year.
292 * @param now Calendar to start with.
293 * @return A select object with all the years starting five years
294 * from now and five years before this year.
295 */
296 public static Select getYearSelector(String name, Calendar now)
297 {
298 int startYear = now.get(Calendar.YEAR);
299 return (getYearSelector(name, startYear - 5, startYear + 5, startYear));
300 }
301
302 /***
303 * Return a year selector.
304 *
305 * @param name The name to use for the selected year.
306 * @param firstYear the first (earliest) year in the selector.
307 * @param lastYear the last (latest) year in the selector.
308 * @param selectedYear the year initially selected in the Select html.
309 * @return A select object with all the years from firstyear
310 * to lastyear..
311 */
312 public static Select getYearSelector(String name,
313 int firstYear, int lastYear,
314 int selectedYear)
315 {
316 Select yearSelect = new Select().setName(name);
317
318 for (int currentYear = firstYear;
319 currentYear <= lastYear;
320
321 currentYear++)
322 {
323 Option o = new Option();
324 o.addElement(Integer.toString(currentYear));
325 o.setValue(currentYear);
326 if (currentYear == selectedYear)
327 {
328 o.setSelected(true);
329 }
330 yearSelect.addElement(o);
331 }
332 return (yearSelect);
333 }
334
335 /***
336 * Select the day to be selected if the showDays(false) behavior
337 * is used. Individual getMonth, getDay, getYear static methods
338 * will not use this setting.
339 *
340 * @param day The day.
341 * @return A DateSelector (self).
342 */
343 public boolean setYear(int firstYear, int lastYear, int selectedYear)
344 {
345 if (firstYear <= lastYear && firstYear <= selectedYear
346 && selectedYear <= lastYear)
347 {
348 this.useYears = true;
349 this.firstYear = firstYear;
350 this.lastYear = lastYear;
351 this.selectedYear = selectedYear;
352 return true;
353 }
354 else
355 {
356 return false;
357 }
358 }
359
360 /***
361 * Used to build the popupmenu in HTML. The properties set in the
362 * object are used to generate the correct HTML. The selName
363 * attribute is used to seed the names of the select lists. The
364 * names will be generated as follows:
365 *
366 * <ul>
367 * <li>selName + "_month"</li>
368 * <li>selName + "_day"</li>
369 * <li>selName + "_year"</li>
370 * </ul>
371 *
372 * If onChange was set it is also used in the generation of the
373 * output. The output HTML will list the select lists in the
374 * following order: month day year.
375 *
376 * @return A String with the correct HTML for the date selector.
377 */
378 public String output()
379 {
380 return (ecsOutput().toString());
381 }
382
383 /***
384 * Used to build the popupmenu in HTML. The properties set in the
385 * object are used to generate the correct HTML. The selName
386 * attribute is used to seed the names of the select lists. The
387 * names will be generated as follows:
388 *
389 * <ul>
390 * <li>selName + "_month"</li>
391 * <li>selName + "_day"</li>
392 * <li>selName + "_year"</li>
393 * </ul>
394 *
395 * The output HTML will list the select lists in the following
396 * order: month day year.
397 *
398 * @return A String with the correct HTML for the date selector.
399 */
400 public String toString()
401 {
402 return (ecsOutput().toString());
403 }
404
405
406
407
408
409
410
411 public ElementContainer ecsOutput()
412 {
413 if (this.useDate == null)
414 {
415 this.useDate.setTime(new Date());
416 }
417
418 Select monthSelect = getMonthSelector(selName + MONTH_SUFFIX, useDate);
419 ConcreteElement daySelect = null;
420 if (!showDays)
421 {
422 daySelect = new Input(Input.hidden, selName + DAY_SUFFIX, setDay);
423 }
424 else
425 {
426 Select tmp = getDaySelector(selName + DAY_SUFFIX, useDate);
427 if (onChangeSet)
428 {
429 tmp.setOnChange(onChange);
430 }
431 daySelect = tmp;
432 }
433 Select yearSelect = null;
434 if (useYears)
435 {
436 yearSelect = getYearSelector(selName + YEAR_SUFFIX,
437 firstYear, lastYear, selectedYear);
438 }
439 else
440 {
441 yearSelect = getYearSelector(selName + YEAR_SUFFIX, useDate);
442 }
443 if (onChangeSet)
444 {
445 monthSelect.setOnChange(onChange);
446 yearSelect.setOnChange(onChange);
447 }
448 ElementContainer ec = new ElementContainer();
449
450 ec.addElement(monthSelect);
451 ec.addElement(daySelect);
452 ec.addElement(yearSelect);
453
454 return (ec);
455 }
456 }