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