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 }