Recently, in my spare time, I’ve been working on a simple booking system for a friend of mine. I had the need to present a date selector using jQuery UI’s date picker, but I wanted to change the default behaviour as follows;
- Dates in the past can’t be selected and must be stylised
- Dates in the future can be selected, but the calendar should highlight any dates that are not available
- I don’t want to go hunting and changing my jQuery UI theme styles, nor do I want to modify any jQuery UI code
The starting point – vanilla datepicker
Adding the following code;
Provided the following default behaviour;
Disabling dates in the past and dates that have bookings already
So this part is pretty simple, the component provides us with two hooks of note – onChangeMonthYear which is fired when the user navigates the calendar between months or years etc (but not on first display) and the second – beforeShowDay, which is called before an actual day is rendered into the control and allows you to specify whether the date is available, any extra css to apply and a tooltip to show.
I could use the onChangeMonthYear event to load my known events via a JSON call and then check the variables in the beforeShowDay event, but to be honest I’m going to only be interested in future bookings and there aren’t going to be a massive volume. As such, I can afford to load all the events using a single ajax call during page start up and then interrogate the result in beforeShowDay.
So, my code to implement the datepicker now looks like this;
with the following function;
The component expects this function to return an array in the format of [<<availability>>, <<css>>, <<tooltip>>]. It’s worth noting that my availability data is stored as a JSON object in this hierarchy; (If there is an entry, that date is booked).
- DD = true
- DD = true
- eg: 2010
- 15 = true
- 16 = true
So, on the above code, lines 3+4 are defining the available and booked responses. Line 6-7 checks if the date being rendered is in the past, and if it is, it returns a booked result to prevent it from being selected. This now results in the following;
Notice that 1st Aug and 12 July are booked in this example.
Making it look how I want it.
This is all well and good, but I want past dates to appear as disabled and booked dates to appear with a red X through them, like this end result:
I’m pretty sure you already know the answer – the beforeShowDay event expects us to pass back availability, and extra CSS classes to apply plus any tooltip we want. So we change our function thus;
So we’re now returning the extra CSS. We define this extra CSS is our site’s stylesheet;
And voila, we get….
hmmm – not quite the desired result! The problem here is many of the styles are inherited from jquery UI, our reset.css and so on, and some of those styles are taking precedence over our new styles. As we are confident we want these attributes on this particular class, we can ensure they are applied with preference by adding the !important moniker to them in CSS;
And we get the desired result.
Of course, you’ll want to use filter:Alpha(Opacity=…. for internet explorer;