Ajaxtoolkit Calendar Extender close button and date restriction

ASP.NET AjaxToolkit Calendar extender is most used control from AjaxControlToolkit. However developers often give it up, because of some additional business requirements. Usually asp.net developers replace it with standard asp.net calendar control and UpdatePanel. However this is very slow solution, so in this article I'll show you how you can modify AjaxlControlToolkit Calendar Control Extender, so it fits your needs, without touching AjaxControlToolkit source code.

Let's build simple sample of Calendar extender:

<asp:ScriptManager ID="ScriptManager1" runat="server">

</asp:ScriptManager>

<table>

    <tr>

        <td>

            <asp:TextBox ID="txtDate" runat="server" Width="70"></asp:TextBox>

            <ajaxToolkit:CalendarExtender ID="ceCalendar" runat="server"

                PopupButtonID="ibtnCalendar"

                TargetControlID="txtDate">

            </ajaxToolkit:CalendarExtender> 

        </td>

        <td>

            <asp:ImageButton ID="ibtnCalendar" ImageUrl="~/images/CalendarIcon.jpg" Width="20px" runat="server" />

        </td>

    </tr>

</table>          

Ajaxtoolkit Calendar Simple Sample

Close Button

First of all they always want a close button. At least twice I had to give up for AjaxControlToolkit Calendar, because it doesn't have a close button. What if customer, doesn't want to pick a date, how he can close calendar? I usually reply, that you need to click outside of calendar control. Business guys said that this is not obvious. Calendar need to have close button, like a normal window! Let's give them close button.

To solve this problem we need king of javascript, JQuery (now recongnized even by Microsoft).

<script src="javascript/jquery-1.2.6.min.js" type="text/javascript"></script>

    <asp:PlaceHolder runat="server" Visible="false">

        <script src="javascript/jquery-1.2.6.min-vsdoc.js" type="text/javascript"></script>

    </asp:PlaceHolder>

First line includes jquery itself. Then I have PlaceHolder that doesn't generate any code, since it has Visible equal false. This is a bulletproof way of enabling jquery intellisense.

Let's put little cross in right top corner of calendar. If you inspect ajaxtoolkit calendar with firebug you will see that it consits of div#ceCalendar_container and inside two divs: div#ceCalendar_header and div#ceCalendar_body. So, we need to inject our little cross before those two divs. After we add div with little x, we need to bind handler which will close it onclick.

<script type="text/javascript">

    function GenerateCloseButton(sender, e)

    {                   

        if ($('#ajax__calendar_close_button').length == 0)

        {

            $(sender._header).before("<div id='ajax__calendar_close_button'>x</div>");                   

            $('#ajax__calendar_close_button').bind("click", sender, function(e) {

                e.data.hide();

            });

        }

    }

</script>

My close button is just a little x, however you can put any fancy image as background of div. Below is some basic css style for close button.

<style type="text/css">

    #ajax__calendar_close_button

    {   

        margin-right:5px;

        margin-left:auto;

        width:10px;

        font-weight:bold;

        cursor:pointer;       

        text-align:right;

    }

</style>

Last step, you need to bind GenerateCloseButton function to some event in AjaxControlToolkit Calendar. OnClientShown is the best event for this purpose:

<ajaxToolkit:CalendarExtender ID="ceCalendar" runat="server"

    PopupButtonID="ibtnCalendar"

    TargetControlID="txtDate"

    OnClientShown="GenerateCloseButton"

    >

</ajaxToolkit:CalendarExtender>

Ajaxtoolkit Calendar with close button

Date restrictions

Second most needed requirement is date restriction

The simplest solution is to check date in OnClientDateSelectionChanged event. However at this point you can't stop calendar from changing selected date and hinding itself. You can try to do some hacks like clear selected date and show calendar again, but this is not we are looking for. Calendar should not hide if I selected wrong date. It should not allow me to select date at all. Let's take a look at Ajaxtoolkit Calendar source code. We are not going to change it. We just take a look at it guts (AjaxControlToolkit source code). Let's open CalendarBehavior.js. It's easy to see that we need to intercept _cell_onclick event. Let's write our own _cell_onclick (we also need to overwrite _button_onblur, so calendar won't hide, when you click ok in alert window).

