KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > blandware > atleap > webapp > taglib > core > html > CalendarTag


1 /*
2  * Copyright 2004 Blandware (http://www.blandware.com)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package com.blandware.atleap.webapp.taglib.core.html;
17
18
19 import com.blandware.atleap.common.util.DateUtil;
20 import com.blandware.atleap.webapp.util.core.ApplicationResources;
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.struts.Globals;
24 import org.apache.struts.taglib.TagUtils;
25
26 import javax.servlet.http.HttpServletRequest JavaDoc;
27 import javax.servlet.jsp.JspException JavaDoc;
28 import javax.servlet.jsp.PageContext JavaDoc;
29 import javax.servlet.jsp.tagext.SimpleTagSupport JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.StringWriter JavaDoc;
32 import java.util.Locale JavaDoc;
33
34 /**
35  * <p>This tag renders javascript to show calendar popup window with different options.
36  * Selected date will be stored into form field with given name.
37  * </p>
38  * <p>
39  * You must include link to JS file with calendar functions somewhere on your page
40  * </p>
41  * <p>
42  * Body of this tag will generate body of a link.
43  * </p>
44  * <p>
45  * Allowed attributes are:
46  * <ul>
47  * <li>
48  * <b>fieldName</b> - full name of input field to put selected date in. Must be
49  * correct JavaScript name such as follows: <code>document.forms[0].dateInput</code>
50  * </li>
51  * <li>
52  * <b>anchorName</b> - name of anchor that will be generated for calendar popup.
53  * By default it is &quot;jsCalendarAnchor&quot; plus ordinal number (positive
54  * integer leading by zero) of this tag on current page
55  * </li>
56  * <li>
57  * <b>datePattern</b> - pattern for displaying date. By default it is taken from
58  * locale stored in session under <code>org.apache.struts.Globals.LOCALE_KEY</code>
59  * Date pattern taken has only date symbols, not time symbols
60  * </li>
61  * <li>
62  * <b>startDate</b> - Pre-selected start date in calendar according to specified
63  * date pattern. By default current date is preselected (it is calendar default)
64  * </li>
65  * <li>
66  * <b>style</b> - Style of calendar displaying. Valid values are WINDOW and DIV
67  * (manner is case insensitive). Default value is WINDOW
68  * </li>
69  * <li>
70  * <b>divStyleId</b> - ID of 'div' tag for DIV-style display of calendar. This
71  * attribute is optional if style was set to DIV, otherwise it is ignored. If
72  * DIV style was set and this attribute is omitted, default value will be
73  * &quot;jsCalendarDiv&quot;. Tag will be generated once, despite on number of
74  * calendar tags on current page
75  * </li>
76  * <li>
77  * <b>cssPrefix</b> - CSS prefix to search CSS classes for displaying calendar
78  * when DIV-style is enabled. By default it is &quot;calendar-&quot;
79  * </li>
80  * <li>
81  * <b>showYearNavigation</b> - Whether or not show year navigation. By default
82  * it is FALSE
83  * </li>
84  * <li>
85  * <b>showYearNavigationInput</b> - Whether or not show year navigation input.
86  * By default it is FALSE
87  * </li>
88  * <li>
89  * <b>showNavigationDropdowns</b> - Whether or not show navigation drop-downs.
90  * By default it is FALSE
91  * </li>
92  * <li>
93  * <b>monthNamesKey</b> - Bundle key to search for localized month names. If it
94  * is not specified, calendar defaults are used. If no message was found for
95  * specified key, <code>JspException</code> will be thrown
96  * </li>
97  * <li>
98  * <b>daysHeadersKey</b> - Bundle key to search for localized day headers. If it
99  * is not specified, calendar defaults are used. If no message was found for
100  * specified key, <code>JspException</code> will be thrown
101  * </li>
102  * <li>
103  * <b>weekStartDay</b> - Bundle key to search for week start day. If it is not
104  * specified, calendar defaults are used. If no message was found for specified
105  * key, <code>JspException</code> will be thrown. Under this key number of day
106  * that will be considered first must be stored. For example, if Sunday is first
107  * day of week, this number will be 0; if Monday -- then 1 and so on
108  * </li>
109  * <li>
110  * <b>todayTextKey</b> - Bundle key to search for localized 'today' text. If it is
111  * not specified, calendar defaults are used. If no message was found for
112  * specified key, <code>JspException</code> will be thrown
113  * </li>
114  * </ul>
115  * </p>
116  * <p><a HREF="CalendarTag.java.htm"><i>View Source</i></a></p>
117  *
118  * @author Sergey Zubtcovskii <a HREF="mailto:sergey.zubtcovskii@blandware.com">&lt;sergey.zubtcovskii@blandware.com&gt;</a>
119  * @version $Revision: 1.3 $ $Date: 2005/10/20 06:31:37 $
120  * @jsp.tag name="calendar"
121  * body-content="scriptless"
122  */

