[Asp.netAjaxToolkit扩展]Calendar支持时间段
2010-07-16 16:14
435 查看
Asp.Net Ajax Control Toolkit中的Calendar是一个相当不错的日历控件。但是有些时候它却不能满足我们的要求,比如:这次客户要求不能选择当前日期以前的日期,只能点未来的日期。这个大家应该在酒店、航班等时效性要求比较强的网站上经常见到。之前的日期都加了个删除线,并且不能选择。
为了实现这个功能,又不想浪费这么好的Calendar控件功能。 怎么办呢?
原来,Asp.Net Ajax 为我们提供了扩展接口,方便我们对Asp.Net Ajax Control Toolkit的二次开发。
经过Google,在网上找到了一段原始代码,已经实现了,不能对之前的日期进行选择等功能。但是,在显示上,它却不能进行显示灰色,加上删除线。所以我进行的进一步的修改。代码如下(注:以下代码在VS2008 sp1 环境下编译通过):
---------------代码开始(Code Begin)----------------
CalendarCustom.cs代码如下:
--------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web.UI;
using AjaxControlToolkit;
[assembly: System.Web.UI.WebResource("Custom.CalendarExtender.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("Custom.Calendar.css", "text/css", PerformSubstitution = true)]
namespace Custom
{
[ClientCssResource("Custom.Calendar.css")]
[ClientScriptResource("Custom.CalendarExtender", "Custom.CalendarExtender.js")]
[ToolboxData("<{0}:CalendarExtender runat=server></{0}:CalendarExtender>")]
public class CalendarExtender : AjaxControlToolkit.CalendarExtender
{
[DefaultValue(null)]
[ExtenderControlProperty]
[ClientPropertyName("lowerBoundDate")]
public virtual DateTime? LowerBoundDate
{
get { return GetPropertyValue("LowerBoundDate", (DateTime?)null); }
set { SetPropertyValue("LowerBoundDate", value); }
}
[DefaultValue(null)]
[ExtenderControlProperty]
[ClientPropertyName("upperBoundDate")]
public virtual DateTime? UpperBoundDate
{
get { return GetPropertyValue("UpperBoundDate", (DateTime?)null ); }
set { SetPropertyValue("UpperBoundDate", value); }
}
public IEnumerable<ScriptReference> GetScriptReferences()
{
return new ScriptReference[] { new ScriptReference("Custom.CalendarExtender.js", "Custom") };
}
}
}
----------------------------
CalendarExtender.js代码如下:
----------------------------
// Register the namespace for the control.
Type.registerNamespace('Custom');
Custom.CalendarExtender = function(element) {
/// <summary>
/// A behavior that attaches a calendar date selector to a textbox
/// </summmary>
/// <param name="element" type="Sys.UI.DomElement">The element to attach to</param>
Custom.CalendarExtender.initializeBase(this, [element]);
this._lowerBoundDate = null;
this._upperBoundDate = null;
}
Custom.CalendarExtender.prototype = {
initialize: function() {
/// <summary>
/// Initializes the components and parameters for this behavior
/// </summary>
Custom.CalendarExtender.callBaseMethod(this, "initialize");
},
dispose: function() {
/// <summary>
/// Disposes this behavior's resources
/// </summary>
Custom.CalendarExtender.callBaseMethod(this, "dispose");
},
get_lowerBoundDate: function() {
/// <summary>
/// The date currently visible in the calendar
/// </summary>
/// <value type="Date" />
if (this._lowerBoundDate != null) {
return this._lowerBoundDate;
}
},
set_lowerBoundDate: function(value) {
if (value && (String.isInstanceOfType(value)) && (value.length != 0)) {
value = new Date(value);
}
if (value) value = value.getDateOnly();
if (this._lowerBoundDate != value) {
this._lowerBoundDate = value;
this.raisePropertyChanged("lowerBoundDate");
}
},
get_upperBoundDate: function() {
/// <value type="Date">
/// The date to use for "Today"
/// </value>
if (this._upperBoundDate != null) {
return this._upperBoundDate;
}
},
set_upperBoundDate: function(value) {
if (value && (String.isInstanceOfType(value)) && (value.length != 0)) {
value = new Date(value);
}
if (value) value = value.getDateOnly();
if (this._upperBoundDate != value) {
this._upperBoundDate = value;
this.raisePropertyChanged("upperBoundDate");
}
},
_performLayout: function() {
/// <summmary>
/// Updates the various views of the calendar to match the current selected and visible dates
/// </summary>
var elt = this.get_element();
if (!elt) return;
if (!this.get_isInitialized()) return;
if (!this._isOpen) return;
var dtf = Sys.CultureInfo.CurrentCulture.dateTimeFormat;
var selectedDate = this.get_selectedDate();
var visibleDate = this._getEffectiveVisibleDate();
var todaysDate = this.get_todaysDate();
switch (this._mode) {
case "days":
var firstDayOfWeek = this._getFirstDayOfWeek();
var daysToBacktrack = visibleDate.getDay() - firstDayOfWeek;
if (daysToBacktrack <= 0)
daysToBacktrack += 7;
var startDate = new Date(visibleDate.getFullYear(), visibleDate.getMonth(), visibleDate.getDate() - daysToBacktrack, this._hourOffsetForDst);
var currentDate = startDate;
for (var i = 0; i < 7; i++) {
var dayCell = this._daysTableHeaderRow.cells[i].firstChild;
if (dayCell.firstChild) {
dayCell.removeChild(dayCell.firstChild);
}
dayCell.appendChild(document.createTextNode(dtf.ShortestDayNames[(i + firstDayOfWeek) % 7]));
}
for (var week = 0; week < 6; week++) {
var weekRow = this._daysBody.rows[week];
for (var dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
var dayCell = weekRow.cells[dayOfWeek].firstChild;
if (dayCell.firstChild) {
dayCell.removeChild(dayCell.firstChild);
}
dayCell.appendChild(document.createTextNode(currentDate.getDate()));
dayCell.title = currentDate.localeFormat("D");
dayCell.date = currentDate;
//modify by arden 2008.8.21
$common.removeCssClasses(dayCell.parentNode, ["ajax__calendar_other", "ajax__calendar_disabled", "ajax__calendar_active", "custom__calendar_lower"]);
if (this._lowerBoundDate == null && this._upperBoundDate == null ) {
Sys.UI.DomElement.addCssClass(dayCell.parentNode, this._getCssClass(dayCell.date, 'd'));
}
else if ((this._upperBoundDate != null && currentDate > this._upperBoundDate) ||
(this._lowerBoundDate != null && currentDate < this._lowerBoundDate))
{
Sys.UI.DomElement.addCssClass(dayCell.parentNode, "custom__calendar_lower");
}
//modify end
currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + 1, this._hourOffsetForDst);
}
}
this._prevArrow.date = new Date(visibleDate.getFullYear(), visibleDate.getMonth() - 1, 1, this._hourOffsetForDst);
this._nextArrow.date = new Date(visibleDate.getFullYear(), visibleDate.getMonth() + 1, 1, this._hourOffsetForDst);
if (this._title.firstChild) {
this._title.removeChild(this._title.firstChild);
}
this._title.appendChild(document.createTextNode(visibleDate.localeFormat("MMMM, yyyy")));
this._title.date = visibleDate;
break;
case "months":
for (var i = 0; i < this._monthsBody.rows.length; i++) {
var row = this._monthsBody.rows[i];
for (var j = 0; j < row.cells.length; j++) {
var cell = row.cells[j].firstChild;
cell.date = new Date(visibleDate.getFullYear(), cell.month, 1, this._hourOffsetForDst);
cell.title = cell.date.localeFormat("Y");
$common.removeCssClasses(cell.parentNode, ["ajax__calendar_other", "ajax__calendar_disabled", "ajax__calendar_active"]);
Sys.UI.DomElement.addCssClass(cell.parentNode, this._getCssClass(cell.date, 'M'));
}
}
if (this._title.firstChild) {
this._title.removeChild(this._title.firstChild);
}
this._title.appendChild(document.createTextNode(visibleDate.localeFormat("yyyy")));
this._title.date = visibleDate;
this._prevArrow.date = new Date(visibleDate.getFullYear() - 1, 0, 1, this._hourOffsetForDst);
this._nextArrow.date = new Date(visibleDate.getFullYear() + 1, 0, 1, this._hourOffsetForDst);
break;
case "years":
var minYear = (Math.floor(visibleDate.getFullYear() / 10) * 10);
for (var i = 0; i < this._yearsBody.rows.length; i++) {
var row = this._yearsBody.rows[i];
for (var j = 0; j < row.cells.length; j++) {
var cell = row.cells[j].firstChild;
cell.date = new Date(minYear + cell.year, 0, 1, this._hourOffsetForDst);
if (cell.firstChild) {
cell.removeChild(cell.lastChild);
} else {
cell.appendChild(document.createElement("br"));
}
cell.appendChild(document.createTextNode(minYear + cell.year));
$common.removeCssClasses(cell.parentNode, ["ajax__calendar_other", "ajax__calendar_disabled", "ajax__calendar_active"]);
Sys.UI.DomElement.addCssClass(cell.parentNode, this._getCssClass(cell.date, 'y'));
}
}
if (this._title.firstChild) {
this._title.removeChild(this._title.firstChild);
}
this._title.appendChild(document.createTextNode(minYear.toString() + "-" + (minYear + 9).toString()));
this._title.date = visibleDate;
this._prevArrow.date = new Date(minYear - 10, 0, 1, this._hourOffsetForDst);
this._nextArrow.date = new Date(minYear + 10, 0, 1, this._hourOffsetForDst);
break;
}
if (this._today.firstChild) {
this._today.removeChild(this._today.firstChild);
}
this._today.appendChild(document.createTextNode(String.format(AjaxControlToolkit.Resources.Calendar_Today, todaysDate.localeFormat("MMMM d, yyyy"))));
this._today.date = todaysDate;
},
_isOutOfBounds: function(date, part) {
/// <summary>
/// Gets whether the supplied date is out of the lower / upper bound date limits
/// </summary>
/// <param name="date" type="Date">The date to match</param>
/// <param name="part" type="String">The most significant part of the date to test</param>
/// <returns type="Boolean" />
switch (part) {
case 'd':
if (this._lowerBoundDate && date < this._lowerBoundDate)
return true;
else if (this._upperBoundDate && date > this._upperBoundDate)
return true;
case 'M':
if (this._lowerBoundDate && (date.getMonth() < this._lowerBoundDate.getMonth() ||
date.getFullYear() < this._lowerBoundDate.getFullYear()))
return true;
else if (this._upperBoundDate && (date.getMonth() > this._upperBoundDate.getMonth() ||
date.getFullYear() > this._upperBoundDate.getFullYear()))
return true;
case 'y':
if (this._lowerBoundDate && date.getFullYear() < this._lowerBoundDate.getFullYear())
return true;
else if (this._upperBoundDate && date.getFullYear() > this._upperBoundDate.getFullYear())
return true;
}
return false;
},
_getCssClass: function(date, part) {
/// <summary>
/// Gets the cssClass to apply to a cell based on a supplied date
/// </summary>
/// <param name="date" type="Date">The date to match</param>
/// <param name="part" type="String">The most significant part of the date to test</param>
/// <returns type="String" />
if (this._isSelected(date, part)) {
return "ajax__calendar_active";
} else if (this._isOutOfBounds(date, part)) {
return "ajax__calendar_disabled";
} else if (this._isOther(date, part)) {
return "ajax__calendar_other";
} else {
return "";
}
},
_cell_onclick: function(e) {
/// <summary>
/// Handles the click event of a cell
/// </summary>
/// <param name="e" type="Sys.UI.DomEvent">The arguments for the event</param>
e.stopPropagation();
e.preventDefault();
if (!this._enabled) return;
var target = e.target;
var visibleDate = this._getEffectiveVisibleDate();
Sys.UI.DomElement.removeCssClass(target.parentNode, "ajax__calendar_hover");
switch (target.mode) {
case "prev":
case "next":
this._switchMonth(target.date);
break;
case "title":
switch (this._mode) {
case "days": this._switchMode("months"); break;
case "months": this._switchMode("years"); break;
}
break;
case "month":
if (!this._isOutOfBounds(target.date, 'M')) {
if (target.month == visibleDate.getMonth()) {
this._switchMode("days");
} else {
this._visibleDate = target.date;
this._switchMode("days");
}
}
break;
case "year":
if (!this._isOutOfBounds(target.date, 'y')) {
if (target.date.getFullYear() == visibleDate.getFullYear()) {
this._switchMode("months");
} else {
this._visibleDate = target.date;
this._switchMode("months");
}
}
break;
case "day":
if (!this._isOutOfBounds(target.date, 'd')) {
this.set_selectedDate(target.date);
this._switchMonth(target.date);
this._blur.post(true);
this.raiseDateSelectionChanged();
}
break;
case "today":
this.set_selectedDate(target.date);
this._switchMonth(target.date);
this._blur.post(true);
this.raiseDateSelectionChanged();
break;
}
}
}
Custom.CalendarExtender.registerClass("Custom.CalendarExtender", AjaxControlToolkit.CalendarBehavior);
PS: 如果AjaxControlToolkit升级到了40412verstion, 默认的客户端命名空间要改为Sys.Extended.UI,不然就会报"AjaxControlTookit is undefined"错误。
---------------------
Calendar.css代码如下:
---------------------
.custom__calendar_lower{color: #C0C0C0;text-decoration: line-through;}
---------------代码结束(Code End)----------------
注:在CalendarCustom.cs文件中加红显示的,是我这次解决这个问题花费时间最长的地方。一不小心就会报错了,出现问题时可查看以下内容
http://blogs.msdn.com/irenak/archive/2007/04/17/sysk-330-how-to-use-an-embedded-resource-from-a-sub-folder.aspx
-------------------摘录开始(Begin)----------------
Click on the .js file in the Solution Explore to select it, and then set Build Action (in the properties window) to Embedded Resource.
Add the following attribute to your control code-behind file (e.g. MyControl.cs):
[assembly: System.Web.UI.WebResource("ControlLibrary.MyControl.js", "text/javascript")]
In GetScriptReferences, instead of setting the Path property, use the parameterized constructor as follows:
public IEnumerable<ScriptReference> GetScriptReferences()
{
return new ScriptReference[] { new ScriptReference("ControlLibrary.MyControl.js", "ControlLibrary") };
}
However, if you place your JavaScript files in a subfolder (e.g. /ControlLibrary/Scripts/MyControl.js), then you will have to add the folder name to the dotted resource name above, e.g. ControlLibrary.Scripts.MyControl.js.
If you don’t add the folder name, you’ll probably see a run-time error message like this:
System.InvalidOperationException: Assembly ControlLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' contains a Web resource with name 'ControlLibrary.MyControl.js', but does not contain an embedded resource with name 'ControlLibrary.MyControl.js'.
Published Tuesday, April 17, 2007 4:32 AM by irenak
-------------------摘录结束(End)----------------
页面代码:
<%@ Register Assembly="Custom" Namespace="Custom" TagPrefix="cc1" %>
<cc1:CalendarExtender LowerBoundDate="2010-7-18" UpperBoundDate="2010-12-30" ID="CalendarExtender1" runat="server" TargetControlID="Date1" />
运行效果:
为了实现这个功能,又不想浪费这么好的Calendar控件功能。 怎么办呢?
原来,Asp.Net Ajax 为我们提供了扩展接口,方便我们对Asp.Net Ajax Control Toolkit的二次开发。
经过Google,在网上找到了一段原始代码,已经实现了,不能对之前的日期进行选择等功能。但是,在显示上,它却不能进行显示灰色,加上删除线。所以我进行的进一步的修改。代码如下(注:以下代码在VS2008 sp1 环境下编译通过):
---------------代码开始(Code Begin)----------------
CalendarCustom.cs代码如下:
--------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web.UI;
using AjaxControlToolkit;
[assembly: System.Web.UI.WebResource("Custom.CalendarExtender.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("Custom.Calendar.css", "text/css", PerformSubstitution = true)]
namespace Custom
{
[ClientCssResource("Custom.Calendar.css")]
[ClientScriptResource("Custom.CalendarExtender", "Custom.CalendarExtender.js")]
[ToolboxData("<{0}:CalendarExtender runat=server></{0}:CalendarExtender>")]
public class CalendarExtender : AjaxControlToolkit.CalendarExtender
{
[DefaultValue(null)]
[ExtenderControlProperty]
[ClientPropertyName("lowerBoundDate")]
public virtual DateTime? LowerBoundDate
{
get { return GetPropertyValue("LowerBoundDate", (DateTime?)null); }
set { SetPropertyValue("LowerBoundDate", value); }
}
[DefaultValue(null)]
[ExtenderControlProperty]
[ClientPropertyName("upperBoundDate")]
public virtual DateTime? UpperBoundDate
{
get { return GetPropertyValue("UpperBoundDate", (DateTime?)null ); }
set { SetPropertyValue("UpperBoundDate", value); }
}
public IEnumerable<ScriptReference> GetScriptReferences()
{
return new ScriptReference[] { new ScriptReference("Custom.CalendarExtender.js", "Custom") };
}
}
}
----------------------------
CalendarExtender.js代码如下:
----------------------------
// Register the namespace for the control.
Type.registerNamespace('Custom');
Custom.CalendarExtender = function(element) {
/// <summary>
/// A behavior that attaches a calendar date selector to a textbox
/// </summmary>
/// <param name="element" type="Sys.UI.DomElement">The element to attach to</param>
Custom.CalendarExtender.initializeBase(this, [element]);
this._lowerBoundDate = null;
this._upperBoundDate = null;
}
Custom.CalendarExtender.prototype = {
initialize: function() {
/// <summary>
/// Initializes the components and parameters for this behavior
/// </summary>
Custom.CalendarExtender.callBaseMethod(this, "initialize");
},
dispose: function() {
/// <summary>
/// Disposes this behavior's resources
/// </summary>
Custom.CalendarExtender.callBaseMethod(this, "dispose");
},
get_lowerBoundDate: function() {
/// <summary>
/// The date currently visible in the calendar
/// </summary>
/// <value type="Date" />
if (this._lowerBoundDate != null) {
return this._lowerBoundDate;
}
},
set_lowerBoundDate: function(value) {
if (value && (String.isInstanceOfType(value)) && (value.length != 0)) {
value = new Date(value);
}
if (value) value = value.getDateOnly();
if (this._lowerBoundDate != value) {
this._lowerBoundDate = value;
this.raisePropertyChanged("lowerBoundDate");
}
},
get_upperBoundDate: function() {
/// <value type="Date">
/// The date to use for "Today"
/// </value>
if (this._upperBoundDate != null) {
return this._upperBoundDate;
}
},
set_upperBoundDate: function(value) {
if (value && (String.isInstanceOfType(value)) && (value.length != 0)) {
value = new Date(value);
}
if (value) value = value.getDateOnly();
if (this._upperBoundDate != value) {
this._upperBoundDate = value;
this.raisePropertyChanged("upperBoundDate");
}
},
_performLayout: function() {
/// <summmary>
/// Updates the various views of the calendar to match the current selected and visible dates
/// </summary>
var elt = this.get_element();
if (!elt) return;
if (!this.get_isInitialized()) return;
if (!this._isOpen) return;
var dtf = Sys.CultureInfo.CurrentCulture.dateTimeFormat;
var selectedDate = this.get_selectedDate();
var visibleDate = this._getEffectiveVisibleDate();
var todaysDate = this.get_todaysDate();
switch (this._mode) {
case "days":
var firstDayOfWeek = this._getFirstDayOfWeek();
var daysToBacktrack = visibleDate.getDay() - firstDayOfWeek;
if (daysToBacktrack <= 0)
daysToBacktrack += 7;
var startDate = new Date(visibleDate.getFullYear(), visibleDate.getMonth(), visibleDate.getDate() - daysToBacktrack, this._hourOffsetForDst);
var currentDate = startDate;
for (var i = 0; i < 7; i++) {
var dayCell = this._daysTableHeaderRow.cells[i].firstChild;
if (dayCell.firstChild) {
dayCell.removeChild(dayCell.firstChild);
}
dayCell.appendChild(document.createTextNode(dtf.ShortestDayNames[(i + firstDayOfWeek) % 7]));
}
for (var week = 0; week < 6; week++) {
var weekRow = this._daysBody.rows[week];
for (var dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
var dayCell = weekRow.cells[dayOfWeek].firstChild;
if (dayCell.firstChild) {
dayCell.removeChild(dayCell.firstChild);
}
dayCell.appendChild(document.createTextNode(currentDate.getDate()));
dayCell.title = currentDate.localeFormat("D");
dayCell.date = currentDate;
//modify by arden 2008.8.21
$common.removeCssClasses(dayCell.parentNode, ["ajax__calendar_other", "ajax__calendar_disabled", "ajax__calendar_active", "custom__calendar_lower"]);
if (this._lowerBoundDate == null && this._upperBoundDate == null ) {
Sys.UI.DomElement.addCssClass(dayCell.parentNode, this._getCssClass(dayCell.date, 'd'));
}
else if ((this._upperBoundDate != null && currentDate > this._upperBoundDate) ||
(this._lowerBoundDate != null && currentDate < this._lowerBoundDate))
{
Sys.UI.DomElement.addCssClass(dayCell.parentNode, "custom__calendar_lower");
}
//modify end
currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + 1, this._hourOffsetForDst);
}
}
this._prevArrow.date = new Date(visibleDate.getFullYear(), visibleDate.getMonth() - 1, 1, this._hourOffsetForDst);
this._nextArrow.date = new Date(visibleDate.getFullYear(), visibleDate.getMonth() + 1, 1, this._hourOffsetForDst);
if (this._title.firstChild) {
this._title.removeChild(this._title.firstChild);
}
this._title.appendChild(document.createTextNode(visibleDate.localeFormat("MMMM, yyyy")));
this._title.date = visibleDate;
break;
case "months":
for (var i = 0; i < this._monthsBody.rows.length; i++) {
var row = this._monthsBody.rows[i];
for (var j = 0; j < row.cells.length; j++) {
var cell = row.cells[j].firstChild;
cell.date = new Date(visibleDate.getFullYear(), cell.month, 1, this._hourOffsetForDst);
cell.title = cell.date.localeFormat("Y");
$common.removeCssClasses(cell.parentNode, ["ajax__calendar_other", "ajax__calendar_disabled", "ajax__calendar_active"]);
Sys.UI.DomElement.addCssClass(cell.parentNode, this._getCssClass(cell.date, 'M'));
}
}
if (this._title.firstChild) {
this._title.removeChild(this._title.firstChild);
}
this._title.appendChild(document.createTextNode(visibleDate.localeFormat("yyyy")));
this._title.date = visibleDate;
this._prevArrow.date = new Date(visibleDate.getFullYear() - 1, 0, 1, this._hourOffsetForDst);
this._nextArrow.date = new Date(visibleDate.getFullYear() + 1, 0, 1, this._hourOffsetForDst);
break;
case "years":
var minYear = (Math.floor(visibleDate.getFullYear() / 10) * 10);
for (var i = 0; i < this._yearsBody.rows.length; i++) {
var row = this._yearsBody.rows[i];
for (var j = 0; j < row.cells.length; j++) {
var cell = row.cells[j].firstChild;
cell.date = new Date(minYear + cell.year, 0, 1, this._hourOffsetForDst);
if (cell.firstChild) {
cell.removeChild(cell.lastChild);
} else {
cell.appendChild(document.createElement("br"));
}
cell.appendChild(document.createTextNode(minYear + cell.year));
$common.removeCssClasses(cell.parentNode, ["ajax__calendar_other", "ajax__calendar_disabled", "ajax__calendar_active"]);
Sys.UI.DomElement.addCssClass(cell.parentNode, this._getCssClass(cell.date, 'y'));
}
}
if (this._title.firstChild) {
this._title.removeChild(this._title.firstChild);
}
this._title.appendChild(document.createTextNode(minYear.toString() + "-" + (minYear + 9).toString()));
this._title.date = visibleDate;
this._prevArrow.date = new Date(minYear - 10, 0, 1, this._hourOffsetForDst);
this._nextArrow.date = new Date(minYear + 10, 0, 1, this._hourOffsetForDst);
break;
}
if (this._today.firstChild) {
this._today.removeChild(this._today.firstChild);
}
this._today.appendChild(document.createTextNode(String.format(AjaxControlToolkit.Resources.Calendar_Today, todaysDate.localeFormat("MMMM d, yyyy"))));
this._today.date = todaysDate;
},
_isOutOfBounds: function(date, part) {
/// <summary>
/// Gets whether the supplied date is out of the lower / upper bound date limits
/// </summary>
/// <param name="date" type="Date">The date to match</param>
/// <param name="part" type="String">The most significant part of the date to test</param>
/// <returns type="Boolean" />
switch (part) {
case 'd':
if (this._lowerBoundDate && date < this._lowerBoundDate)
return true;
else if (this._upperBoundDate && date > this._upperBoundDate)
return true;
case 'M':
if (this._lowerBoundDate && (date.getMonth() < this._lowerBoundDate.getMonth() ||
date.getFullYear() < this._lowerBoundDate.getFullYear()))
return true;
else if (this._upperBoundDate && (date.getMonth() > this._upperBoundDate.getMonth() ||
date.getFullYear() > this._upperBoundDate.getFullYear()))
return true;
case 'y':
if (this._lowerBoundDate && date.getFullYear() < this._lowerBoundDate.getFullYear())
return true;
else if (this._upperBoundDate && date.getFullYear() > this._upperBoundDate.getFullYear())
return true;
}
return false;
},
_getCssClass: function(date, part) {
/// <summary>
/// Gets the cssClass to apply to a cell based on a supplied date
/// </summary>
/// <param name="date" type="Date">The date to match</param>
/// <param name="part" type="String">The most significant part of the date to test</param>
/// <returns type="String" />
if (this._isSelected(date, part)) {
return "ajax__calendar_active";
} else if (this._isOutOfBounds(date, part)) {
return "ajax__calendar_disabled";
} else if (this._isOther(date, part)) {
return "ajax__calendar_other";
} else {
return "";
}
},
_cell_onclick: function(e) {
/// <summary>
/// Handles the click event of a cell
/// </summary>
/// <param name="e" type="Sys.UI.DomEvent">The arguments for the event</param>
e.stopPropagation();
e.preventDefault();
if (!this._enabled) return;
var target = e.target;
var visibleDate = this._getEffectiveVisibleDate();
Sys.UI.DomElement.removeCssClass(target.parentNode, "ajax__calendar_hover");
switch (target.mode) {
case "prev":
case "next":
this._switchMonth(target.date);
break;
case "title":
switch (this._mode) {
case "days": this._switchMode("months"); break;
case "months": this._switchMode("years"); break;
}
break;
case "month":
if (!this._isOutOfBounds(target.date, 'M')) {
if (target.month == visibleDate.getMonth()) {
this._switchMode("days");
} else {
this._visibleDate = target.date;
this._switchMode("days");
}
}
break;
case "year":
if (!this._isOutOfBounds(target.date, 'y')) {
if (target.date.getFullYear() == visibleDate.getFullYear()) {
this._switchMode("months");
} else {
this._visibleDate = target.date;
this._switchMode("months");
}
}
break;
case "day":
if (!this._isOutOfBounds(target.date, 'd')) {
this.set_selectedDate(target.date);
this._switchMonth(target.date);
this._blur.post(true);
this.raiseDateSelectionChanged();
}
break;
case "today":
this.set_selectedDate(target.date);
this._switchMonth(target.date);
this._blur.post(true);
this.raiseDateSelectionChanged();
break;
}
}
}
Custom.CalendarExtender.registerClass("Custom.CalendarExtender", AjaxControlToolkit.CalendarBehavior);
PS: 如果AjaxControlToolkit升级到了40412verstion, 默认的客户端命名空间要改为Sys.Extended.UI,不然就会报"AjaxControlTookit is undefined"错误。
---------------------
Calendar.css代码如下:
---------------------
.custom__calendar_lower{color: #C0C0C0;text-decoration: line-through;}
---------------代码结束(Code End)----------------
注:在CalendarCustom.cs文件中加红显示的,是我这次解决这个问题花费时间最长的地方。一不小心就会报错了,出现问题时可查看以下内容
http://blogs.msdn.com/irenak/archive/2007/04/17/sysk-330-how-to-use-an-embedded-resource-from-a-sub-folder.aspx
-------------------摘录开始(Begin)----------------
SYSK 330: How To Use An Embedded Resource From A Sub-Folder
If you’re creating a custom client-side control by deriving from System.Web.UI.IScriptControl, you may want to embed the .js files into your assembly instead of having to deploy them to every web site that uses those controls (this is especially valuable if you’re developing a control library). All you need to do is to:Click on the .js file in the Solution Explore to select it, and then set Build Action (in the properties window) to Embedded Resource.
Add the following attribute to your control code-behind file (e.g. MyControl.cs):
[assembly: System.Web.UI.WebResource("ControlLibrary.MyControl.js", "text/javascript")]
In GetScriptReferences, instead of setting the Path property, use the parameterized constructor as follows:
public IEnumerable<ScriptReference> GetScriptReferences()
{
return new ScriptReference[] { new ScriptReference("ControlLibrary.MyControl.js", "ControlLibrary") };
}
However, if you place your JavaScript files in a subfolder (e.g. /ControlLibrary/Scripts/MyControl.js), then you will have to add the folder name to the dotted resource name above, e.g. ControlLibrary.Scripts.MyControl.js.
If you don’t add the folder name, you’ll probably see a run-time error message like this:
System.InvalidOperationException: Assembly ControlLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' contains a Web resource with name 'ControlLibrary.MyControl.js', but does not contain an embedded resource with name 'ControlLibrary.MyControl.js'.
Published Tuesday, April 17, 2007 4:32 AM by irenak
-------------------摘录结束(End)----------------
页面代码:
<%@ Register Assembly="Custom" Namespace="Custom" TagPrefix="cc1" %>
<cc1:CalendarExtender LowerBoundDate="2010-7-18" UpperBoundDate="2010-12-30" ID="CalendarExtender1" runat="server" TargetControlID="Date1" />
运行效果:
相关文章推荐
- Asp.net完美日历控件,支持FireFox,IE7(AjaxControlToolKit.Calendar)中文版
- Asp.net完美日历控件,支持FireFox,IE7(AjaxControlToolKit.Calendar)中文版
- ASP.NET AJAX Control Toolkit 新扩展特性:AutoCompleteExtender
- ASP.NET AJAX Advance Tips & Tricks (8) 扩展AJAX Control Toolkit中的控件
- ASP.NET AJAX Control Toolkit 新扩展特性:AutoCompleteExtender
- UpdatePanel中GridView的分页问题 GridView中的超链接 (输入一半带提示功能)ASP.NET AJAX Control Toolkit 新扩展特性:AutoCompleteExtender
- ASP.NET AjaxControlToolkit-Framework4.0 配置实用(简单介绍CalendarExtender日期控件)
- [转]ASP.NET MVC HtmlHelper扩展之Calendar日期时间选择
- ASP.NET AJAX Control Toolkit 新扩展特性:AutoCompleteExtender
- ASP.NET MVC HtmlHelper扩展之Calendar日期时间选择
- ASP.NET AJAX Advance Tips & Tricks (8) 扩展AJAX Control Toolkit中的控件
- ASP.NET AJAX Control Toolkit 控件说明(转)
- ASP.NET AJAX Control Toolkit 控件速查
- 使用ASP.NET AJAX Control Toolkit中的NoBot控件拒绝垃圾发布程序
- Asp.net Ajax Control Toolkit 资源整合
- 用ASP.NET AJAX框架扩展HTML Map控件
- asp.net教程:ASP.NET MVC框架内置AJAX支持编程技术
- 让ASP.NET AJAX Control Toolkit的两个版本同时存在于VS2008
- Nikhil的WebDevHelper工具及其ASP.NET AJAX支持