How to patch the Ajax Control Toolkit CalendarExtender to add Decade support and InitialView – Part 4

Missed the rest of the article? Click here for Part 1

Ok, so now we have a decade view. If you keep clicking on the title of the calendar, you’ll eventually get to decade view. Hopefully it works as good for you as it does for me.

Next step is to create an InitialView so that you can set the calendar to show the Decade when you first click the calendar image.

To add any class that you want to have access on both the server and the client, you need to add a class file to the Calendar folder. I simply right-clicked on the CalendarPosition.cs file, then clicked Copy. Then I Pasted the file into the Calendar folder, and renamed it “InitialView”.

Initial View cs file

Initial View cs file

Now we need an enumeration so that we can set the view.  Change the code in the file so that the class name is InitialView, and it contains Day, Month, Year and Decade, as follows:

//S2 - Add Initial View so that you can choose a starting view for your date selection. You might want to do this
//so that selection of the date is more efficient.</pre>
namespace AjaxControlToolkit
{
    /// <summary>
    /// The initial view of the calendar
    /// </summary>
    public enum InitialView
    {
        Day = 0,
        Month = 1,
        Year = 2,
        Decade = 3
    }
}
//E2

Again, we are really just copying the CalendarPosition enumeration. To get this to be recognised in javascript, copy the three code blocks that make up the client side javascript block for CalendarPosition, then modify the code to be consistent with the InitialView that we are trying to achieve.

Original code:

AjaxControlToolkit.CalendarPosition = function() {
    /// <summary>
    /// Position of the popup relative to the target control
    /// </summary>
    /// <field name="BottomLeft" type="Number" integer="true" />
    /// <field name="BottomRight" type="Number" integer="true" />
    /// <field name="TopLeft" type="Number" integer="true" />
    /// <field name="TopRight" type="Number" integer="true" />
    /// <field name="Right" type="Number" integer="true" />
    /// <field name="Left" type="Number" integer="true" />
    throw Error.invalidOperation();
}
AjaxControlToolkit.CalendarPosition.prototype = {
    BottomLeft: 0,
    BottomRight: 1,
    TopLeft: 2,
    TopRight: 3,
    Right: 4,
    Left: 5
}
AjaxControlToolkit.CalendarPosition.registerEnum('AjaxControlToolkit.CalendarPosition');

 Additional code, add at the bottom of the CalendarBehavior.js file just below the code for registering the CalendarPosition enum:

//S2 Initial View. This is the code that synchronises the server side enum with the client side enum
AjaxControlToolkit.InitialView = function() {
    /// <summary>
    /// View of the calendar opened when the user selects the calendar
    /// </summary>
    /// <field name="Day" type="Number" integer="true" />
    /// <field name="Month" type="Number" integer="true" />
    /// <field name="Year" type="Number" integer="true" />
    /// <field name="Decade" type="Number" integer="true" />
    throw Error.invalidOperation();
}
AjaxControlToolkit.InitialView.prototype = {
    Day: 0,
    Month: 1,
    Year: 2,
    Decade: 3
}
AjaxControlToolkit.InitialView.registerEnum('AjaxControlToolkit.InitialView');
//E2

Still in the CalendarBehavior.js file, scroll to the top. We need to declare the _initialView variable and set it’s initial default value. Find the code that initialises the popup position. This is how the default Calendar Position is set. It is also the variable that we are copying.

Original code:

this._popupPosition = AjaxControlToolkit.CalendarPosition.BottomLeft;

Modified code:

this._popupPosition = AjaxControlToolkit.CalendarPosition.BottomLeft;
//S2 - set the initial default in javascript
this._initialView = AjaxControlToolkit.InitialView.Day;
//E2

To be consistent with the other client script variables, we create getters and setters. Simply copy the ones for popupPosition:

Original code:

 get_popupPosition: function() {
   /// <value type="AjaxControlToolkit.CalendarPosition">
   /// Where the popup should be positioned relative to the target control.
   /// Can be BottomLeft (Default), BottomRight, TopLeft, TopRight.
   /// </value>
   return this._popupPosition;
},
set_popupPosition: function(value) {
  if (this._popupPosition != value) {
    this._popupPosition = value;
    this.raisePropertyChanged('popupPosition');
  }
},

 

Modified code:

 get_popupPosition: function() {
   /// <value type="AjaxControlToolkit.CalendarPosition">
   /// Where the popup should be positioned relative to the target control.
   /// Can be BottomLeft (Default), BottomRight, TopLeft, TopRight.
   /// </value>
   return this._popupPosition;
},
set_popupPosition: function(value) {
  if (this._popupPosition != value) {
    this._popupPosition = value;
    this.raisePropertyChanged('popupPosition');
  }
},
//S2 - set and get variables for javascript initialView, copied off first day of week
get_initialView: function() {
  /// <value type="AjaxControlToolkit.InitialView">
  /// The initial view of the calendar, day, month, year or decade
  /// </value>
  return this._initialView;
},
set_initialView: function(value) {
  if (this._initialView != value) {
     this._initialView = value;
     this.invalidate();
     this.raisePropertyChanged("initialView");
  }
},
//E2

The final bit of javascript code is where we switch between modes of the calendar. This occurs in the show function. Basically, when the calendar needs to show, it calls the method this._switchMonth(null, true); so that the correct month is selected in the calendar. I think we should leave this to do it’s work. Instead, I will use the internal function _switchMode to switch between the different calendar views.

Original code:

show: function() {
  /// <summary>
  /// Shows the calendar
  /// </summary>
 

  this._ensureCalendar();

  if (!this._isOpen) {

     var eventArgs = new Sys.CancelEventArgs();
     this.raiseShowing(eventArgs);
     if (eventArgs.get_cancel()) {
        return;
     }

     this._isOpen = true;
     this._switchMonth(null, true);
     this._popupBehavior.show();
     this.raiseShown();
   }
},

Modified code:

show: function() {
  /// <summary>
  /// Shows the calendar
  /// </summary>
 

  this._ensureCalendar();

  if (!this._isOpen) {

     var eventArgs = new Sys.CancelEventArgs();
     this.raiseShowing(eventArgs);
     if (eventArgs.get_cancel()) {
        return;
     }

     this._isOpen = true;
     this._switchMonth(null, true);
     //S2 - We've let the code create the calendar, now switch the calendar to the initial view that we want.
     //Note that we only want this to happen if a date has not already been selected, as they may want to
     //change only some of the date
     if (this._selectedDate == null) {
        var _initialView = this.get_initialView();
        switch (_initialView) {
           case AjaxControlToolkit.InitialView.Day:
              this._switchMode("days");
              break;
           case AjaxControlToolkit.InitialView.Month:
              this._switchMode("months");
              break;
           case AjaxControlToolkit.InitialView.Year:
              this._switchMode("years");
              break;
           case AjaxControlToolkit.InitialView.Decade:
              this._switchMode("decades");
              break;
         }
     }
     //E2           
     this._popupBehavior.show();
     this.raiseShown();
   }
},

Now the last thing we need to do is to ensure that there is a method of setting the InitialView on the calendar extender. This is done in the CalendarExtender.cs file.

Scroll down to the code that handles to PopupPosition property. Copy and Paste that, and rename CalendarPosition to InitialView, popupPosition to initialView (case sensitive) and set the default value to InitialView.Day. It should now look like the following:

 //S2 - This is how to get a variable from the server to the client.
[DefaultValue(InitialView.Day)]
[ExtenderControlProperty]
[ClientPropertyName("initialView")]
public virtual InitialView InitialView
{
  get { return GetPropertyValue("InitialView", InitialView.Day); }
  set { SetPropertyValue("InitialView", value); }
}
//E2

Add a text box to a page, attach a calendar extender, then add the attribute InitialView=”Decade” and when you click on the calendar, it will open in decade view. But it will only do this if there isn’t a date already selected. If there is a date already in the text box, then the calendar will open in Day view. This is by design.

Remember to update the assembly version. This is a custom variation to the AjaxControlToolkit, so we don’t want it pretending it’s the original. Under the properties folder in the AjaxControlToolkit project, double-click on the AssemblyInfo.cs file. Change the AssemblyVersion and AssemblyFileVersion attributes. I changed mine as follows:

[assembly: AssemblyVersion("3.0.20822.*")]
[assembly: AssemblyFileVersion("3.0.20822.0")]

And that’s pretty much it!

Got messed up somewhere along the line? Here’s the source code complete with patch so you can see where you went wrong. http://cid-5e237543fffb2891.skydrive.live.com/self.aspx/Public/DecadeView.zip

One Response to How to patch the Ajax Control Toolkit CalendarExtender to add Decade support and InitialView – Part 4

  1. […] Click for Part 4 >> Possibly related posts: (automatically generated)6 Ways to Break the Da Vinci Code […]

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: