Theming the AjaxControlToolkit's Calendar Control
The calendar control that my team is using in our current web application is terrible for three reasons:
- it is ugly. Viewing the control reminds me of the first time I went back to Window's 95 after having upgraded to XP
- it opens the calendar control in a new browser instance (something our users hate)
- it has a lot of supporting, custom JavaScript that has had its fair share of bugs
If I am not mistaken, somehow the control survived the port from classic ASP to ASP.NET 1.1 and then again from ASP.NET 1.1 to ASP.NET 2.0. I have no idea where the control orignally came from, but it is time to get rid of it.
Live Demo (IE6, IE7, FF) | Download
So my latest research tasks was to look into replacing this legacy control with something a little hipper. I took a look at the AjaxControlToolkit's Calendar control to see if it was something we could use. Sure enough it was. It pops the control up without opening a new browser instance, it has a nice transition animation that plays as the user switches between months, and it was designed with visual customization in mind - it can easily be themed using CSS. This last point is great because the only issue my team has with this control is that the default theme is a little boring.
So while looking into how this new date picker control would integrate with our existing application, I also played around with changing the theme to something with a little more flash. Below are a few sample calendar themes. The first theme is one that I based on the YUI calendar control. The second one is based Telerik's RadCalendar control.
Just like when I was working with theming the TabContainer control, before I could create a custom theme, I needed to understand how the CSS classes mapped to the default Vista style calendar. So my first step was to use the IE Developer Toolbar to inspect the HTML and style's that are used for the default Vista style calendar. Here are the screenshots that were the output of this exercise. The regions with the blue border correspond to the class.
After I familiarized myself with the CSS classes, I then used the IE Developer Toolbar again to reverse engineer a few of couple of Calendar controls that I liked. I then went through the process of mapping these styles to the AjaxControlToolkit's Calendar classes. My team is pretty picky, so I doubt we will actually use either of these themes exactly as they appear here, but I figured I would post my work in case anyone can make use of it.
How to Specify a Custom Theme
Described below (taken from here) are the steps that need to be followed to apply a custom theme. You should take note that no matter what the Calendar.css class is pulled to the client the style classes defined in this file will be applied to your custom theme unless you specifically override the values. I found this a little annoying. A couple of times margins, padding or border widths were being taken from the default theme's stylesheet because I wasn't specifically setting them to zero. For me, it worked best to have the default stylesheet handy so I could see what the default styles were.
That's it. Enjoy!
Comments
Your blog ROCKS! I read it all the time. I use both IE Developer Toolbar and Firebug all the time to analyze the internals of controls, reverse engineer, and get my own ideas. I wish I had the extra time to post my findings. Thanks and keep up the great work. -Dan
This looks great! The only thing I dislike about this control is the way it behaves after the calendar becomes visible. I wish clicking outside of the calendar made it disappear. It seems to me like you *have* to choose a date to get the control to go away.
Thanks for sharing!
Josh, You can get the behavior youre looking for by making the activation button/icon an ImageButton control. (However, I agree with you, in that it should work that way even if you use a regular image with a click event.)
My personal gripe about the ACT Calendar control is that it is impossible to disable any dates. Since it is entirely rendered on the client, it should have a JavaScript callback function that you can specify, which would return true or false, depending on if the date is clickable or not. (That is exactly how the ASP.NET calendar control works server-side.)
Matt,
This is perfect! I was looking for something like this just this morning. Nice, appreciate the hard work you share with us!!
-brian
your web site and your approach is very nice. i like and i appriciate to you and your team for good work.
i have a problem with call theme on master page or web config. please send me some tutorial or any help.
Rgds
Naresh Kumar
@josh -
Yep, I agree. I wonder if there are any work arounds ...
Matt.
i dont see the todays date in other two calendar? is that possible to have?
thanks.
I want to display the same calender below the textbox where i click but calender displays back the other controls(like textboxx and dropdownlist) below the textbox.please give me a solution.
Matt,
All of your stuff that I have seen so far is great. The only problem I have had with some of your stylings is having my images show up in the header portion of the calendar control. Wondering if anyone else has had problems with this?
Nice article. I wonder if there is any way to stop the assembly from loading the default stylsheet? I want to control every aspect of the calendar and other controls, so Im defining styles for everything, but its still loading the default styles. Id like to get rid of that overhead.
Wow,..you are amazing dude,... i read all bout your posting.
Hi Matt,
If I place the calendar control inside a ListView, and the ListView table has the following style:
.dataTable , .dataTable th, .dataTable td
{
padding: 3px 6px 3px 6px;
border: 1px solid #C0C0C0;
border-collapse: collapse;
empty-cells: show;
}
the calendar control inherits the style for th and td.
Unfortunately my knowledge of CSS is a bit limited and I have been unable to work out how to override th and td in Calendar.css.
Any ideas?
Many thanks
Jeremy
@Jeremy -
Try using class names instead of the TH and TD references. Maybe something like
.dataTable, .dataTable .header, .dataTable .item
would work.
Matt.
Hi Matt,
Thanks very much - maybe I was just being lazy because I wanted to avoid inserting a class attribute in each and - with the ListView there are so many templates it gets very wearing making a change in ItemTemplate and forgetting to do the same in AlternatingTemplate.
Its a shame that the CalendarExtender uses th and td - it would be nicer if the control used the class method allowing the lazy developer to use "global" attributes.
Regards
Jeremy
I have downloaded the project from http://mattberseth.com/blog/2007/10/theming_the_ajaxcontroltoolkit.html.
When i built and run athe application i get the error
Could not load file or assembly System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 or one of its dependencies. The system cannot find the file specified. C:Documents and SettingsmansoorMy DocumentsVisual Studio 2005Projectscalendar_themeweb.config 30
How do i solve this.
Thanks.
JInga
Thanks matt..
That is great work, well still I have one Q.
I dont know how to do weekend style.
I had the same problem as Jeremy did above, but with a global thead rule in my CSS. I added the following rule to my calendar CSS and it fixed the header.
.yui thead {background-color:#f2f2f2; padding: 0;}
You should be able to do the same for TH and TD.
- Scott.
Hi Matt,
I have a calendar control on a page along with a textbox and listbox. The calendar control will sit behind the listbox if my listbox happens to be right where my calendar drops down. Have you found any tricks on how to make the calendar control be on top?
Thanks
Tina
CalendarExtender not displaying proper when i place inside a FormView. Any help regards this will be appreciated.