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