123 public class CalendarTag extends SimpleTagSupport JavaDoc {
124
125     protected transient final Log log = LogFactory.getLog(CalendarTag.class);
126
127     /**
128      * Full name of input field to put selected date in.
129      * Must be correct JavaScript name such as follows:
130      * document.forms[0].dateInput
131      */

132     protected String JavaDoc fieldName;
133
134     /**
135      * Name of anchor that will be generated for calendar popup.
136      * By default it is "jsCalendarAnchor" plus ordinal number
137      * (positive integer leading by zero) of this tag on current page
138      */

139     protected String JavaDoc anchorName = null;
140
141     /**
142      * Pattern for displaying date.
143      * By default it is taken from locale stored in session under
144      * org.apache.struts.Globals.LOCALE_KEY
145      * Date pattern taken has only date symbols, not time symbols
146      *
147      * @see org.apache.struts.Globals#LOCALE_KEY
148      */

149     protected String JavaDoc datePattern = null;
150
151     /**
152      * Pre-selected start date in calendar according to specified date pattern
153      * By default current date is preselected (it is calendar default)
154      */

155     protected String JavaDoc startDate = null;
156
157     /**
158      * Style of calendar displaying.
159      * Valid values are WINDOW and DIV (manner is case insensitive)
160      * Default value is WINDOW
161      */

162     protected String JavaDoc style = "window";
163
164     /**
165      * ID of 'div' tag for DIV-style display of calendar.
166      * This attribute is optional if style was set to DIV, otherwise it is ignored
167      * If DIV style was set and this attribute is omitted, default value will be "jsCalendarDiv"
168      * Tag will be generated once, despite on number of calendar tags on current page
169      */

170     protected String JavaDoc divStyleId = null;
171
172     /**
173      * CSS prefix to search CSS classes for displaying calendar when DIV-style is enabled
174      * By default it is "calendar-"
175      */

176     protected String JavaDoc cssPrefix = "calendar-";
177
178     /**
179      * Whether or not show year navigation
180      * By default it is FALSE
181      */

182     protected Boolean JavaDoc showYearNavigation = Boolean.FALSE;
183
184     /**
185      * Whether or not show year navigation input
186      * By default it is FALSE
187      */

188     protected Boolean JavaDoc showYearNavigationInput = Boolean.FALSE;
189
190     /**
191      * Whether or not show navigation drop-downs
192      * By default it is FALSE
193      */

194     protected Boolean JavaDoc showNavigationDropdowns = Boolean.FALSE;
195
196     /**
197      * Bundle key to search for localized month names
198      * If it is not specified, calendar defaults are used
199      * If no message was found for specified key, JspException will be thrown
200      */

201     protected String JavaDoc monthNamesKey = null;
202
203     /**
204      * Bundle key to search for localized day headers
205      * If it is not specified, calendar defaults are used
206      * If no message was found for specified key, JspException will be thrown
207      */

208     protected String JavaDoc dayHeadersKey = null;
209
210     /**
211      * Bundle key to search for week start day
212      * If it is not specified, calendar defaults are used
213      * If no message was found for specified key, JspException will be thrown
214      */

215     protected String JavaDoc weekStartDayKey = null;
216
217     /**
218      * Bundle key to search for localized today text
219      * If it is not specified, calendar defaults are used
220      * If no message was found for specified key, JspException will be thrown
221      */

222     protected String JavaDoc todayTextKey = null;
223
224     protected static final String JavaDoc NUMBER_KEY = "com.blandware.atleap.taglib.CALENDAR_TAG_NUMBER";
225     protected static final String JavaDoc DIV_STYLE_ID_KEY = "com.blandware.atleap.taglib.CALENDAR_TAG_DIV_STYLE_ID";
226
227     /**
228      * Returns field name
229      *
230      * @return field name
231      * @see #fieldName
232      * @jsp.attribute required="false"
233      * rtexprvalue="true"
234      * type="java.lang.String"
235      * description="Full name of input field to put selected date in."
236      */

237     public String JavaDoc getFieldName() {
238         return fieldName;
239     }
240
241     /**
242      * Sets field name
243      *
244      * @param fieldName field name to set
245      * @see #fieldName
246      */

247     public void setFieldName(String JavaDoc fieldName) {
248         this.fieldName = fieldName;
249     }
250
251     /**
252      * Returns anchor name
253      *
254      * @return anchor name
255      * @see #anchorName
256      * @jsp.attribute required="false"
257      * rtexprvalue="true"
258      * type="java.lang.String"
259      * description="Name of anchor that will be generated for calendar popup"
260      */

261     public String JavaDoc getAnchorName() {
262         return anchorName;
263     }
264
265     /**
266      * Sets anchor name
267      *
268      * @param anchorName anchor name to set
269      * @see #anchorName
270      */

271     public void setAnchorName(String JavaDoc anchorName) {
272         this.anchorName = anchorName;
273     }
274
275     /**
276      * Returns date pattern
277      *
278      * @return date pattern
279      * @see #datePattern
280      * @jsp.attribute required="false"
281      * rtexprvalue="true"
282      * type="java.lang.String"
283      * description="Pattern for displaying date."
284      */

285     public String JavaDoc getDatePattern() {
286         return datePattern;
287     }
288
289     /**
290      * Sets date pattern
291      *
292      * @param datePattern date pattern to set
293      * @see #datePattern
294      */

295     public void setDatePattern(String JavaDoc datePattern) {
296         this.datePattern = datePattern;
297     }
298
299     /**
300      * Returns start date
301      *
302      * @return start date
303      * @see #startDate
304      * @jsp.attribute required="false"
305      * rtexprvalue="true"
306      * type="java.lang.String"
307      * description="Pre-selected start date in calendar according to specified date pattern"
308      */

309     public String JavaDoc getStartDate() {
310         return startDate;
311     }
312
313     /**
314      * Sets start date
315      *
316      * @param startDate start date to set
317      * @see #startDate
318      */

319     public void setStartDate(String JavaDoc startDate) {
320         this.startDate = startDate;
321     }
322
323     /**
324      * Returns style
325      *
326      * @return style
327      * @see #style
328      * @jsp.attribute required="false"
329      * rtexprvalue="true"
330      * type="java.lang.String"
331      * description="Style of calendar displaying."
332      */

333     public String JavaDoc getStyle() {
334         return style;
335     }
336
337     /**
338      * Sets style
339      *
340      * @param style style to set
341      * @see #style
342      */

343     public void setStyle(String JavaDoc style) {
344         this.style = style;
345     }
346
347     /**
348      * Returns DIV style ID
349      *
350      * @return DIV style ID
351      * @see #divStyleId
352      * @jsp.attribute required="false"
353      * rtexprvalue="true"
354      * type="java.lang.String"
355      * description="ID of 'div' tag for DIV-style display of calendar"
356      */

357     public String JavaDoc getDivStyleId() {
358         return divStyleId;
359     }
360
361     /**
362      * Sets DIV style ID
363      *
364      * @param divStyleId DIV style ID to set
365      * @see #divStyleId
366      */

367     public void setDivStyleId(String JavaDoc divStyleId) {
368         this.divStyleId = divStyleId;
369     }
370
371     /**
372      * Returns CSS prefix
373      *
374      * @return CSS prefix
375      * @see #cssPrefix
376      * @jsp.attribute required="false"
377      * rtexprvalue="true"
378      * type="java.lang.String"
379      * description="CSS prefix to search CSS classes for displaying calendar when DIV-style is enabled"
380      */

381     public String JavaDoc getCssPrefix() {
382         return cssPrefix;
383     }
384
385     /**
386      * Sets CSS prefix
387      *
388      * @param cssPrefix CSS prefix to set
389      * @see #cssPrefix
390      */

391     public void setCssPrefix(String JavaDoc cssPrefix) {
392         this.cssPrefix = cssPrefix;
393     }
394
395     /**
396      * Returns whether to show year navigation
397      *
398      * @return whether to show year navigation
399      * @see #showYearNavigation
400      * @jsp.attribute required="false"
401      * rtexprvalue="true"
402      * type="java.lang.Boolean"
403      * description="Whether or not show year navigation"
404      */

405     public Boolean JavaDoc getShowYearNavigation() {
406         return showYearNavigation;
407     }
408
409     /**
410      * Sets whether to show year navigation
411      *
412      * @param showYearNavigation whether to show year navigation
413      * @see #showYearNavigation
414      */

415     public void setShowYearNavigation(Boolean JavaDoc showYearNavigation) {
416         this.showYearNavigation = showYearNavigation;
417     }
418
419     /**
420      * Returns whether to show year navigation input
421      *
422      * @return whether to show year navigation input
423      * @see #showYearNavigationInput
424      * @jsp.attribute required="false"
425      * rtexprvalue="true"
426      * type="java.lang.Boolean"
427      * description="Whether or not show year navigation input"
428      */

429     public Boolean JavaDoc getShowYearNavigationInput() {
430         return showYearNavigationInput;
431     }
432
433     /**
434      * Sets whether to show year navigation input
435      *
436      * @param showYearNavigationInput whether to show year navigation input
437      * @see #showYearNavigationInput
438      */

439     public void setShowYearNavigationInput(Boolean JavaDoc showYearNavigationInput) {
440         this.showYearNavigationInput = showYearNavigationInput;
441     }
442
443     /**
444      * Returns whether to show navigation dropups
445      *
446      * @return whether to show navigation dropups
447      * @see #showNavigationDropdowns
448      * @jsp.attribute required="false"
449      * rtexprvalue="true"
450      * type="java.lang.Boolean"
451      * description="Whether or not show navigation drop-downs"
452      */

453     public Boolean JavaDoc getShowNavigationDropdowns() {
454         return showNavigationDropdowns;
455     }
456
457     /**
458      * Sets whether to show navigation dropups
459      *
460      * @param showNavigationDropdowns whether to show navigation dropups
461      * @see #showNavigationDropdowns
462      */

463     public void setShowNavigationDropdowns(Boolean JavaDoc showNavigationDropdowns) {
464         this.showNavigationDropdowns = showNavigationDropdowns;
465     }
466
467     /**
468      * Returns month names bundle key
469      *
470      * @return month names bundle key
471      * @see #monthNamesKey
472      * @jsp.attribute required="false"
473      * rtexprvalue="true"
474      * type="java.lang.String"
475      * description="Bundle key to search for localized month names"
476      */

477     public String JavaDoc getMonthNamesKey() {
478         return monthNamesKey;
479     }
480
481     /**
482      * Sets month names bundle key
483      *
484      * @param monthNamesKey month names bundle key to set
485      * @see #monthNamesKey
486      */

487     public void setMonthNamesKey(String JavaDoc monthNamesKey) {
488         this.monthNamesKey = monthNamesKey;
489     }
490
491     /**
492      * Returns day headers bundle key
493      *
494      * @return month names bundle key
495      * @see #dayHeadersKey
496      * @jsp.attribute required="false"
497      * rtexprvalue="true"
498      * type="java.lang.String"
499      * description="Bundle key to search for localized day headers"
500      */

501     public String JavaDoc getDayHeadersKey() {
502         return dayHeadersKey;
503     }
504
505     /**
506      * Sets day headers bundle key
507      *
508      * @param dayHeadersKey day headers bundle key to set
509      * @see #dayHeadersKey
510      */

511     public void setDayHeadersKey(String JavaDoc dayHeadersKey) {
512         this.dayHeadersKey = dayHeadersKey;
513     }
514
515     /**
516      * Returns week start day bundle key
517      *
518      * @return week start day bundle key
519      * @see #weekStartDayKey
520      * @jsp.attribute required="false"
521      * rtexprvalue="true"
522      * type="java.lang.String"
523      * description="Bundle key to search for week start day"
524      */

525     public String JavaDoc getWeekStartDayKey() {
526         return weekStartDayKey;
527     }
528
529     /**
530      * Sets week start day bundle key
531      *
532      * @param weekStartDayKey week start day bundle key to set
533      * @see #weekStartDayKey
534      */

535     public void setWeekStartDayKey(String JavaDoc weekStartDayKey) {
536         this.weekStartDayKey = weekStartDayKey;
537     }
538
539     /**
540      * Returns today text bundle key
541      *
542      * @return today text bundle key
543      * @see #todayTextKey
544      * @jsp.attribute required="false"
545      * rtexprvalue="true"
546      * type="java.lang.String"
547      * description="Bundle key to search for localized today text"
548      */

549     public String JavaDoc getTodayTextKey() {
550         return todayTextKey;
551     }
552
553     /**
554      * Sets today text bundle key
555      *
556      * @param todayTextKey today text bundle key to set
557      * @see #todayTextKey
558      */

559     public void setTodayTextKey(String JavaDoc todayTextKey) {
560         this.todayTextKey = todayTextKey;
561     }
562
563     /**
564      * Performs needed actions: outputs needed HTML code
565      *
566      * @throws JspException
567      * @throws IOException
568      */

569     public void doTag() throws JspException JavaDoc, IOException JavaDoc {
570
571         PageContext JavaDoc pageContext = (PageContext JavaDoc) getJspContext();
572         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) pageContext.getRequest();
573
574         if ( datePattern == null ) {
575             datePattern = DateUtil.getDatePattern((Locale JavaDoc) pageContext.getAttribute(Globals.LOCALE_KEY, PageContext.SESSION_SCOPE));
576         }
577
578         Integer JavaDoc tagNumber = (Integer JavaDoc) pageContext.getAttribute(NUMBER_KEY);
579
580         if ( tagNumber == null ) {
581             tagNumber = new Integer JavaDoc(0);
582         } else {
583             tagNumber = new Integer JavaDoc(tagNumber.intValue() + 1);
584         }
585
586         if ( log.isDebugEnabled() ) {
587             log.debug("This tag number will be " + tagNumber);
588         }
589
590         pageContext.setAttribute(NUMBER_KEY, tagNumber);
591
592         String JavaDoc var = "jsCalendar" + tagNumber;
593
594         if ( log.isDebugEnabled() ) {
595             log.debug("Anchor name: " + anchorName);
596         }
597
598         if ( anchorName == null ) {
599             anchorName = "jsCalendarAnchor" + tagNumber;
600         }
601
602         if ( "div".equalsIgnoreCase(style) ) {
603             if ( divStyleId == null ) {
604                 divStyleId = "jsCalendarDiv";
605             }
606         } else {
607             divStyleId = null;
608         }
609
610         if ( log.isDebugEnabled() ) {
611             log.debug("Style: " + style + "\tDIV style ID: " + divStyleId);
612         }
613
614         String JavaDoc script = "<script language=\"javascript\">\n";
615         if ( divStyleId != null ) {
616             script += "var " + var + " = new CalendarPopup(\'" + divStyleId + "\');\n";
617         } else {
618             script += "var " + var + " = new CalendarPopup();\n";
619         }
620         if ( cssPrefix != null ) {
621             script += var + ".setCssPrefix(\'" + cssPrefix + "\');\n";
622         }
623         if ( showYearNavigation.booleanValue() ) {
624             script += var + ".showYearNavigation();\n";
625         }
626
627         if ( showYearNavigationInput.booleanValue() ) {
628             script += var + ".showYearNavigationInput();\n";
629         }
630
631         if ( showNavigationDropdowns.booleanValue() ) {
632             script += var + ".showNavigationDropDowns();\n";
633         }
634
635         if ( monthNamesKey == null ) {
636             monthNamesKey = "core.calendar.monthNames";
637         }
638
639         if ( dayHeadersKey == null ) {
640             dayHeadersKey = "core.calendar.dayHeaders";
641         }
642
643         if ( weekStartDayKey == null ) {
644             weekStartDayKey = "core.calendar.weekStartDay";
645         }
646         if ( todayTextKey == null ) {
647             todayTextKey = "core.calendar.todayText";
648         }
649
650         TagUtils tagUtils = TagUtils.getInstance();
651         ApplicationResources applicationResources = ApplicationResources.getInstance(pageContext.getServletContext());
652         String JavaDoc monthNames = applicationResources.getMessage(request, monthNamesKey);
653         if ( monthNames == null ) {
654             if ( log.isWarnEnabled() ) {
655                 log.warn("No message for key '" + monthNamesKey + "' was found ");
656             }
657         } else {
658             script += var + ".setMonthNames(" + monthNames + ");\n";
659         }
660
661         String JavaDoc dayHeaders = applicationResources.getMessage(request, dayHeadersKey);
662         if ( dayHeaders == null ) {
663             if ( log.isWarnEnabled() ) {
664                 log.warn("No message for key '" + dayHeadersKey + "' was found ");
665             }
666         } else {
667             script += var + ".setDayHeaders(" + dayHeaders + ");\n";
668         }
669
670         String JavaDoc weekStartDay = applicationResources.getMessage(request, weekStartDayKey);
671         if ( weekStartDay == null ) {
672             if ( log.isWarnEnabled() ) {
673                 log.warn("No message for key '" + weekStartDayKey + "' was found ");
674             }
675         } else {
676             script += var + ".setWeekStartDay(" + weekStartDay + ");\n";
677         }
678
679         String JavaDoc todayText = applicationResources.getMessage(request, todayTextKey);
680         if ( todayText == null ) {
681             if ( log.isWarnEnabled() ) {
682                 log.warn("No message for key " + todayTextKey + " was found ");
683             }
684         } else {
685             script += var + ".setTodayText(\'" + todayText + "\');\n";
686         }
687
688         script += "</script>\n";
689
690         StringWriter JavaDoc sw = new StringWriter JavaDoc();
691         StringBuffer JavaDoc sb = sw.getBuffer();
692         sb.append(script).append("<a HREF=\"#\" id=\"")
693                 .append(anchorName).append("\" name=\"")
694                 .append(anchorName).append("\" onclick=\"")
695                 .append(var).append(".select(").append(fieldName)
696                 .append(", \'").append(anchorName).append("\', \'")
697                 .append(datePattern).append("\'")
698                 .append(startDate != null ? ", \'" + startDate + "\'" : ");")
699                 .append(" return false;\">");
700
701         getJspBody().invoke(sw);
702         sb.append("</a>\n");
703
704         if ( style.equalsIgnoreCase("div") && pageContext.getAttribute(DIV_STYLE_ID_KEY) == null ) {
705             sb.append("<div id=\"").append(divStyleId).append("\" style=\"visibility: hidden; position: absolute; background-color: white; layer-background-color: white;\"></div>");
706             pageContext.setAttribute(DIV_STYLE_ID_KEY, divStyleId);
707         }
708
709         tagUtils.write(pageContext, sw.toString());
710     }
711
712 }
713
Popular Tags