YUI Library Home

YUI Library Examples: Button Control: Calendar Menu Button with Date on Button Face

Button Control: Calendar Menu Button with Date on Button Face

This example demonstrates how to create a Menu Button whose Menu displays a Calendar. Selecting a date from the Calendar updates the label of the Button to reflect the currently selected date.

Personal Information

Begin by defining an anonymous function in order to keep all variables out of the global scope. Inside the anonymous function, define some shortcuts to utils that will be used frequently (Dom and Event).

1(function () { 
2 
3    var Event = YAHOO.util.Event, 
4        Dom = YAHOO.util.Dom; 
5             
6}());            
view plain | print | ?

Inside the the anonymous function, use the onContentReady method of the Event utility to instantiate an Overlay and a Button when the "datefields" <fieldset> is available to be scripted. Additionally, create references to each of the form fields used to set the date. Each of the three date form fields are hidden and the Calendar will be used as a proxy for them.

1Event.onDOMReady(function () { 
2 
3    var oCalendarMenu; 
4 
5 
6    var oDateFields = Dom.get("datefields"); 
7        oMonthField = Dom.get("month"), 
8        oDayField = Dom.get("day"), 
9        oYearField = Dom.get("year"); 
10 
11 
12    // Hide the form fields used for the date so that they can be replaced by the  
13    // calendar button. 
14 
15    oMonthField.style.display = "none"
16    oDayField.style.display = "none"
17    oYearField.style.display = "none"
18 
19     
20    // Create a Overlay instance to house the Calendar instance 
21 
22    oCalendarMenu = new YAHOO.widget.Overlay("calendarmenu", { visible: false }); 
23 
24 
25    // Create a Button instance of type "menu" 
26 
27    var oButton = new YAHOO.widget.Button({  
28                                    type: "menu",  
29                                    id: "calendarpicker",  
30                                    label: "Choose A Date",  
31                                    menu: oCalendarMenu,  
32                                    container: "datefields" }); 
33 
34}); 
view plain | print | ?

Once the new Button is created, add a listener for its "appendTo" event that will be used to render its Overlay instance into the same DOM element specified as the containing element for the Button.

1oButton.on("appendTo"function () { 
2 
3    // Create an empty body element for the Overlay instance in order  
4    // to reserve space to render the Calendar instance into. 
5 
6    oCalendarMenu.setBody(" "); 
7 
8    oCalendarMenu.body.id = "calendarcontainer"
9 
10}); 
view plain | print | ?

Add a listener for the Button's "click" event that will be used to create a new Calendar instance. (Defering the creation and rendering of the Calendar until the firing of the "click" event improves the intial load time of the Button instance.)

1var onButtonClick = function () { 
2 
3    // Create a Calendar instance and render it into the body  
4    // element of the Overlay. 
5 
6    var oCalendar = new YAHOO.widget.Calendar("buttoncalendar", oCalendarMenu.body.id); 
7 
8    oCalendar.render(); 
9 
10 
11    // Subscribe to the Calendar instance's "select" event to  
12    // update the Button instance's label when the user 
13    // selects a date. 
14 
15    oCalendar.selectEvent.subscribe(function (p_sType, p_aArgs) { 
16 
17        var aDate, 
18            nMonth, 
19            nDay, 
20            nYear; 
21 
22        if (p_aArgs) { 
23             
24            aDate = p_aArgs[0][0]; 
25 
26            nMonth = aDate[1]; 
27            nDay = aDate[2]; 
28            nYear = aDate[0]; 
29 
30            oButton.set("label", (nMonth + "/" + nDay + "/" + nYear)); 
31 
32 
33            // Sync the Calendar instance's selected date with the date form fields 
34 
35            Dom.get("month").selectedIndex = (nMonth - 1); 
36            Dom.get("day").selectedIndex = (nDay - 1); 
37            Dom.get("year").value = nYear; 
38 
39        } 
40         
41        oCalendarMenu.hide(); 
42     
43    }); 
44 
45 
46    // Pressing the Esc key will hide the Calendar Menu and send focus back to  
47    // its parent Button 
48 
49    Event.on(oCalendarMenu.element, "keydown"function (p_oEvent) { 
50     
51        if (Event.getCharCode(p_oEvent) === 27) { 
52            oCalendarMenu.hide(); 
53            this.focus(); 
54        } 
55     
56    }, nullthis); 
57     
58     
59    var focusDay = function () { 
60 
61        var oCalendarTBody = Dom.get("buttoncalendar").tBodies[0], 
62            aElements = oCalendarTBody.getElementsByTagName("a"), 
63            oAnchor; 
64 
65         
66        if (aElements.length > 0) { 
67         
68            Dom.batch(aElements, function (element) { 
69             
70                if (Dom.hasClass(element.parentNode, "today")) { 
71                    oAnchor = element; 
72                } 
73             
74            }); 
75             
76             
77            if (!oAnchor) { 
78                oAnchor = aElements[0]; 
79            } 
80 
81 
82            // Focus the anchor element using a timer since Calendar will try  
83            // to set focus to its next button by default 
84             
85            YAHOO.lang.later(0, oAnchor, function () { 
86                try { 
87                    oAnchor.focus(); 
88                } 
89                catch(e) {} 
90            }); 
91         
92        } 
93         
94    }; 
95 
96 
97    // Set focus to either the current day, or first day of the month in  
98    // the Calendar when it is made visible or the month changes 
99 
100    oCalendarMenu.subscribe("show", focusDay); 
101    oCalendar.renderEvent.subscribe(focusDay, oCalendar, true); 
102 
103 
104    // Give the Calendar an initial focus 
105     
106    focusDay.call(oCalendar); 
107 
108 
109    // Re-align the CalendarMenu to the Button to ensure that it is in the correct 
110    // position when it is initial made visible 
111     
112    oCalendarMenu.align(); 
113 
114 
115    // Unsubscribe from the "click" event so that this code is  
116    // only executed once 
117 
118    this.unsubscribe("click", onButtonClick); 
119 
120}; 
121 
122 
123/*
124    Add a listener for the "click" event.  This listener will be
125    used to defer the creation the Calendar instance until the 
126    first time the Button's Overlay instance is requested to be displayed
127    by the user.
128*/         
129 
130oButton.on("click", onButtonClick); 
view plain | print | ?

Configuration for This Example

You can load the necessary JavaScript and CSS for this example from Yahoo's servers. Click here to load the YUI Dependency Configurator with all of this example's dependencies preconfigured.

Copyright © 2009 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings