KARPACH

WEB DEVELOPER BLOG

Ajaxtoolkit Calendar Extender close button and date restriction

ASP.NET AjaxToolkit Calendar extender is the 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 a 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 a simple sample of a 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, users always want a close button. At least twice I had to give up an AjaxControlToolkit Calendar control because it doesn’t have a close button. What if a customer, doesn’t want to pick a date, how they can close a calendar? I usually reply that you need to click outside of calendar control. Business guys said that this is not obvious. The calendar needs to have a close button, like a normal window! Let’s give them a close button.

To solve this problem we need a king of javascript, JQuery (now, recognized 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>

The first line includes jquery itself. Then I have PlaceHolder that doesn’t generate any code since it has a Visible attribute equal to false. This is a bulletproof way of enabling jquery IntelliSense.

Let’s put a little cross in the right top corner of the calendar control. If you inspect the Ajaxtoolkit calendar with FireBug you will see that it consists of div#ceCalendar_container and inside of two divs: div#ceCalendar_header and div#ceCalendar_body. So, we need to inject our little cross before those two div tags. After we add div with little x, we need to bind a handler which will close it on click.

<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 a background image of div. Below is some basic CSS style for a 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, a most needed requirement is date restriction

The simplest solution is to check a date in OnClientDateSelectionChanged event. However, at this point, you can’t stop a calendar from changing a selected date and hiding itself. You can try to do some hacks like clear the selected date and show the calendar again, but this is not what we are looking for. The calendar control should not hide if I selected the wrong date. It should not allow me to select a 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 its 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 the calendar won’t hide, when you click ok in the 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

Posted on January 5, 2009 by

Comments

Posted on 3/12/2009 01:24:45 AM by Asaad M. Chalabi

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

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.

Posted on 4/15/2009 02:49:09 AM by charan

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…

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

Posted on 4/15/2009 10:19:35 PM by Fenil

can the same close button be generated for asp.net calendar control.

if yes then how?

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.

Posted on 5/4/2009 11:50:44 PM by eyal

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

Posted on 5/6/2009 06:24:08 AM by Gunther

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

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(&quot;&lt;div class='ajax__calendar_close_button'&gt;x&lt;/div&gt;&quot;);  
        $(sender._popupDiv).children('.ajax__calendar_close_button').bind(&quot;click&quot;, sender, function(e)  
        {  
            e.data.hide();  
        });              
    }  
}

Posted on 7/12/2009 11:17:27 PM by Eyal

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

Can u help ?

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.

Posted on 7/25/2009 12:53:50 PM by Chris

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

Posted on 9/8/2009 09:39:14 AM by Juan

Nice stuff man! it works like a swiss watch!

Posted on 9/15/2009 01:26:30 AM by Bhavuk

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?

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.

Posted on 11/1/2009 09:54:53 PM by hardik

Great Job

But how to use it in GridView ??

Posted on 11/1/2009 10:08:45 PM by hardik

I have got it man..

Grea Post

Posted on 11/9/2009 01:37:49 AM by paul makram

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

Posted on 11/17/2009 08:12:10 PM by deepak

Thanks for posting the nice stuff.

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

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;" />

Posted on 11/30/2009 12:39:40 AM by Ionut

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” ?

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();  
}

Posted on 3/29/2010 01:36:50 AM by Asif Iqbal Paracha

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.

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.

Posted on 4/13/2010 03:02:50 PM by urbanek

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.

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.

Posted on 4/29/2010 09:28:48 PM by S.Subha

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
Use ToShortDateString method to convert your dates and then String.Compare to compare.

Posted on 8/10/2010 04:36:39 AM by hemasekhar

Hi,

This is sekhar.iam having a problem in calender control. i want to display a calender.when we click on the date it should display a jpg files. it means when we click on the 10/8/2010 it should display a cart.jpg file and the next day it should display another jpg file.can any one help me………….

Posted on 9/10/2010 12:20:22 AM by Satish Deverkonda

How can i restrict user so that user cannot select date 45 days older than current date ……….please help me out any one…

Posted on 9/19/2010 08:25:36 AM by vasanth

Hi,

I’m Using ASP.net Ajaxtoolkit Calendar Extender in Update panel, How to set the Close button?

Posted on 10/4/2010 04:42:21 AM by Prateek

Hi when i m using ur code on a page its showing error,error is “Sys.Extended.UI.TextboxWrapper is Null or not an object”

plse tell me where is prob??

Posted on 12/9/2010 10:44:54 PM by Vijay

I’m using an Ajax Calandar Controll Extender inside Update Panel. I need to disable all the Dates except the Month before, Current Month and the Next Month. Can anybody give a Solution.

Thanks in Advance

Posted on 2/16/2011 05:30:33 AM by Victoria

Thanks for that example. I’ was looking all over on how to disable not wanted dates. I’m trying to implement this for .net 4.0 so I changed it to using from ScriptManager to ToolkitScriptManager and now I get a javascript error AjaxControlToolkit is undefined. Is there a way to do it for 4.0? Please help. Thanks!

Posted on 2/16/2011 10:52:10 PM by Asmasm

I’m unable to get the value of textbox what to do as the value gets cleared during postback?

And i also want to display in dd-mm-yy format and save in dbase as mm-dd-yy format

Plz help me

Posted on 3/1/2011 07:14:45 AM by Alaa

How can i get Date Part without Time from calender?
I am not sure if I understand your question correctly, but you can use ToShortDateString method.

Posted on 4/3/2011 12:16:18 AM by AlaskanShade

I took your example and went a couple steps farther. The final code is a bit too much to post here. First, I added min and max attributes to my textbox on the server side and use those for checking valid dates. Then I set onclick and onmouseover to simple cancel out if the date is out of range (which conveniently stops the user from scrolling past the range as well) and overrode _getCssClass to set a disabled style on any day that is out of range. There were a couple details to fix up, but I am really happy with the result. Thanks for posting this.

Posted on 4/11/2011 11:32:16 PM by Mihir

am i suppose to change the actual javascript which is provided by AJAX toolkit for date rane?
No you do not need to change actual ajax toolkit script. Use it only for your injection reference.

Posted on 4/27/2011 03:57:13 PM by Reuven Nissan

Very good article. I have used Some of your code to many things and I find it so much needed!

Posted on 5/9/2011 11:29:25 PM by dip

Hi,

if ($(sender._popupDiv).children('.ajax__calendar_close_button').length == 0)

I am getting js error in this live…i cant use firefox,,,the application run only in ie…

the error is..—-

“Microsoft JScript runtime error: Object expected”

then if i click on continue, the is opening but without X buuton….please help me….

Posted on 5/11/2011 06:02:48 AM by damu

yes: it is really good job

Posted on 7/12/2011 03:05:16 AM by Bhavin

I want to use this calender extender with input box of html same as we use for asp:textbox in asp.net.how can be it possible?
I think it is not possible by definition of calendar extender. Try to use jQuery plugins for this purpose.

Posted on 7/20/2011 05:37:26 AM by Tejas

I want to strike out date less then today’s date in calenderextender is that possible to do.Help me.
Yes, it is possible. Read my tutorial.

Posted on 7/26/2011 11:07:50 AM by hassan mohamed

last two weeks have been struggling to do confirm before changing date in text box!! let me download jquery and come to you later, thanks great job

Posted on 7/26/2011 03:21:45 PM by hassan mohamed

thanks this is great i have downloaded it and it worked fine; but how about using it inside gridview templated field (for edit) when i want to check before updating a date already in the grid; i cannot use attributes.add to the extender at rowdatabound event

Posted on 7/30/2011 02:59:39 AM by Bilal

I want to show dates by weeks…Simple saying i want to show weeks in calender. Can any body help me???
I think it is possible, but would be really difficult.

Posted on 8/22/2011 03:53:59 PM by mobibb

I would like to get all of the code sample listed in the response “…and went a couple steps farther….” I need the min/max stuff and have two date fields with calendar controls.

Posted on 8/22/2011 05:01:20 PM by mobibb

Where can I get “jquery-1.4.1.min-vsdoc.js”?

I see jquery-1.4.1-vsdoc.js and jquery-1.4.1.min.js

Tried the posted code and the date restriction does NOT work.

You can get jQuery libs here http://www.asp.net/ajaxlibrary/cdn.ashx

Posted on 9/8/2011 07:43:37 AM by galvin verghese

I am using your same code for display the close button in calendarextender control. But is now showing the cross button sign and when i check with firebug it will give an error in the line.

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

$ is not defined. so how can i solve this. Please tell me.

Posted on 9/23/2011 02:53:54 AM by ramya

