Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Implementing a jQuery-Datepicker ASP.NET Control


:P
On this page:

[9/12/2009 – Note this post is an update of an older post that discussed a wrapper around Marc Garbanski’s jQuery-calender control. This post updates to the current jQuery.ui version (1.72). The control has been integrated into the West Wind Web & Ajax Toolkit for ASP.NET and you can grab the code from there in the Westwind.Web project. The links to the sample and download point at the Toolkit]

I've posted a wrapper ASP.NET around the jQuery.UI Datepickercontrol. This small client side calendar control is compact, looks nice and is very easy to use and I've added it some time back to my control library.

This is primarily an update for the jQuery.ui version, and so I spend a few hours or so cleaning it up which wasn’t as easy as it could have been since the API has changed quite drastically from Marc’s original implementation. The biggest changes have to do with the theming integration and the resulting explosion of related resources.

If you want to use this component you can check it out a sample and the code here:

The control is a very basic wrapper around jQuery.ui Datepicker control and it provides the basic features of the client control wrapped with server side properties so you can just drag and drop the control onto a page.

Building a control wrapper around this control is pretty straight forward. The main complications arise out of determining the best way of dealing with the resources. ASP.NET controls tend to embed all resources into the control assemblies - which has certain advantages such as the ability to automatically compress the content. But it's not always optimal to do this for example, if you have many sites and can rely on shared script resources in a server - or even on a remote server - to serve resources which is more efficient then letting ASP.NET serve resources.

Unlike the original component that I posted 2+ years back this component does not wrap up all of the required resources in ASP.NET resource for fully self contained operation. The reason for this change is that jquery.ui’s theming has drastically changed the amount of dependencies required and so both jquery.ui and the theme items must be deployed separately. By default the expected location are ~/script/jquery-ui-custom.js and a themes folder below it, but this configurable on the control.

This control works by a SelectedDate property that is tied to the underlying text box - or in the case of the Inline calendar a hidden value. Although jQuery datepicker  is all client side the control implementation is Postback aware and appropriately persists date values.

The main task of the control is simply to map server properties to the appropriate jQuery-calendar initialization code (in jQuery().ready). Thanks to Marc's simple front end to the control it's pretty straight forward to set up  a server control. All of the initialization happens through JavaScript code, so there's a bit of not so clean script generation by the control in the sense the script code generation is always pretty ugly. 

The control is super easy to use. In its default configuration it looks something like this:

<div class="samplebox">
   <h3>Image Button Popup:</h3>
   <hr />
   This version shows a calendar image button to click on to pop up the calendar:<br /><br />
   
   Enter Date: 
        <ww:jQueryDatePicker runat="server" 
                       id="txtImageButton" 
                       DisplayMode="ImageButton" 
                       DateFormat="MM-dd-yyyy" 
                       ShowButtonPanel="true"
                       SelectedDate="08-10-2009" 
                       Theme="Redmond"  />                    
</div>

which looks like this (using the Redmond theme from theme roller):

jQueryDatePicker 

In code behind you can read and write the SelectedDate or Text properties.

There's not a ton of code here so you can check it out for yourself here or by downloading the code from the link above. The code has a dependency on my ClientScript component which is also part of the West Wind Web Toolkit so you may have to download a couple of additional files (ClientScriptProxy.cs, WebUtils.cs at least) or you can replace those calls with the ASP.NET ClientScript or ScriptManager objecs.

Anyways here’s the code:
[updated: Sept. , '09 with for jQuery.ui  1.72]

    /// <summary>
    /// ASP.NET jQuery DatePicker Control Wrapper
    /// by Rick Strahl
    /// http://www.west-wind.com/
    /// based on jQuery UI DatePicker client control by Marc Grabanski    
    /// http://marcgrabanski.com/code/ui-datepicker/
    /// 
    /// Simple DatePicker control that uses jQuery UI DatePicker to pop up 
    /// a date picker. 
    /// 
    /// Important Requirements (configurable):
    /// ~/scripts/jquery.js             (available from WebResource)
    /// ~/scripts/jquery-ui-custom.js   (custom build of jQuery.ui)
    /// ~/scripts/themes/base           (set Theme property for other themes to apply)
    /// 
    /// 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\"  />")]
    public class jQueryDatePicker : TextBox
    {

        public jQueryDatePicker()
        {
            // Date specific width
            this.Width = Unit.Pixel(80);
        }

        /// <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"), DefaultValue(typeof(DatePickerDisplayModes), "ImageButton")]
        public DatePickerDisplayModes DisplayMode
        {
            get { return _DisplayMode; }
            set { _DisplayMode = value; }
        }
        private DatePickerDisplayModes _DisplayMode = DatePickerDisplayModes.ImageButton;



        /// <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 _ButtonImage; }
            set { _ButtonImage = value; }
        }
        private string _ButtonImage = "WebResource";

        /// <summary>
        /// The CSS that is used for the calendar
        /// </summary>
        [Category("Resources"), Description("The CSS that is used for the calendar or empty. WebResource loads from resources. This property serves as the base url - use Theme to apply a specific theme"),
         DefaultValue("~/scripts/themes/base/ui.all.css")]
        public string CalendarCss
        {
            get { return _CalendarCss; }
            set { _CalendarCss = value; }
        }
        private string _CalendarCss = "~/scripts/themes/base/ui.all.css";


        /// <summary>
        /// Theme applied to the base CSS url. Replaces /base/ with the theme selected
        /// </summary>
        [Category("Resources"),
         Description("Theme applied to the base CSS url. Replaces /base/ with the theme selected"),
         DefaultValue("Redmond")]        
        public string Theme
        {
            get { return _Theme; }
            set { _Theme = value; }
        }
        private string _Theme = "Redmond";

        /// <summary>
        /// Location for the calendar JavaScript
        /// </summary>
        [Description("Location for the calendar JavaScript or empty for none. WebResource loads from resources")]
        [Category("Resources"), DefaultValue("~/scripts/jquery-ui-custom.js")]
        public string CalendarJs
        {
            get { return _CalendarJs; }
            set { _CalendarJs = value; }
        }
        private string _CalendarJs = "~/scripts/jquery-ui-custom.js";


        /// <summary>
        /// Location of jQuery library. Use WebResource for loading from resources
        /// </summary>
        [Description("Location of jQuery library or empty for none. Use WebResource for loading from resources")]
        [Category("Resources"), DefaultValue("WebResource")]
        public string jQueryJs
        {
            get { return _jQueryJs; }
            set { _jQueryJs = value; }
        }
        private string _jQueryJs = "WebResource";


        /// <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 _DateFormat; }
            set { _DateFormat = value; }
        }
        private string _DateFormat = "Auto";

        /// <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 _MinDate; }
            set { _MinDate = value; }
        }
        private DateTime? _MinDate = null;

        /// <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 _MaxDate; }
            set { _MaxDate = value; }
        }
        private DateTime? _MaxDate = null;


        /// <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 _OnClientSelect; }
            set { _OnClientSelect = value; }
        }
        private string _OnClientSelect = "";


        /// <summary>
        /// Client event handler that fires before the date picker is activated
        /// </summary>
        [Description("Client event handler that fires before the date picker is activated")]
        [Category("Date Selection"), DefaultValue("")]
        public string OnClientBeforeShow
        {
            get { return _OnClientBeforeShow; }
            set { _OnClientBeforeShow = value; }
        }
        private string _OnClientBeforeShow = "";


        /// <summary>
        /// Determines where the Close icon is displayed. True = top, false = bottom.
        /// </summary>
        [Description("Determines where the Today and Close buttons are displayed on the bottom (default styling) of the control.")]
        [Category("Date Selection"), DefaultValue(true)]
        public bool ShowButtonPanel
        {
            get { return _CloseAtTop; }
            set { _CloseAtTop = value; }
        }
        private bool _CloseAtTop = true;


        /// <summary>
        /// Code that embeds related resources (.js and css)
        /// </summary>
        /// <param name="scriptProxy"></param>
        protected void RegisterResources(ClientScriptProxy scriptProxy)
        {
            scriptProxy.LoadControlScript(this, this.jQueryJs, ControlResources.JQUERY_SCRIPT_RESOURCE, ScriptRenderModes.HeaderTop);
            scriptProxy.RegisterClientScriptInclude(this.Page, typeof(ControlResources), this.CalendarJs, ScriptRenderModes.Header);

            string cssPath = this.CalendarCss;
            if (!string.IsNullOrEmpty(this.Theme))
                cssPath = cssPath.Replace("/base/", "/" + this.Theme + "/");

            scriptProxy.RegisterCssLink(this.Page, typeof(ControlResources), cssPath, cssPath);
        }

        protected override void  OnInit(EventArgs e)
        {
                base.OnInit(e);

                // Retrieve the date explicitly - NOTE: Date written by CLIENTID id & name.
                if (this.Page.IsPostBack && this.DisplayMode == DatePickerDisplayModes.Inline)
                    this.Text = this.Page.Request.Form[this.ClientID]; // Note this is the right value!            
        }

        

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

            // Register resources
            this.RegisterResources(scriptProxy);

            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.Append("showOn: 'button',");
            else if (this.DisplayMode == DatePickerDisplayModes.ImageButton)
            {
                string img = this.ButtonImage;
                if (img == "WebResource")
                    img = scriptProxy.GetWebResourceUrl(this, typeof(ControlResources), ControlResources.CALENDAR_ICON_RESOURCE);
                else
                    img = this.ResolveUrl(this.ButtonImage);

                sbOptions.Append("showOn: 'button', buttonImageOnly: true, buttonImage: '" + img + "',buttonText: 'Select date',");
            }
            else if (this.DisplayMode == DatePickerDisplayModes.Inline)
            {                
                // need to store selection in the page somehow for inline since it's
                // not tied to a textbox
                scriptProxy.RegisterHiddenField(this, this.ClientID, this.Text);
                onSelect = this.ClientID + "OnSelect";
            }

            if (!string.IsNullOrEmpty(onSelect))
                sbOptions.Append("onSelect: " + onSelect + ",");

            if (this.DisplayMode != DatePickerDisplayModes.Inline)
            {
                if (!string.IsNullOrEmpty(this.OnClientBeforeShow))
                    sbOptions.Append("beforeShow: function(y,z) { $('#ui-datepicker-div').maxZIndex(); " + 
                                     this.OnClientBeforeShow + "(y,z); },");
                else
                    sbOptions.Append("beforeShow: function() { $('#ui-datepicker-div').maxZIndex(); },");
                        
            }


            if (this.MaxDate.HasValue)
                sbOptions.Append("maxDate: " + WebUtils.EncodeJsDate(MaxDate.Value) + ",");

            if (this.MinDate.HasValue)
                sbOptions.Append("minDate: " + WebUtils.EncodeJsDate(MinDate.Value) + ",");

            if (this.ShowButtonPanel)
                sbOptions.Append("showButtonPanel: true,");

            sbOptions.Append("dateFormat: '" + dateFormat + "'}");


            // Write out initilization code for calendar
            StringBuilder sbStartupScript = new StringBuilder(400);
            sbStartupScript.AppendLine("$(document).ready( function() {");


            if (this.DisplayMode != DatePickerDisplayModes.Inline)
            {
                scriptProxy.RegisterClientScriptBlock(this.Page,
                                                      typeof(ControlResources),
                                                      "__attachDatePickerInputKeys",
                                                      this.AttachDatePickerKeysScript, true);

                sbStartupScript.AppendFormat("var cal = jQuery('#{0}').datepicker({1}).attachDatepickerInputKeys();\r\n",
                                             this.ClientID, sbOptions);
            }
            else
            {
                sbStartupScript.AppendLine("var cal = jQuery('#" + this.ClientID + "Div').datepicker(" + sbOptions.ToString() + ")");

                if (this.SelectedDate.HasValue && this.SelectedDate.Value > new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc))
                {
                    WestwindJsonSerializer ser = new WestwindJsonSerializer();
                    ser.DateSerializationMode = JsonDateEncodingModes.NewDateExpression;
                    string jsDate = ser.Serialize(this.SelectedDate);

                    sbStartupScript.AppendLine("cal.datepicker('setDate'," + jsDate + ");");
                }
                else
                    sbStartupScript.AppendLine("cal.datepicker('setDate',new Date());");

                // Assign value to hidden form var on selection
                scriptProxy.RegisterStartupScript(this, typeof(ControlResources), this.UniqueID + "OnSelect",
                    "function  " + this.ClientID + "OnSelect(dateStr)\r\n" +
                    "{\r\n" +
                    ((!string.IsNullOrEmpty(this.OnClientSelect)) ? this.OnClientSelect + "(dateStr);\r\n" : "") +
                    "jQuery('#" + this.ClientID + "')[0].value = dateStr;\r\n}\r\n", true);
            }

            sbStartupScript.AppendLine("} );");
            scriptProxy.RegisterStartupScript(this.Page, typeof(ControlResources), "_cal" + this.UniqueID,
                 sbStartupScript.ToString(), true);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        public override void RenderControl(HtmlTextWriter writer)
        {
            if (this.DisplayMode != DatePickerDisplayModes.Inline)
                base.RenderControl(writer);
            else
            {
                
                if (this.DesignMode)
                    writer.Write("<div id='" + this.ClientID + "Div' style='width: 200px; height: 200px; padding: 20px;background: silver; color; white'>Inline Calendar Placeholder</div>");
                else
                    writer.Write("<div id='" + this.ClientID + "Div'></div>");
            }

            // this code is only for the designer
            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(), ControlResources.CALENDAR_ICON_RESOURCE);
                    else
                        img = this.ResolveUrl(this.ButtonImage);

                    writer.AddAttribute(HtmlTextWriterAttribute.Src, img);
                    writer.AddAttribute("hspace", "2");
                    writer.RenderBeginTag(HtmlTextWriterTag.Img);
                    writer.RenderEndTag();
                }
            }
        }

        private string AttachDatePickerKeysScript =
@"
$.fn.attachDatepickerInputKeys = function(callback) {
    if (this.length < 1) return this;

    this.keydown(function(e) {
        var j = jQuery(this);
        var di = $.datepicker._getInst(this);
        if (!di)
            return;

        $.datepicker._setDateFromField(di);  // force update first

        var d = j.datepicker('getDate');
        if (!d)
            return true;

        var month = d.getMonth();
        var year = d.getFullYear();
        var day = d.getDate();

        switch (e.keyCode) {
            case 84: // [T]oday
                d = new Date(); break;
            case 109: case 189:
                d = new Date(year, month, day - 1); break;
            case 107: case 187:
                d = new Date(year, month, day + 1); break;
            case 77: //M
                d = new Date(year, month - 1, day); break;
            case 72: //H
                d = new Date(year, month + 1, day); break;
            default:
                return true;
        }
        
        j.datepicker('setDate', d);
        if (callback)
            callback(this);
        return false;
    });
    return this;
}
$.fn.maxZIndex = function(opt) {
    var def = { inc: 10, group: ""*"" };
    $.extend(def, opt);
    var zmax = 0;
    $(def.group).each(function() {
        var cur = parseInt($(this).css('z-index'));
        zmax = cur > zmax ? cur : zmax;
    });
    if (!this.jquery)
        return zmax;

    return this.each(function() {
        zmax += def.inc;
        $(this).css(""z-index"", zmax);
    });
}
";
    }


    public enum DatePickerDisplayModes
    {
        Button,
        ImageButton,
        AutoPopup,
        Inline
    }

Enjoy,

+++ Rick --

Posted in jQuery  

The Voices of Reason


 

Jason Haley
September 13, 2009

# Interesting Finds: September 13, 2009

Interesting Finds: September 13, 2009

SKOROZSI.NET
September 13, 2009

# links for 2009-09-13

links for 2009-09-13

www.hotmail.com
September 14, 2009

# re: Implementing a jQuery-Datepicker ASP.NET Control

Hi,
This article is really great...I will like to appreciate your efforts...You are really very good programemer and even a better thinker .Please Keep up posting good articles as you are really great explainer and and a great tutor.
Thanks.
Stally

Pedro
September 30, 2009

# re: Implementing a jQuery-Datepicker ASP.NET Control

Uhh, that looks like a lot of code for a datepicker.

Rick Strahl
September 30, 2009

# re: Implementing a jQuery-Datepicker ASP.NET Control

@Pedro - have you ever actually implemented a date picker that's reasonaby usable? Then you would know that date pickers tend to be fairly complex. The above isn't even an implementation, just a wrapper to set the options on the date picker to allow customization easily.

The point is this is a control that's supposed to make the developer's job as easy as possible.

Rob
October 02, 2009

# re: Implementing a jQuery-Datepicker ASP.NET Control

I fully agree with Pedro, a lot of code for getting a jQuery datepicker work on ASP.NET controls. I was searching for a solution too, I found this post also, but I didn't like the whole bunch of code for something 'simple'.

I worked a bit on jQuery and I found an even easier way. I post it on my blog (http://blog.vanmeeuwen-online.nl/2009/10/easy-way-to-use-jquery-datepicker-on.html), but in short, use for all asp.net controls that should get an date a standard piece of text for the name, like txtDate... with some extra text to distinguish and place in the head section of you page the following:
$("input[name*='txtDate']").datepicker();
.
Now all asp.net controls with txtDate in the name, will get the jQuery datepicker functionality. Works great to me.

Rick Strahl
October 02, 2009

# re: Implementing a jQuery-Datepicker ASP.NET Control

Sure, if that's all you need fine. But if you need to configure DatePicker and you have to do it on every page you'll find out that one line of code turns into a big block of code with many variables to set. Most people don't use .datepicker() with its default settings (at least not what I've seen).

This code also does a number of things the date picker doesn't do natively. Like the ability to use keystrokes to increment the date in the textbox without bringing up the date picker popup (+,- etc.) as well as handling proper z-Order placement when working with other z-Indexed content etc. converting .NET date formats to datepicker's date format to name a few.

IAC, the idea here is just to make the integration into pages easier and more consistent including designer support. The amount of code to do this is really irrelevant - the code you have to write to get it to render the way you want in your pages is what really counts at least to me.

Vishwa Kumar
December 07, 2009

# re: Implementing a jQuery-Datepicker ASP.NET Control

Well said Rick. I agree the amount of code in the control is irrelevant.

After using .datepicker() on two of my pages, i realised ASP.Net control route is the best solution.

gopi
December 12, 2009

# re: Implementing a jQuery-Datepicker ASP.NET Control

How to set Jquery Calender Position in asp.net 2.0 ... How to set back and bring front of ur calender. Its overlapping with other control. So that , we cnt able to pick the date...
Plz help me .... Its vry Urgent ... Hope U vl do the needful ...
Email. ID: gopihere@indiatimes.com

Rick Strahl
December 12, 2009

# re: Implementing a jQuery-Datepicker ASP.NET Control

@gopi - This is a bug in the datepicker. There's a workaround for this by explicitly setting the z-index style. More info here: http://www.west-wind.com/weblog/posts/891992.aspx

Dimitri
December 30, 2009

# re: Implementing a jQuery-Datepicker ASP.NET Control

Very informative post. And the approach - just like I would do it. Love to have it simple, even tho the amount of code is relatively big, it is reusable. And you don't have to worry about dependencies. One question though: If I place more than one datepicker controls on a web page, will they all call RegisterResources method and register more than one instances of jQuery.js and css files?

Tom
March 12, 2010

# re: Implementing a jQuery-Datepicker ASP.NET Control

With a master page it will not work without doing this, i spent (wasted) hours on it. Thus This solution works great, but if you have a master page, you must visit this link below (it is not my article or site, i commented on it, as i had 1 issue i resolved)
http://blog.waleedmohamed.net/2009/12/aspnet-master-page-and-jquery-reference.html

amendez
April 07, 2010

# Exception

It does't work when is assigned to RequiredFiledValidator. It throws an javascript exception.

borith
April 11, 2010

# re: Implementing a jQuery-Datepicker ASP.NET Control

Please give me a link to the code like c# or vb.net code.

thanks

John Doe
April 26, 2010

# re: Implementing a jQuery-Datepicker ASP.NET Control

you have download for 8mb but where do i find the datepicker code?

Error
July 25, 2010

# re: Implementing a jQuery-Datepicker ASP.NET Control

Type 'Westwind.WebToolkit.jQueryDatePicker' does not have a public property named 'DisplayMode'.

Any ideas?

Rick Strahl
July 25, 2010

# re: Implementing a jQuery-Datepicker ASP.NET Control


Yves M.
August 10, 2010

# re: Implementing a jQuery-Datepicker ASP.NET Control

I did something quite similar to that control. The difference is that I dont like the javascript-code in dotnet code. What I do is i just render a textbox with all attributes set and a jQuery plugin does the rest on the client side.

Tina Riley
November 01, 2010

