YUI Calendar Popup from Text Input
October 19th, 2008I needed a way to provide my users with a date picker that was automatically provided when a text area received focus. I was eager to use the excellent YUI calendar as a starting point, but the provided documentation didn’t provide a solid example for this type of implementation.
Dav Glass has provided a solid example of the Calendar tied to a text input. But, his example is highly dependent on the text input having specific ids. This doesn’t take advantage of YUI’s excellent Selector library really didn’t meet my need for a simple universal solution.
Key Requirements:
- Progressive Enhancement (No inline javascript)
- Yui based
- Universal implementation across all pages in a site.
- Support for multiple date inputs on a page.
Getting Started:
The bulk of the code used is pretty solidly Dav’s I’ve simply replaced all of the hard coded references to dynamically generated targets and moved from hard coded ID’s for the target fields to a css class. Lastly, I’ve added a “activeCal” class to the currently active target input so that one calendar can be recycled across multiple text areas on the page.
Source:
var cal1;
var over_cal = false;
function transmogCals() {
cal1 = new YAHOO.widget.Calendar(”cal1″,”cal1Container”);
cal1.selectEvent.subscribe(getDate, cal1, true);
cal1.renderEvent.subscribe(setupListeners, cal1, true);
var pickers = YAHOO.util.Selector.query(’.date-picker’);
for( i in pickers){
YAHOO.util.Event.addListener(pickers[i], ‘focus’, showCal);
YAHOO.util.Event.addListener(pickers[i], ‘blur’, hideCal);
}
cal1.render();
}
function setupListeners() {
YAHOO.util.Event.addListener(’cal1Container’, ‘mouseover’, overCal);
YAHOO.util.Event.addListener(’cal1Container’, ‘mouseout’, outCal);
}
function getDate() {
var calDate = this.getSelectedDates()[0];
calDate = (calDate.getMonth() + 1) + ‘/’ + calDate.getDate() + ‘/’ + calDate.getFullYear();
YAHOO.util.Selector.query(’.activeCal’)[0].value = calDate;
over_cal = false;
hideCal();
}
function showCal(e, targ) {
var xy = YAHOO.util.Dom.getXY(this);
var el = new YAHOO.util.Element(this);
el.addClass(’activeCal’);
var date = this.value;
if (date) {
cal1.cfg.setProperty(’selected’, date);
cal1.cfg.setProperty(’pagedate’, new Date(date), true);
cal1.render();
}
YAHOO.util.Dom.setStyle(’cal1Container’, ‘display’, ‘block’);
xy[1] = xy[1] + 20;
YAHOO.util.Dom.setXY(’cal1Container’, xy);
}
function hideCal() {
if (!over_cal) {
var el = new YAHOO.util.Element(this);
el.removeClass(’activeCal’);
YAHOO.util.Dom.setStyle(’cal1Container’, ‘display’, ‘none’);
}
}
function overCal() {
over_cal = true;
}
function outCal() {
over_cal = false;
}
YAHOO.util.Event.addListener(window, ‘load’, transmogCals);
Adding it to your page
Integrating the code into the page is VERY easy.
In the header of the page add the following css includes.
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.6.0/build/calendar/assets/skins/sam/calendar.css">
In the footer add the following script include and include the date-picker.js file
| <script type=“text/javascript” src=“http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/calendar/calendar-min.js&2.6.0/build/selector/selector-beta-min.js”></script> |
Lastly, place a class of date-picker to any text fields you want to tie to the input and add the following to your pages markup:
<div class=’yui-skin-sam’ style=”position:absolute; left:-1000px;”>
<div id=”cal1Container”></div>
</div>


Previous Post
Next Post

7 Comments
October 24th, 2008 at 2:28 pm
[...] 2008年10月22日 14:28 | マルコフ 未分類 | YUI 【YUI Calendar Popup from Text Input】←というページを発見!! [...]
October 25th, 2008 at 4:51 am
[...] 2008年10月23日 4:51 | マルコフ 未分類 | YUI 【YUI Calendar Popup from Text Input】←というページを発見!! [...]
November 3rd, 2008 at 12:06 pm
[...] 2008年11月1日 12:05 | マルコフ 未分類 | YUI 【YUI Calendar Popup from Text Input】←というページを発見!! [...]
November 3rd, 2008 at 6:40 pm
[...] 2008年11月1日 18:40 | マルコフ 未分類 | YUI 【YUI Calendar Popup from Text Input】←というページを発見!! [...]
December 19th, 2008 at 1:50 pm
Nice implementation, but I’m having an issue with multiple date inputs on a page. For example, I have a basic test page with 3 text fields. The script works properly on #1, but when I pick dates for input #2 and #3, the date in #1 is updated instead. They all have unique name & id, and from what I can see in Firebug the activeCal class is being moved properly on focus/blur. Any ideas?
December 19th, 2008 at 4:15 pm
Thanks for pointing this out, it’s definitely a bug. When I get home tonight I’ll look into it some more.
December 25th, 2008 at 1:39 pm
Don:
Great article. Thanks.
Chris/Don:
It doesn’t look like removeClass in hideCal is behaving. Since ‘element’ is still beta, this may be a bug. I just remove activeCal from ALL of the Inputs during hideCal.
In hideCal, replace:
var el = new YAHOO.util.Element(this);
el.removeClass(’activeCal’);
YAHOO.util.Dom.setStyle(’cal1Container’, ‘display’, ‘none’);
With this:
var els = new YAHOO.util.Selector.query(’input.activeCal’);
YAHOO.util.Dom.removeClass(els, ‘activeCal’);
YAHOO.util.Dom.setStyle(’cal1Container’, ‘display’, ‘none’);
Merry Christmas.
~ Garth
Leave a Reply