i use ajaxcalenderexdender but when click textbox calender not popup how pick date to textbox ??????

Posted on 9/29/2011 09:14:42 AM by charan

Thank you for nice post. I am not able to make it work. I am novice in asp.net, AJAX etc. Do I need to download JQuery to make it work? If yes, the link you have given for Jquery doesn’t have jquery-1.2.6.min.js Please clarify.
Any version of jquery is fine. Just change reference to proper version.

Posted on 11/13/2011 10:48:57 PM by Anup Dharia

Excellent thread!! Thnx a lot!!

Posted on 12/8/2011 03:58:27 AM by nuthan

no comments

i am facing problem with ajax calender extender

we have two modules,

i am using only one textbox and one ajax calender extender for both modules

i amm comparing through sessions if admin then or user then likewise i am doing

if i login with admin css style was not apply

if i login with user css style applied

plese help any one if you knw

i hope any one respond

Use firebug. See if css file is loaded. Try to move CSS to page head section. See if you are binding by id and id is changing if you are loggedin as admin. There are so many things that can go wrong.

Posted on 1/17/2012 05:34:07 AM by Rahul Kumar

Hi this blog is awesome but i want to disable the previous past dates form the ajax calendar. Please Let me Know how to do this or if you have any example.

Thanks

Rahul Kumar

Asp.net Developer

New Delhi, India

You can easily do you own date verification in AjaxControlToolkit.CalendarBehavior.prototype._cell_onclick function. Just compare target.date with today_date minus couple days.

Posted on 2/27/2012 02:47:16 AM by ragesh

Very helpful post.Thanks brother

Posted on 3/15/2012 08:36:19 AM by Roger

…Register Assembly=“AjaxControlToolkit” Namespace=“AjaxControlToolkit”…. but it’s giving me the following error:

Microsoft JScript runtime error: ‘AjaxControlToolkit’ is undefined

Posted on 3/26/2012 12:11:56 AM by kidmabagsik

Same as ragesh . . .

Register Assembly=“AjaxControlToolkit” Namespace=“AjaxControlToolkit”…. but it’s giving me the following error:

Microsoft JScript runtime error: ‘AjaxControlToolkit’ is undefined

Posted on 6/6/2012 11:45:26 AM by Ben

I have a calendar that I need to duplicate on a form via javascript clone. When this is done, the calendar that pops up is bound to the original textbox.

Is there away to change the targetcontrolID with javascript?

Great post BTW

I don’t know. Check source code.

Posted on 8/6/2012 03:38:21 AM by Adnan

Nice post,

one more question:

How to change the date format and how to change month names to specific language?

Thx

Posted on 8/23/2012 05:40:29 AM by yogendra

Hello,

it is nice post, can u put the code how to disable the date before the current date so user can select even he try .

thanks

Posted on 11/18/2012 08:21:09 AM by jan

hi, very good article. a doubt i’d like to clear though.

How to disable certain dates from database?

Posted on 11/20/2012 05:12:57 AM by Jure

For those who get ‘AjaxControlToolkit’ is undefined error: try replacing AjaxControlToolkit with Sys.Extended.UI

Posted on 11/24/2012 11:18:34 PM by Meenakshi Luthra

Hi, Can we close calender extender when user click anywhere on screen?

Posted on 3/4/2013 06:31:59 AM by Daren

Thanks for this, great solution! I also have the problem of two calendars on one page, and only one showing the “x”.

Could you please give an example of using GenerateCloseButton1 and GenerateCloseButton2 to put the “x” in both calendars. My drop down calendar is in a usercontrol which I use on other pages. Thanks.

See above my reply for Gunther

Posted on 3/4/2013 08:27:39 AM by Daren

Brilliant! Your solution for Gunther for multiple calendars on a page worked! I have my calendar in a usercontrol, and this solution works if I have to put the usercontrol on to a page several times. Thanks again.

Posted on 6/20/2013 07:09:03 AM by chellapandian

how to get textbox date using ajax calender exdender.. if post back form the textbox is empty… how to get the date…

pls help me

Posted on 1/2/2014 01:57:42 AM by Raghu

How to access selected date in the Javascript during “OnClientShown”

Posted on 7/14/2020 12:23:21 AM by vini

I downloaded the source code , but i want to restrict dates from a data table, where the admin tells 3 dates are holidays and no appointment to be made .. in this case how can i pass the values from data table to calender extender to disable those holidays dates