AjaxControlToolkit.CalendarBehavior.prototype._button_onblur_original = AjaxControlToolkit.CalendarBehavior.prototype._button_onblur;

AjaxControlToolkit.CalendarBehavior.prototype._button_onblur = function(e)

{

    if (!this._selectedDateChanging)

    {

        this._button_onblur_original(e);

    }

}

AjaxControlToolkit.CalendarBehavior.prototype._cell_onclick_original = AjaxControlToolkit.CalendarBehavior.prototype._cell_onclick;

AjaxControlToolkit.CalendarBehavior.prototype._cell_onclick = function(e)

{               

    var target = e.target;

    var today_date = new Date();

    if (target.date.getFullYear() < 2001)

    {

        this._selectedDateChanging = true;

        alert('Date should be greate than January 1, 2001!');

        this._selectedDateChanging = false;

        return;

    }

    if (target.date > today_date)

    {

        this._selectedDateChanging = true;

        alert('You can\'t choose date in future.');

        this._selectedDateChanging = false;

        return;

    }

 

    this._cell_onclick_original(e);

}

Ajaxtoolkit Calendar Simple Sample

Here a final source code of AjaxToolkit Calendar Extender Page


kick it on DotNetKicks.com


Monday, January 05, 2009 | Comments (17) | Add Comment

Comments

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

Thanks for sharing this great code, but i have two calendar extenders on the same page and the x is shown only in one of them how to change it to be displayed in both of them .

Thanks

3/12/2009 1:24:45 AM | by Asaad M. Chalabi
Gravatar

The easiest way is to create two different GenerateCloseButton javascript functions. For example, GenerateCloseButton1 and GenerateCloseButton2. Inside of each function replace ajax__calendar_close_button with ajax__calendar_close_button1 or ajax__calendar_close_button2 according to a function.

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

Hi,
I have used the above code and its working very fine. Only issue I have is, I want to decrease the time calender takes to open. On my system it takes around 3-4 seconds to open the calender. Any thing to decrease this time span???

Thanks in Advance...

4/15/2009 2:49:09 AM | by charan
Gravatar

Check how big is your view state. Try to disable it.

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

can the same close button be generated for asp.net calendar control.
if yes then how?

4/15/2009 10:19:35 PM | by Fenil
Gravatar

It is possible, but a little bit more difficult. Regular asp.net calendar control is full postback driven control. So, you need to inject close button and connect it with server side event. Let me know if you need more details. I'll try then to implement this solution.

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

Hey
thank u very much work great in control with popoup id but calender with no pop up id the hide method does not work

5/4/2009 11:50:44 PM | by eyal
Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

Thx for a great solution which works perfectly. However in our current solution we have an implementation where we use the altered calendarcontrol in a listview (in the itemtemplate).

Can you give me any pointers on how to alter the changes so that a unique id is generated for the javascript. Otherwise only the first calendar in the listview gets the extra x.

Any ideas on how to handle this, cause we can't create xx number of functions...

TIA

5/6/2009 6:24:08 AM | by Gunther
Gravatar

Usually, if id method doesn't work then it is time to switch to classes approach :-). Here it is:

.ajax__calendar_close_button
{
margin-right:5px;
margin-left:auto;
width:10px;
font-weight:bold;
cursor:pointer;
text-align:right;
}


function GenerateCloseButton(sender, e)
{
if ($(sender._popupDiv).children('.ajax__calendar_close_button').length == 0)
{
$(sender._header).before("<div class='ajax__calendar_close_button'>x</div>");
$(sender._popupDiv).children('.ajax__calendar_close_button').bind("click", sender, function(e)
{
e.data.hide();
});
}
}

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

I tryed this looks great but the hide command does not work ??
Can u help ?

7/12/2009 11:17:27 PM | by Eyal
Gravatar

Sure, try to trace your javascript first. You can use Firefox FireBug console.log for this purpose. Make sure that your click event is called. Try to trace object itself. In firebug console mode try to execute hide manually.

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

