Customizing the jQuery-UI Datepicker

2010-08-30

I had a few requirements to implement last week involving an inline jQuery datepicker widget that were not natively supported, so I thought I'd share my workarounds. The datepicker widget is being used as a navigation aid to a calendar of events. The full code is at the bottom of the post. There's currently no example page (yet) but I intend to add one in a later update.

Unsupported Requirements

  1. Clickable calendar headings
  2. Ability to select a week at a time

Clickable headings

First off, the users wanted to be able to click the month/year title bar and jump to that month's calendar events. I figured that would be straightforward to implement with a click event on the .ui-datepicker-title div, but unfortunately that only works for the original title that's displayed. If you navigate to a different month, that event is lost. I ended up settling on using the (very cool) .live selector to make sure whatever was in any element matching that class selector had the same click event applied to it.

$('.ui-datepicker-title').live('click', function(){
    window.location = myUrl + $.datepicker.formatDate('yy/mm', myDate);
});

In the code above, myUrl is the location of the calendar of events page, and myDate is the currently-selected date. I use a callback function defined in the datepicker itself (using the onChangeMonthYear option) to keep myDate accurate:

onChangeMonthYear: function(year, month) {
    myDate.setFullYear(year);
    myDate.setMonth(month - 1);
},

Selecting a week at a time

The final tweak from the requirements document was that the users of the system wanted to be able to select entire weeks at a time. I had previously set up the site so myUrl/week/YYYY/MM/DD would display the events for a the week starting with the passed date, so all we needed was a way to trigger that selection from the datepicker.

After digging through the docs I finally settled on the optional calculateWeek callback option, I just chose to take it in a different direction than (I'm sure) its creators intended.

calculateWeek: function(date) {
    return '<a href="' + myUrl + 'week/' + $.datepicker.formatDate('yy/mm/dd', date) + '">»</a&gt:';
}

Here, instead of an alternate method of calculating the week, I chose to scrap that entirely and had the function output a link tag instead, and that combined with the showWeek option means I got free "view week" links prepended to each week of the datepicker.

Final Code

Final notes: if you want to start out on a different date other than current, pass that date into the Date constructor on the first line. The code below also assumes that your datepicker lives inside of a div with an ID of #cal.

var myDate = new Date();
var myUrl = '/your/calendar/url/goes/here';

$(document).ready(function() {
    $("#cal").html('');
    $("#cal").datepicker({
        defaultDate: myDate,
        dateFormat: 'yy/mm/dd',
        gotoCurrent: true,
        dayNamesMin: ['Su', 'M', 'T', 'W', 'Th', 'F', 'Sa'],
        numberOfMonths: 1,
        prevText: '',
        nextText: '',
        showWeek: true,
        firstDay: 0,
        onSelect: function(date) {
            window.location = myUrl + date;
        },
        onChangeMonthYear: function(year, month) {
            myDate.setFullYear(year);
            myDate.setMonth(month - 1); //JS months run from 0-11
        },
        calculateWeek: function(date) {
             return '<a href="' + myUrl + 'week/' + $.datepicker.formatDate('yy/mm/dd', date) + '">»</a>';
        }
    });
}

$('.ui-datepicker-title').live('click', function(){
    window.location = myUrl + $.datepicker.formatDate('yy/mm', myDate);
});

Tags: jquery

Comments