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