I have a page that uses 2 CaledarExtender Calendars

The first i want to default to todays date if none chosen, I cant see how the SelectedDate server tag can be used for this.

the second i want to restrict any date previous to the first Calenders Chosen date.

It it possible with your date restriction to conect the second calender to the value in the first, so a date previous to the first calender can not be chosen

7/25/2009 12:53:50 PM | by Chris
Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

Nice stuff man! it works like a swiss watch!

9/8/2009 9:39:14 AM | by Juan
Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

Thanks for posting the nice stuff.
I am struggling with AjaxControlToolkit.CalendarBehavior.prototype.get_isOpen() method. I actually want to check in a JS method whether the calendar is open or not at that point of time, but this method always returns 'undefined'. can you please help?

9/15/2009 1:26:30 AM | by Bhavuk
Gravatar

Hi,

Use sender.get_isOpen(). Prototype keyword is only for declaration purposes. You can save sender in global variable and then use it anywhere in your code. Use firebug console window for your tests.

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

Great Job

But how to use it in GridView ??

11/1/2009 9:54:53 PM | by hardik
Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

I have got it man..
Grea Post

11/1/2009 10:08:45 PM | by hardik
Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

its very good job ,with nice creation ,thank you man alot

11/9/2009 1:37:49 AM | by paul makram
Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

Thanks for posting the nice stuff.

I need to open calendar in both TargetControlID and PopupButtonID.Howz it's possoble thanks in advance.

11/17/2009 8:12:10 PM | by deepak
Gravatar

Set BehaviorID for your calendar. For example, BehaviorID="calendarJS". Then you can manually show calendar using following technique:

$("#btnTest").bind("click",null,function (e) { $find("calendarJS").show(); });

Use OnClientClick for asp.net buttons:

<asp:Button ID="btnTest" runat="server" Text="Test" OnClientClick="$find("calendarJS").show();return false;" />

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

Hi I would like to use the calendar to select only the month. I mean, I intercept the cell_onclick property, look at the date and then i want to close (hide) the calendar. Is there any way to hide the calendar after the user has selected a month in the month "view ", without opening the day "view" ?

11/30/2009 12:39:40 AM | by Ionut
Gravatar

Sure it's possible. Add following to GenerateCloseButton function:

sender._switchMode("months",true);

and then:

AjaxControlToolkit.CalendarBehavior.prototype._cell_onclick = function(e)
{
var target = e.target;
var month =target.date.getMonth());
this.hide();
}

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

Thanks for posting such effective code.
My Question is that if I have two calenders on form
and I want to restric date of second cal is not less than date of first cal,how i do this?
Thanks in advance.

3/29/2010 1:36:50 AM | by Asif Iqbal Paracha
Gravatar

Set BehaviourID for your first calendar lets say to calendarJS1. Then you can get selected date using this command:

$find('calendarJS1')._visibleDate

Modify AjaxControlToolkit.CalendarBehavior.prototype._cell_onclick to use this date as restriction.

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

How about if I want the user to be able to enter data ONLY through the calendar extender. In all cases I've seen, the user could type in garbage, even after they've selected a date because random text entry in the target text box is perfectly legal.

4/13/2010 3:02:50 PM | by urbanek
Gravatar

There are a few different solutions to this problem:

1. You can use regular expression validator or compare validator to prevent garbage in textbox

2. Using JavaScript you can disable focus on text box. Just hook up onfocus event and redirect focus to DatePicker button for example.

3. Try to attach textbox to maskeditextender. I never tried it before, but it might work.

Personally I prefer first solution.

Gravatar

Re:Ajaxtoolkit Calendar Extender close button and date restriction

I have a problem in the above code.It will compare the time with current time with default time.for example it will compare Fri Apr 30 09:30 with Fri Apr 30 12:00.I want to compare date only.please help me

4/29/2010 9:28:48 PM | by S.Subha
Gravatar

Use ToShortDateString method to convert your dates and then String.Compare to compare.

New Comment

Your Name:
Email (for internal use only):
Subject:
Comment:
 
Code above:

Categories

Recent Tweets

Valid XHTML 1.0 Transitional