001: package com.salmonllc.html;
002:
003: /////////////////////////
004: //$Archive: /SOFIA/SourceCode/com/salmonllc/html/HtmlDateComponent.java $
005: //$Author: Srufle $
006: //$Revision: 51 $
007: //$Modtime: 10/26/04 3:46p $
008: /////////////////////////
009:
010: import java.sql.Date;
011: import java.sql.Timestamp;
012: import java.text.DecimalFormat;
013: import java.util.*;
014:
015: import com.salmonllc.html.events.ValueChangedEvent;
016: import com.salmonllc.localizer.LanguagePreferences;
017: import com.salmonllc.localizer.LanguageResourceFinder;
018: import com.salmonllc.properties.Props;
019: import com.salmonllc.sql.*;
020: import com.salmonllc.util.MessageLog;
021:
022: /**
023: * Use this class to represent an SQL DATE or TIMESTAMP value as a series of drop-down
024: * lists to support selection of year, month, day, and hour.
025: */
026: public class HtmlDateComponent extends HtmlFormComponent {
027: protected HtmlContainer _cont;
028: protected HtmlDropDownList _month, _day, _year, _hour;
029: protected int _dsDataType;
030: protected GregorianCalendar _calendar = new GregorianCalendar();
031: protected int _minuteInterval;
032: protected int _startYear, _endYear;
033: protected DecimalFormat _formatMinutes = new DecimalFormat("00");
034: protected boolean _showHour = true;
035: protected DataStore _dsTemp;
036: protected int _iIndexOffset = -1;
037: protected String _displayFormat;
038: public final static int MONTH_NAME_FULL = 0;
039: public final static int MONTH_NAME_PARTIAL = 1;
040: public final static int MONTH_NAME_DIGIT = 2;
041: private Integer _tabIndex;
042: private String _accessKey;
043: public final static String DMY_DISPLAY_FORMAT = "DMY";
044: public final static String MDY_DISPLAY_FORMAT = "MDY";
045: public final static String YMD_DISPLAY_FORMAT = "YMD";
046:
047: /*Claudio Pi (12-29-2002) Added the following 3 instance varialbes, for i18n of short and long month labels*/
048: private String _monthLongNames[] = { "January", "February",
049: "March", "April", "May", "June", "July", "August",
050: "September", "October", "November", "December" };
051: private String _monthShortNames[] = { "Jan", "Feb", "Mar", "Apr",
052: "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec" };
053: private boolean _updateLocale = true;
054:
055: /**
056: * HtmlDateComponent constructor. Hour component is divided into half-hour intervals.
057: * @param name Component name.
058: * @param p Page containing the component.
059: */
060: public HtmlDateComponent(String name, HtmlPage p) {
061: this (name, p, 48);
062: }
063:
064: /**
065: * HtmlDateComponent constructor.
066: * @param name Component name.
067: * @param p Page containing the component.
068: * @param nbrIntervals For the hour component, break up the day into this many intervals.
069: * For example, 48 = half-hour intervals. 0 means do not display the hour component.
070: */
071: public HtmlDateComponent(String name, HtmlPage p, int nbrIntervals) {
072: this (name, p, nbrIntervals, -1, -1);
073:
074: }
075:
076: /**
077: * HtmlDateComponent constructor.
078: * @param name Component name.
079: * @param p Page containing the component.
080: * @param nbrIntervals For the hour component, break up the day into this many intervals.
081: * For example, 48 = half-hour intervals. 0 means do not display the hour component.
082: * @param iFromTime For the hour component, skip the hours before this time.
083: * @param iToTime For the hour component, skip the hours after this time.
084: For example iFromTime = 7 and iToTime = 19 => display times only between 7AM to 7PM
085: */
086: public HtmlDateComponent(String name, HtmlPage p, int nbrIntervals,
087: int iFromTime, int iToTime) {
088: this (name, p, nbrIntervals, iFromTime, iToTime, MONTH_NAME_FULL);
089: }
090:
091: /**
092: * HtmlDateComponent constructor.
093: * @param name Component name.
094: * @param p Page containing the component.
095: * @param nbrIntervals For the hour component, break up the day into this many intervals.
096: * For example, 48 = half-hour intervals. 0 means do not display the hour component.
097: * @param iFromTime For the hour component, skip the hours before this time.
098: * @param iToTime For the hour component, skip the hours after this time.
099: For example iFromTime = 7 and iToTime = 19 => display times only between 7AM to 7PM
100: */
101: public HtmlDateComponent(String name, HtmlPage p, int nbrIntervals,
102: int iFromTime, int iToTime, int iFlag) {
103: super (name, p);
104: processLocaleInfo();
105: _cont = new HtmlContainer(name, p);
106: String sMonth[] = new String[12];
107:
108: /*Claudio Pi (12-29-2002) following lines aren't necessary since they are replaced by the i18n instance variables
109: String sMonthFull[] = {"January","February","March","April","May","June","July","August","September","October","November","December"};
110: String sMonthPart[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};*/
111: String sMonthNumb[] = { "01", "02", "03", "04", "05", "06",
112: "07", "08", "09", "10", "11", "12" };
113: _month = new HtmlDropDownList("mm", p);
114: _month.setGenerateNewline(false);
115: _month.addOption(null, "");
116:
117: /*Claudio Pi (12-29-2002) hardcoded values replcaced with i18n instance variables*/
118: if (iFlag == MONTH_NAME_FULL)
119: sMonth = _monthLongNames; // sMonthFull;
120: else if (iFlag == MONTH_NAME_PARTIAL)
121: sMonth = _monthShortNames; // sMonthPart;
122: else if (iFlag == MONTH_NAME_DIGIT)
123: sMonth = sMonthNumb;
124: else if (iFlag == MONTH_NAME_DIGIT)
125: sMonth = _monthLongNames; // sMonthFull;
126: for (int i = 0; i < 12; i++)
127: _month.addOption(String.valueOf(i), sMonth[i]);
128:
129: _day = new HtmlDropDownList("dd", p);
130: _day.setGenerateNewline(false);
131: _day.addOption(null, "");
132: for (int i = 1; i <= 31; i++)
133: _day.addOption(String.valueOf(i), String.valueOf(i));
134: _year = new HtmlDropDownList("yy", p);
135: _year.setGenerateNewline(false);
136:
137: int currentYear = _calendar.get(Calendar.YEAR);
138: setYearRange(currentYear, currentYear + 3);
139:
140: //Determine what order to show the drop down combo boxes for day, month, year
141: _displayFormat = p.getPageProperties()
142: .getProperty(Props.DATE_COMPONENT_DISPLAY_FORMAT,
143: MDY_DISPLAY_FORMAT);
144:
145: if (_displayFormat.equals(DMY_DISPLAY_FORMAT)) {
146: _cont.add(_day);
147: _cont.add(_month);
148: _cont.add(_year);
149: } else if (_displayFormat.equals(YMD_DISPLAY_FORMAT)) {
150: _cont.add(_year);
151: _cont.add(_month);
152: _cont.add(_day);
153: } else {
154: _cont.add(_month);
155: _cont.add(_day);
156: _cont.add(_year);
157: }
158:
159: _hour = new HtmlDropDownList("hh", p);
160: _hour.setGenerateNewline(false);
161: _cont.add(_hour);
162: if (nbrIntervals <= 0) {
163: _showHour = false;
164: _hour.setVisible(false);
165: _minuteInterval = 0;
166: } else if (nbrIntervals <= 1440) {
167: double dRemainder = 1440 % nbrIntervals;
168: if (dRemainder != 0)
169: com.salmonllc.util.MessageLog.writeDebugMessage(
170: "Interval in HtmlDateComponent is not "
171: + "fraction of the day. interval = "
172: + nbrIntervals, this );
173:
174: _showHour = true;
175: _minuteInterval = (24 * 60) / nbrIntervals;
176: int minutes = 0;
177: _hour.addOption("", "");
178: boolean bSkipHour = false;
179:
180: for (int i = 0; i < nbrIntervals; i++) {
181: if (iFromTime > 0 && iToTime > 0) {
182: bSkipHour = true;
183: int hour = minutes / 60;
184: int remainder = minutes % 60;
185: if (hour < iFromTime || hour > iToTime
186: || (hour == iToTime && remainder > 0)) {
187: minutes += _minuteInterval;
188: continue;
189: }
190: }
191:
192: _hour.addOption(String.valueOf(i), formatTime(minutes));
193: minutes += _minuteInterval;
194: }
195:
196: if (bSkipHour) {
197: _iIndexOffset = (iFromTime * (60 / _minuteInterval)) - 1;
198:
199: }
200: }
201: // For simplicity we create a dummy data store and bind to it. This allows the
202: // DataStore class to worry about all details of formatting.
203: DataStore ds = new DataStore();
204: if (_showHour)
205: ds.addColumn("table", "val", DataStore.DATATYPE_DATETIME,
206: false, true);
207: else
208: ds.addColumn("table", "val", DataStore.DATATYPE_DATE,
209: false, true);
210: ds.insertRow();
211: ds.gotoFirst();
212: setColumn(ds, 0);
213: }
214:
215: /**
216: * generates the date.
217: * @return java.lang.String
218: * @param month java.lang.String
219: * @param day java.lang.String
220: * @param year java.lang.String
221: * @param hour java.lang.String
222: */
223: protected String buildValueString(String month, String day,
224: String year, String hour) throws DataStoreException {
225: String newValue;
226: if ((month == null && day == null && year == null && hour == null)) {
227: newValue = null;
228: } else if ((month == null) || (day == null) || (year == null)
229: || (hour == null && _hour.getVisible())) {
230: newValue = (year == null ? " " : year) + "-"
231: + (month == null ? " " : month) + "-"
232: + (day == null ? " " : day) + "-"
233: + (hour == null ? " " : hour);
234: } else {
235: GregorianCalendar gc = new GregorianCalendar();
236: gc.set(Calendar.MONTH, Integer.parseInt(month));
237: gc.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day));
238: gc.set(Calendar.YEAR, Integer.parseInt(year));
239: gc.set(Calendar.SECOND, 0);
240: gc.set(Calendar.MILLISECOND, 0);
241: if (hour != null && !hour.trim().equals("")) {
242: int iHour = Integer.parseInt(hour);
243: int minutes = iHour * _minuteInterval;
244: gc.set(Calendar.HOUR_OF_DAY, minutes / 60);
245: gc.set(Calendar.MINUTE, minutes % 60);
246: } else {
247: gc.set(Calendar.HOUR_OF_DAY, 0);
248: gc.set(Calendar.MINUTE, 0);
249: }
250: // Use temporary data store as a register
251: if (_dsBuff != null) {
252: String fmt = _dsBuff.getFormat(_dsColNo);
253: if (fmt != null)
254: _dsTemp.setFormat(0, fmt);
255: }
256:
257: switch (_dsDataType) {
258: case DataStore.DATATYPE_DATE:
259: _dsTemp.setDate(0, new java.sql.Date(gc.getTime()
260: .getTime()));
261: break;
262: case DataStore.DATATYPE_DATETIME:
263: _dsTemp.setDateTime(0, new java.sql.Timestamp(gc
264: .getTime().getTime()));
265: break;
266: }
267: newValue = _dsTemp.getFormattedString(0);
268: }
269: return newValue;
270: }
271:
272: /**
273: * Clears fields within this control.
274: */
275: public void clearDisplay() {
276: _month.setSelectedIndex(0);
277: _day.setSelectedIndex(0);
278: _year.setSelectedIndex(0);
279: if (_hour != null)
280: _hour.setSelectedIndex(0);
281: }
282:
283: /**
284: * Returns a formatted time for the specified minutes.
285: * @return java.lang.String
286: * @param minutes int
287: */
288: protected String formatTime(int minutes) {
289: int hour = minutes / 60;
290: int remainder = minutes % 60;
291:
292: // Convert 0-based 24-hour sequence into 1-based 12-hour sequence.
293: int h = ((hour + 12 - 1) % 12) + 1;
294:
295: String result = String.valueOf(h) + ":"
296: + _formatMinutes.format(remainder);
297: if (hour >= 12)
298: result += " PM";
299: else
300: result += " AM";
301: return result;
302: }
303:
304: public void generateHTML(java.io.PrintWriter p, int row)
305: throws Exception {
306: // It is essential to call getValue() here because there may be a ValueChanged
307: // event in the queue for this object, which needs to be removed, which getValue()
308: // does. The secondary calls to getValue() from the container will not
309: // do this because there are no events associated with them.
310: String value = getValue(row, true);
311: if (value == null) {
312: clearDisplay();
313: } else if (_dsBuff != null
314: && !_dsBuff.isFormattedStringValid(_dsColNo, value)) {
315: updatePartialDisplay(value);
316: } else {
317: if (_dsBuff != null) {
318: String fmt = _dsBuff.getFormat(_dsColNo);
319: if (fmt != null)
320: _dsTemp.setFormat(0, fmt);
321: }
322:
323: _dsTemp.setFormattedString(0, value);
324: switch (_dsDataType) {
325: case DataStore.DATATYPE_DATE:
326: _calendar.setTime(_dsTemp.getDate(0, 0));
327: break;
328: case DataStore.DATATYPE_DATETIME:
329: _calendar.setTime(_dsTemp.getDateTime(0, 0));
330: break;
331: }
332: updateDisplay();
333: }
334: _cont.generateHTML(p, row);
335: if (_visible && _enabled)
336: p.println("");
337: }
338:
339: /**
340: * This method returns a Date value from the component.
341: * @return java.sql.Date
342: */
343: public Date getDate() {
344: String value = getValue();
345: if (value == null)
346: return null;
347:
348: try {
349: _dsTemp.setFormattedString(0, value);
350: switch (_dsDataType) {
351: case DataStore.DATATYPE_DATE:
352: return new Date(_dsTemp.getDate(0, 0).getTime());
353: case DataStore.DATATYPE_DATETIME:
354: return new Date(_dsTemp.getDateTime(0, 0).getTime());
355: }
356: } catch (DataStoreException ex) {
357: return null;
358: }
359:
360: return null;
361:
362: }
363:
364: /**
365: * This method returns a Timestamp value from the component.
366: * @return java.sql.Timestamp
367: */
368: public Timestamp getDateTime() {
369:
370: String value = getValue();
371: if (value == null)
372: return null;
373:
374: try {
375: _dsTemp.setFormattedString(0, value);
376:
377: switch (_dsDataType) {
378: case DataStore.DATATYPE_DATE:
379: return new Timestamp(_dsTemp.getDate(0, 0).getTime());
380: case DataStore.DATATYPE_DATETIME:
381: return new Timestamp(_dsTemp.getDateTime(0, 0)
382: .getTime());
383: }
384: } catch (DataStoreException e) {
385: return null;
386: }
387:
388: return null;
389: }
390:
391: /**
392: * This method returns the string value of the day subcomponent.
393: * @return String
394: */
395: public String getDay() {
396: return _day.getValue();
397: }
398:
399: /**
400: * Returns the sub-component to be used for setting focus.
401: * @return com.salmonllc.html.HtmlComponent
402: */
403: public HtmlComponent getFocus() {
404: return _month;
405: }
406:
407: /**
408: * This method returns the string value of the hour subcomponent.
409: * @return String
410: */
411: public String getHour() {
412: return _hour.getValue();
413: }
414:
415: /**
416: * This method returns the string value of the month subcomponent.
417: * January = 1, etc.
418: * @return String
419: */
420: public String getMonth() {
421: String s = _month.getValue();
422: return s == null ? null : new Integer(1 + Integer.parseInt(s))
423: .toString();
424: }
425:
426: /**
427: * Gets the value of the component from the parms hashtable based upon the component name & row no.
428: */
429: protected String getParmValue(Hashtable parms, HtmlComponent comp,
430: int rowNo) {
431: String name = comp.getFullName();
432: String result;
433: if (rowNo > -1)
434: name += "_" + rowNo;
435: String val[] = (String[]) parms.get(name);
436: if (val != null) {
437: result = val[0].trim();
438: if (result.equals(""))
439: result = null;
440: } else
441: result = null;
442: return result;
443: }
444:
445: /**
446: * This method returns the string value of the year subcomponent.
447: * @return String
448: */
449: public String getYear() {
450: return _year.getValue();
451: }
452:
453: public boolean processParms(Hashtable parms, int rowNo)
454: throws Exception {
455: if (!getVisible() || !getEnabled())
456: return false;
457:
458: String oldValue;
459: String year, month, day;
460: String hour = null;
461: int r = rowNo;
462: if (r < 0)
463: r = _dsBuff.getRow();
464:
465: try {
466: oldValue = _dsBuff.getFormattedString(r, _dsColNo);
467: } catch (Exception e) {
468: oldValue = getValue();
469: }
470:
471: // Determine the new value from all edit fields.
472: month = getParmValue(parms, _month, rowNo);
473: _month.setValue(month, rowNo);
474: day = getParmValue(parms, _day, rowNo);
475: _day.setValue(day, rowNo);
476: year = getParmValue(parms, _year, rowNo);
477: _year.setValue(year, rowNo);
478: if (_showHour) {
479: hour = getParmValue(parms, _hour, rowNo);
480: _hour.setValue(hour, rowNo);
481: }
482: String newValue = buildValueString(month, day, year, hour);
483: // Compare old and new values and possibly create a ValueChangedEvent.
484: if (!valuesEqual(oldValue, newValue)) {
485: ValueChangedEvent e = new ValueChangedEvent(getPage(),
486: this , getName(), getFullName(), oldValue, newValue,
487: rowNo, _dsColNo, _dsBuff);
488: addEvent(e);
489: }
490: return false;
491: }
492:
493: /**
494: * This method will clear all pending events from the event queue for this component.
495: */
496: public void reset() {
497: super .reset();
498: _cont.reset();
499: }
500:
501: /**
502: * Specifies the Style Class to be used for the Date Component.
503: * Creation date: (7/19/01 8:41:20 AM)
504: * @param sClass java.lang.String A name of a class in Html to be used by this component
505: */
506: public void setClassName(String sClass) {
507:
508: super .setClassName(sClass);
509: if (_month != null)
510: _month.setClassName(sClass);
511:
512: if (_day != null)
513: _day.setClassName(sClass);
514:
515: if (_year != null)
516: _year.setClassName(sClass);
517:
518: if (_hour != null)
519: _hour.setClassName(sClass);
520:
521: }
522:
523: /**
524: * Use this method to bind the component to a column in a DataStore.
525: * @param ds The datastore to bind to.
526: * @param columnNo The index of the column to bind to.
527: */
528: public void setColumn(DataStoreBuffer ds, int columnNo) {
529: super .setColumn(ds, columnNo);
530: try {
531: _dsDataType = _dsBuff.getColumnDataType(columnNo);
532: /* switch (_dsDataType) {
533: case _dsBuff.DATATYPE_DATETIME:
534: // _showHour = true;
535: _hour.setVisible(_showHour);
536: break;
537: case _dsBuff.DATATYPE_DATE:
538: // _showHour = false;
539: _hour.setVisible(false);
540: break;
541: }*/
542: } catch (DataStoreException e) {
543: }
544: // Maintain a temporary data store in parallel with the main data store,
545: // to be used as a value/formatting buffer.
546: _dsTemp = new DataStore();
547: _dsTemp.addColumn("table", "val", _dsDataType, false, true);
548: _dsTemp.insertRow();
549: _dsTemp.gotoFirst();
550: }
551:
552: /**
553: * Sets the value of the component to the given date and display it.
554: * @param d New date value.
555: */
556: public void setDate(Date d) {
557: _calendar.setTime(d);
558: updateDisplay();
559:
560: // Updated on 07/08/02 by BYD to allow component update when not bound to DataStore
561: // example of usage: search date set to passed date after re-direction from another page
562: if (_dsBuff != null) {
563: try {
564: if (_showHour)
565: _dsBuff.setDateTime(0, "table.val", new Timestamp(d
566: .getTime()));
567: else
568: _dsBuff.setDate(0, "table.val", d);
569: } catch (Exception e) {
570: MessageLog.writeErrorMessage("setDate", e, this );
571: }
572: }
573: }
574:
575: /**
576: * Sets the value of the component to the given timestamp and display it.
577: * @param t New timestamp value.
578: */
579: public void setDateTime(Timestamp t) {
580: _calendar.setTime(t);
581: updateDisplay();
582:
583: // Updated on 07/08/02 by BYD to allow component update when not bound to DataStore
584: // example of usage: search date set to passed date after re-direction from another page
585: if (_dsBuff != null) {
586: try {
587: if (_showHour)
588: _dsBuff.setDateTime(0, "table.val", t);
589: else
590: _dsBuff.setDate(0, "table.val", new Date(t
591: .getTime()));
592: } catch (Exception e) {
593: MessageLog.writeErrorMessage("setDateTime", e, this );
594: }
595: }
596: }
597:
598: /**
599: * Sets the font end tag for disabled mode.
600: * @param tag java.lang.String
601: */
602: public void setDisabledFontEndTag(String tag) {
603:
604: _month.setDisabledFontEndTag(tag);
605: _day.setDisabledFontEndTag(tag);
606: _year.setDisabledFontEndTag(tag);
607: _hour.setDisabledFontEndTag(tag);
608: }
609:
610: /**
611: * Sets the font tag for disabled mode.
612: * @param tag java.lang.String
613: */
614: public void setDisabledFontStartTag(String tag) {
615:
616: _month.setDisabledFontStartTag(tag);
617: _day.setDisabledFontStartTag(tag);
618: _year.setDisabledFontStartTag(tag);
619: _hour.setDisabledFontStartTag(tag);
620:
621: }
622:
623: /**
624: * Enables or disables the ability of this component to respond to user input.
625: * @param enabled boolean
626: */
627: public void setEnabled(boolean enabled) {
628: super .setEnabled(enabled);
629: _cont.setEnabled(enabled);
630: }
631:
632: /**
633: * Specifies the parent component for this Date Component.
634: * Creation date: (7/19/01 8:41:20 AM)
635: */
636: public void setParent(HtmlComponent parent) {
637: super .setParent(parent);
638: // This is necessary for the name to be generated correctly, else the leading
639: // sequence of parent names will be lost.
640: _cont.setParent(parent);
641: }
642:
643: /**
644: * This method sets the property theme for the component.
645: * @param sTheme The theme to use.
646: */
647: public void setTheme(String sTheme) {
648:
649: if (sTheme == null)
650: return;
651:
652: if (_month != null)
653: _month.setTheme(sTheme);
654:
655: if (_day != null)
656: _day.setTheme(sTheme);
657:
658: if (_year != null)
659: _year.setTheme(sTheme);
660:
661: if (_hour != null)
662: _hour.setTheme(sTheme);
663:
664: }
665:
666: /**
667: * Changes the drop-down for the year to encompass the given range.
668: * @param startYear
669: * @param endYear
670: */
671: public void setYearRange(int startYear, int endYear) {
672: if ((startYear < 0) || (endYear < 0))
673: // Consistency check
674: return;
675: _startYear = (startYear >= endYear) ? endYear : startYear;
676: _endYear = (startYear < endYear) ? endYear : startYear;
677: _year.resetOptions();
678: _year.addOption(null, "");
679: if (startYear < endYear) {
680: for (int i = startYear; i <= endYear; i++) {
681: String s = String.valueOf(i);
682: _year.addOption(s, s);
683: }
684: } else {
685: for (int i = startYear; i >= endYear; i--) {
686: String s = String.valueOf(i);
687: _year.addOption(s, s);
688: }
689: }
690: }
691:
692: protected void updateDisplay() {
693: _month.setSelectedIndex(_calendar.get(Calendar.MONTH) + 1);
694: _day.setSelectedIndex(_calendar.get(Calendar.DAY_OF_MONTH));
695: int year = _calendar.get(Calendar.YEAR);
696: if ((year < _startYear) || (year > _endYear))
697: setYearRange(year - 5, year + 5);
698: _year.setValue(String.valueOf(year));
699: if (_minuteInterval > 0) {
700: int iIndex = (((_calendar.get(Calendar.HOUR_OF_DAY) * 60) + _calendar
701: .get(Calendar.MINUTE)) / _minuteInterval)
702: - _iIndexOffset;
703: if (iIndex < 0)
704: _hour.setSelectedIndex(0);
705: else
706: _hour.setSelectedIndex(iIndex);
707: }
708: }
709:
710: protected void updatePartialDisplay(String value) {
711: java.util.StringTokenizer st = new java.util.StringTokenizer(
712: value, "-");
713:
714: String year = st.nextToken();
715: String month = st.nextToken();
716: String day = st.nextToken();
717: String hour = null;
718: if (st.hasMoreTokens())
719: hour = st.nextToken();
720:
721: if (!year.equals(" "))
722: _year.setValue(year);
723: else
724: _year.setValue(null);
725:
726: if (!month.equals(" "))
727: _month.setValue(month);
728: else
729: _month.setValue(null);
730:
731: if (!day.equals(" "))
732: _day.setValue(day);
733: else
734: _day.setValue(null);
735:
736: _hour.setValue(null);
737: if (hour != null)
738: if (!hour.equals(" "))
739: _hour.setValue(hour);
740: }
741:
742: /*Claudio Pi (12-29-2002) Added the methods updateLocale, processLocaleInfo and processLocaleArray for
743: i18n of short and long month labels */
744:
745: /**
746: * Updates the month name for the current language<br>
747: * The language property file must have the following key structure<br>
748: * HtmlCalendar.month.short.0 to HtmlCalendar.month.short.11 represents the month short names from jan to dec<br>
749: * HtmlCalendar.month.long.0 to HtmlCalendar.month.long.11 represents the month long names from January to December<br>
750: * Author: Claudio Pi Gamba<br>
751: * Company: http://www.grupo-quanam.com<br>
752: * Email: claudio.pi@quanam.com.uy<br>
753: */
754: public void updateLocale() {
755: _updateLocale = true;
756: }
757:
758: public void processLocaleInfo() {
759: if (_updateLocale) {
760: _updateLocale = false;
761: LanguagePreferences p = getPage().getLanguagePreferences();
762: String appName = getPage().getApplicationName();
763: StringBuffer key = new StringBuffer(
764: "HtmlCalendar.month.short.0");
765: boolean shortOK = (LanguageResourceFinder.getResource(
766: appName, key.toString(), p) != null);
767: key.setLength(0);
768: key.append("HtmlCalendar.month.long.0");
769: boolean longOK = (LanguageResourceFinder.getResource(
770: appName, key.toString(), p) != null);
771:
772: if (shortOK) {
773: processLocaleArray(_monthShortNames,
774: "HtmlCalendar.month.short.", appName, p, key);
775: }
776:
777: if (longOK) {
778: processLocaleArray(_monthLongNames,
779: "HtmlCalendar.month.long.", appName, p, key);
780: }
781: }
782: }
783:
784: private void processLocaleArray(String[] ar, String key,
785: String appName, LanguagePreferences p, StringBuffer sb) {
786: for (int i = 0; i < ar.length; i++) {
787: sb.setLength(0);
788: sb.append(key);
789: sb.append(new Integer(i).toString());
790: String val = LanguageResourceFinder.getResource(appName, sb
791: .toString(), p);
792: if (val != null)
793: ar[i] = val;
794: }
795: }
796:
797: /**
798: * This method will set the edit focus to this component.
799: */
800: public void setFocus() {
801: if (_displayFormat.equals(DMY_DISPLAY_FORMAT))
802: _day.setFocus();
803: else if (_displayFormat.equals(YMD_DISPLAY_FORMAT))
804: _year.setFocus();
805: else
806: _month.setFocus();
807:
808: }
809:
810: /**
811: * This method will set the edit focus to this component for a particular row in a datastore.
812: */
813: public void setFocus(int row) {
814: if (_displayFormat.equals(DMY_DISPLAY_FORMAT))
815: _day.setFocus(row);
816: else if (_displayFormat.equals(YMD_DISPLAY_FORMAT))
817: _year.setFocus(row);
818: else
819: _month.setFocus(row);
820: }
821:
822: /**
823: * Sets javascript that will fire when the user changes a value in the component
824: * @param onChange
825: */
826: public void setOnChange(String onChange) {
827: if (_day != null)
828: _day.setOnChange(onChange);
829: if (_month != null)
830: _month.setOnChange(onChange);
831: if (_year != null)
832: _year.setOnChange(onChange);
833: }
834:
835: /**
836: * @returns the tab index html attribute
837: */
838: public int getTabIndex() {
839: if (_tabIndex == null)
840: return -1;
841: return _tabIndex.intValue();
842: }
843:
844: /**
845: * @param sets the tab index html attribute. You can also pass TAB_INDEX_DEFAULT to use the default tab index for the component or TAB_INDEX_NONE to keep this component from being tabbed to
846: */
847: public void setTabIndex(int val) {
848: if (val == -1)
849: _tabIndex = null;
850: else
851: _tabIndex = new Integer(val);
852: int monthIndex = 0;
853: int dayIndex = 0;
854: int yearIndex = 0;
855: if (_displayFormat.equals(DMY_DISPLAY_FORMAT)) {
856: dayIndex = val;
857: monthIndex = val + 1;
858: yearIndex = val + 2;
859: } else if (_displayFormat.equals(YMD_DISPLAY_FORMAT)) {
860: yearIndex = val;
861: monthIndex = val + 1;
862: dayIndex = val + 2;
863: } else {
864: monthIndex = val;
865: dayIndex = val + 1;
866: yearIndex = val + 2;
867: }
868:
869: if (_month != null)
870: _month.setTabIndex(monthIndex);
871: if (_day != null)
872: _day.setTabIndex(dayIndex);
873: if (_year != null)
874: _year.setTabIndex(yearIndex);
875: if (_hour != null)
876: _hour.setTabIndex(val + 3);
877:
878: }
879:
880: }
|