using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Globalization;
using System.Drawing;
using System.Web;
namespace Mullivan.Web.UI.WebControls
{
/// <summary>
/// ASP.NET jQuery Calendar Control Wrapper
/// by Rick Strahl
/// http://www.west-wind.com
///
///
/// based on jQuery calendar client control by Marc Grabanski
/// http://marcgrabanski.com/code/jquery-calendar////
/// Simple DatePicker control that uses jQuery-calendar to pop up
/// a date picker.
///
/// Important Requirements:
/// scripts/jquery.js
/// scripts/jquery-calendar.js
/// scripts/calendar.css
///
/// Resources are embedded into the assembly so you don't need
/// to reference or distribute anything. You can however override
/// each of these resources with relative URL based resources.
/// </summary>
[ToolboxBitmap(typeof(System.Web.UI.WebControls.Calendar)),
DefaultProperty("Text"),
ToolboxData("<{0}:JQueryDatePicker runat='server' width='80px'></{0}:JQueryDatePicker>")]
public class JQueryDatePicker : TextBox
{
public JQueryDatePicker() : base()
{
this.Width = Unit.Pixel(80);
}
[Browsable(false)]
public string ClientJQueryControlId
{
get
{
this.EnsureID();
return "jq" + this.ClientID;
}
}
[Browsable(false)]
public string ClientJQueryValueControlId
{
get
{
this.EnsureID();
return this.ClientID + "_Value";
}
}
/// <summary>
/// The currently selected date
/// </summary>
[DefaultValue(typeof(DateTime), ""),
Category("Date Selection")]
public DateTime? SelectedDate
{
get
{
DateTime defaultDate = DateTime.Parse("01/01/1900", CultureInfo.InstalledUICulture);
if (this.Text == "")
return defaultDate;
DateTime.TryParse(this.Text, out defaultDate);
return defaultDate;
}
set
{
if (!value.HasValue)
this.Text = "";
else
{
string dateFormat = this.DateFormat;
if (dateFormat == "Auto")
dateFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
this.Text = value.Value.ToString(dateFormat);
}
}
}
/// <summary>
/// Determines how the datepicking option is activated
/// </summary>
[Description("Determines how the datepicking option is activated")]
[Category("Date Selection")]
public DatePickerDisplayModes DisplayMode
{
get
{
return (this.ViewState["DisplayMode"] != null ?
(DatePickerDisplayModes) this.ViewState["DisplayMode"]
: DatePickerDisplayModes.ImageButton);
}
set
{
this.ViewState["DisplayMode"] = value;
}
}
/// <summary>
/// Url to a Calendar Image or WebResource to use the default resource image.
/// Applies only if the DisplayMode = ImageButton
/// </summary>
[Description("Url to a Calendar Image or WebResource to use the default resource image")]
[Category("Resources"), DefaultValue("WebResource")]
public string ButtonImage
{
get
{
return (this.ViewState["ButtonImage"] != null ?
this.ViewState["ButtonImage"].ToString()
: "WebResource");
}
set
{
this.ViewState["ButtonImage"] = value;
}
}
/// <summary>
/// Determines the Date Format used. Auto uses CurrentCulture. Format: MDY/ month, date,year separator
/// </summary>
[Description("Determines the Date Format used. Auto uses CurrentCulture. Format: MDY/ month, date,year separator")]
[Category("Date Selection"), DefaultValue("Auto")]
public string DateFormat
{
get
{
return (this.ViewState["DateFormat"] != null ?
this.ViewState["DateFormat"].ToString()
: "Auto");
}
set
{
this.ViewState["DateFormat"] = value;
}
}
/// <summary>
/// Minumum allowable date. Leave blank to allow any date
/// </summary>
[Description("Minumum allowable date")]
[Category("Date Selection"), DefaultValue(typeof(DateTime?), null)]
public DateTime? MinDate
{
get
{
return (this.ViewState["MinDate"] != null ?
(DateTime?)this.ViewState["MinDate"]
: null);
}
set
{
this.ViewState["MinDate"] = value;
}
}
/// <summary>
/// Maximum allowable date. Leave blank to allow any date.
/// </summary>
[Description("Maximum allowable date. Leave blank to allow any date.")]
[Category("Date Selection"), DefaultValue(typeof(DateTime?), null)]
public DateTime? MaxDate
{
get
{
return (this.ViewState["MaxDate"] != null ?
(DateTime?)this.ViewState["MaxDate"]
: null);
}
set
{
this.ViewState["MaxDate"] = value;
}
}
/// <summary>
/// Client event handler fired when a date is selected
/// </summary>
[Description("Client event handler fired when a date is selected")]
[Category("Date Selection"), DefaultValue("")]
public string OnClientSelect
{
get
{
return (this.ViewState["OnClientSelect"] != null ?
this.ViewState["OnClientSelect"].ToString()
: string.Empty);
}
set
{
this.ViewState["OnClientSelect"] = value;
}
}
/// <summary>
/// Determines where the Close icon is displayed. True = top, false = bottom.
/// </summary>
[Description("Determines where the Close icon is displayed. True = top, false = bottom.")]
[Category("Date Selection"), DefaultValue(true)]
public bool CloseAtTop
{
get
{
return (this.ViewState["CloseAtTop"] != null ?
(bool)this.ViewState["CloseAtTop"]
: true);
}
set
{
this.ViewState["CloseAtTop"] = value;
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
ClientScriptProxy p = ClientScriptProxy.Current;
// *** Register resources
JQueryUtil.RegisterRequiredResources(p, this);
#if DEBUG
p.RegisterClientScriptInclude(this, WebResources.JQUERY_JAVASCRIPT_UI_DATEPICKER, false);
#endif
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (this.Page.IsPostBack && this.DisplayMode == DatePickerDisplayModes.Inline)
{
this.Text = this.Page.Request.Form[ClientJQueryValueControlId];
}
}
/// <summary>
/// Most of the work happens here for generating the hook up script code
/// </summary>
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
// *** MS AJAX aware script management
ClientScriptProxy scriptProxy = ClientScriptProxy.Current;
string dateFormat = this.DateFormat;
if (string.IsNullOrEmpty(dateFormat) || dateFormat == "Auto")
{
// *** Try to create a data format string from culture settings
// *** this code will fail if culture can't be mapped on server hence the empty try/catch
try
{
dateFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
}
catch { }
}
dateFormat = dateFormat.ToLower().Replace("yyyy", "yy");
// *** Capture and map the various option parameters
StringBuilder sbOptions = new StringBuilder(512);
sbOptions.Append("{");
string onSelect = this.OnClientSelect;
if (this.DisplayMode == DatePickerDisplayModes.Button)
sbOptions.AppendLine("showOn: 'button',");
else if (this.DisplayMode == DatePickerDisplayModes.ImageButton)
{
string img = this.ButtonImage;
if (img == "WebResource")
img = scriptProxy.GetWebResourceUrl(this, typeof(WebResources), WebResources.IMAGE_DATEPICKER);
else
img = this.ResolveUrl(this.ButtonImage);
sbOptions.AppendLine("showOn: 'button', buttonImageOnly: true, buttonImage: '" + img + "',buttonText: 'Select date',");
}
else if (this.DisplayMode == DatePickerDisplayModes.Inline)
{
scriptProxy.RegisterHiddenField(this, this.ClientJQueryValueControlId, this.Text);
onSelect = this.ClientID + "OnSelect";
}
if (!string.IsNullOrEmpty(onSelect))
sbOptions.AppendLine("onSelect: " + onSelect + ",");
if (this.MaxDate.HasValue)
sbOptions.AppendLine("maxDate: " + WebUtils.EncodeJsDate(MaxDate.Value) + ",");
if (this.MinDate.HasValue)
sbOptions.AppendLine("minDate: " + WebUtils.EncodeJsDate(MinDate.Value) + ",");
if (!this.CloseAtTop)
sbOptions.AppendLine("closeAtTop: false,");
if (this.DisplayMode != DatePickerDisplayModes.Inline)
{
sbOptions.AppendLine(@"
beforeShow : function (input){
var inst = $.datepicker._getInst(input);
inst.dpDiv[0].style.zIndex = $.ui.dialog.maxZ + 1; //Places Control Above Dialog
},");
}
if (this.SelectedDate.HasValue && this.SelectedDate.Value > new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc))
sbOptions.AppendLine("defaultDate : new Date('" + this.Text + "'),");
sbOptions.AppendLine("dateFormat: '" + dateFormat + "'}");
// *** Write out initilization code for calendar
StringBuilder sbStartupScript = new StringBuilder(400);
sbStartupScript.Append("var ");
sbStartupScript.Append(this.ClientJQueryControlId);
sbStartupScript.Append(" = jQuery('#");
sbStartupScript.Append(this.ClientID);
sbStartupScript.AppendLine("');");
sbStartupScript.AppendLine("jQuery(document).ready( function() {");
sbStartupScript.Append(this.ClientJQueryControlId);
sbStartupScript.AppendLine(".datepicker(" + sbOptions.ToString() + ");");
if (this.DisplayMode == DatePickerDisplayModes.Inline)
{
// *** Assign value to hidden form var on selection
scriptProxy.RegisterStartupScript(this, typeof(WebResources), this.UniqueID + "OnSelect",
"function " + this.ClientID + "OnSelect(dateStr)\r\n" +
"{\r\n" +
((!string.IsNullOrEmpty(this.OnClientSelect)) ? this.OnClientSelect + "(dateStr);\r\n" : "") +
"jQuery('#" + this.ClientJQueryValueControlId + "')[0].value = dateStr;\r\n}\r\n", true);
}
sbStartupScript.AppendLine("} );");
scriptProxy.RegisterStartupScript(this.Page, typeof(WebResources), "_cal" + this.ID,
sbStartupScript.ToString(), true);
}
/// <summary>
///
/// </summary>
/// <param name="writer"></param>
public override void RenderControl(HtmlTextWriter writer)
{
if (this.DisplayMode != DatePickerDisplayModes.Inline)
base.RenderControl(writer);
else
{
writer.Write("<div id='" + this.ClientID + "'></div>");
}
if (HttpContext.Current == null)
{
if (this.DisplayMode == DatePickerDisplayModes.Button)
{
writer.Write(" <input type='button' value='...' style='width: 20px; height: 20px;' />");
}
else if ((this.DisplayMode == DatePickerDisplayModes.ImageButton))
{
string img;
if (this.ButtonImage == "WebResource")
img = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), WebResources.IMAGE_DATEPICKER);
else
img = this.ResolveUrl(this.ButtonImage);
writer.AddAttribute(HtmlTextWriterAttribute.Src, img);
writer.AddAttribute("hspace", "2");
writer.RenderBeginTag(HtmlTextWriterTag.Img);
writer.RenderEndTag();
}
}
}
}
public enum DatePickerDisplayModes
{
Button,
ImageButton,
AutoPopup,
Inline
}
}