# re: Implementing a jQuery-Datepicker ASP.NET Control

Honestly this is one of the easiest controls I've ever implemented into a solution and it just works flawlessly. I can embed the control in a repeater or gridview, I can find the control and get its value easily and I can style it any way I want to. Its like we have the best of both worlds (jQuery and .Net)!! Well done and thanks for this fabulous solution!

Andrew
January 29, 2011

# re: Implementing a jQuery-Datepicker ASP.NET Control

Hi Rick,

Thanks for a great Date picker.

I am using this control on a search page with a GridView to show the search results...for some strange reason that I am yet to work out when I move to the next page of the gridview (i.e. when there is enough rows for it to paginate) after stepping through OnPageIndexChanging(object sender, GridViewPageEventArgs e) I get the following exception:

Type: System.InvalidOperationException

Message: The script tag registered for type 'Westwind.Web.Controls.ControlResources' and key '_calcss' has invalid characters outside of the script tags: . Only properly formatted script tags can be registered.

Method: Void CheckScriptTagTweenSpace(System.Web.UI.RegisteredScript, System.String, Int32, Int32)

System.InvalidOperationException: The script tag registered for type 'Westwind.Web.Controls.ControlResources' and key '_calcss' has invalid characters outside of the script tags: . Only properly formatted script tags can be registered.
at System.Web.UI.ScriptRegistrationManager.CheckScriptTagTweenSpace(RegisteredScript entry, String text, Int32 start, Int32 length)
at System.Web.UI.ScriptRegistrationManager.WriteScriptWithTags(HtmlTextWriter writer, String token, RegisteredScript activeRegistration)
at System.Web.UI.ScriptRegistrationManager.RenderActiveScriptBlocks(List`1 updatePanels, HtmlTextWriter writer, String token, List`1 scriptRegistrations)
at System.Web.UI.ScriptRegistrationManager.RenderActiveScripts(List`1 updatePanels, HtmlTextWriter writer)
at System.Web.UI.PageRequestManager.ProcessScriptRegistration(HtmlTextWriter writer)
at System.Web.UI.PageRequestManager.RenderPageCallback(HtmlTextWriter writer, Control pageControl)
at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
at System.Web.UI.Page.Render(HtmlTextWriter writer)
at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Any ideas...Is this a bug or am have I not implemented it properly?

Thanks,

Andrew

Subhadip
June 16, 2011

# re: Implementing a jQuery-Datepicker ASP.NET Control

Hi Rick,

I am also facing same problem as Andrew.

Rick Strahl
June 16, 2011

# re: Implementing a jQuery-Datepicker ASP.NET Control

@Andrew - that sounds like a bug, but I can't duplicate it. I'm also not sure what that error message actually means. The the _calcss resource is actually a CSS file link injected into the page, rather than script which makes it all the more puzzling.

If you can post (or email me) a simple repo scenario that can run on its own I can take a look at it.

Hetalkumar Kachhadiya
August 17, 2011

# re: Implementing a jQuery-Datepicker ASP.NET Control

Hi Rick,

Just create a new web site with Ajax Update Panel and put the jQuery Datepicker control on it. Add a New Button control on page with postback =true.

Select the date using the datepicker and click on save button. you will get this error.

Mark
August 30, 2011

# re: Implementing a jQuery-Datepicker ASP.NET Control

hi Rick

Have you made any progress on the error stated by Andrew as we are also getting this error when using the date picker control in ajax update panel.

Matteo
December 07, 2011

# re: Implementing a jQuery-Datepicker ASP.NET Control

Thanks for this control!

Just one question: i need to set the language for the datapicker. i tryed to set the attribute CalendarJs as
CalendarJs="development-bundle/ui/i18n/jquery-ui-i18n.js"

but it's not working.

I need to set ut in Italian Language.
Thanks for the help!!
Matteo

Magesh
February 21, 2013

# re: Implementing a jQuery-Datepicker ASP.NET Control

Thanks rick you saved a lot of my development time.

I have started customizing the control according to my need.

(When Assign the SelectedDate value to Another JqueryDatePicker it is returning Datetime min value becuase of conversion failed when Tryparse. So that i have used ParseExact with using of this.Dateformat.) I want to post it here because i dont want anyone to disturb you for small doubts.
Thanks Once Again for your Efforts. :)

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024