View Javadoc

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 &lt;SELECT&gt; 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 }