You are hereBlogs / Paul's blog / Create an Interactive Appointment Calendar
Create an Interactive Appointment Calendar
Need an appointment calendar for your web site or app? Use the Yahoo! User Interface. Yahoo! develops and uses this framework on its own web sites, and it is tested against "A-grade" browsers.
A demo and technical description follow after the jump. Contact me for rates and availability if you are interested in a custom appointment calendar for your web site.
Demo
I have preset a few dates as unavailable. Clicking on any available date will temporarily mark that date as unavailable, too. This particular example was developed for use by a charity.
Give a Day
Select a day to sponsor.
The unavailable dates reset when you reload the page; in an actual appointment calendar, you would save these dates in a database using AJAX or a form submission. You would most likely embed this in a form, or use it as the front of a multi-page form control.
Implementation
This is the same calendar component used on travel site Kayak and a number of other Web 2.0 sites. A small amount of code allows you to block out dates and create a booking calendar.
The first step is to import the necessary YUI libraries, which Yahoo hosts gratis on its reliable, fast CDN. Below, I demonstrate how to do this, but if you view the source of this page, you will see that I am using my own hosted version (a previous version, with modifications to the sam-skin CSS file).
The Code
Import the CSS and Javascript somewhere on your page:
<!-- Load CSS and Javascript libs from Yahoo CDN --> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.6.0/build/calendar/assets/skins/sam/calendar.css"> <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"></script>
Add markup to your page for the calendar. In the example, I use a container div to apply the YUI Skin (class yui-skin-sam). In a real app, you would probably apply this to the body or an existing, semantic container. Another div with ID "calContainer" will become our calendar control:
<div class="yui-skin-sam">
<h4>Give a Day</h4>
<p>Select a day to sponsor.</p>
<div id="calContainer"></div>
<div id="evtentries" class="bd"></div>
<br clear="all" />
</div>
Finally, instantiate the calendar and add the custom code for blocking out dates:
<script>
YAHOO.namespace("hope.calendar");
//get today's date so we can show the calendar for the current month.
YAHOO.hope.calendar.myTodaysDate = new Date();
/* For actual use, pull dates from a database on the server
* and stuff them in the below array.
*/
YAHOO.hope.calendar.myTakenDates = new Array("11/27/2008","11/15/2008","11/19/2008","12/16/2008","12/18/2008","1/4/2008");
/* Next, initialize the calendar, and run a special renderer to strip
* out the dates from the above array. Then, render the calendar.
* Use an event handler to push new dates into the array,
* and then rerender the calendar as above.
*/
// The init function is set up here and then run once the DOM is ready
YAHOO.hope.calendar.init = function() {
//substitute some ajax magic for the select handler in a production system
function mySelectHandler(type,args,obj) {
var selDate = this.toDate(args[0][0]);
YAHOO.hope.calendar.myTakenDates.push(selDate.getMonth()+1 + "/" + selDate.getDate() + "/" + selDate.getFullYear());
mySetUnavailable();
YAHOO.hope.calendar.cal.render(); //reinitialize to show new date as unavailable.
};
YAHOO.hope.calendar.cal = new YAHOO.widget.Calendar("cal","calContainer",
{mindate:YAHOO.hope.calendar.myTodaysDate});
YAHOO.hope.calendar.cal.selectEvent.subscribe(mySelectHandler, YAHOO.hope.calendar.cal, true);
//iterate through the unavailable dates and modify how they render
mySetUnavailable = function(){
for (var iii=0, jjj = YAHOO.hope.calendar.myTakenDates.length;iii<jjj;iii++){
YAHOO.hope.calendar.cal.addRenderer(YAHOO.hope.calendar.myTakenDates[iii], YAHOO.hope.calendar.cal.renderBodyCellRestricted);
}
};
mySetUnavailable();
YAHOO.hope.calendar.cal.render();
}
YAHOO.util.Event.onDOMReady(YAHOO.hope.calendar.init);
</script>
Exercise for the Reader
To get from the above demo to something workable you need:
- a persistent data store
- atomicity
- server-side validation
These are left as an exercise for the reader.
Alternatively, contact me for information on hiring Henrich Interactive to develop a custom booking calendar solution.




Post new comment