You are hereBlogs / Paul's blog / Create an Interactive Appointment Calendar

Create an Interactive Appointment Calendar


By Paul - Posted on 02 November 2008

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.

Trackback URL for this post:

http://www.paulreads.com/trackback/19083

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <p>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
Not required for registered users. This spam-reducing system helps Carnegie Melon digitize and preserve old books.