Rajeeshcv.com

Sharing my knowledge

JQueryUI Datepicker in ASP.Net MVC

Datepicker is nice and cool plugin for displaying the calendar with ease. It is very easy to use JQuery plugin, it comes as part of JQueryUI library, so if you want to use this – first download JQueryUI from http://jqueryui.com/download and also download JQuery(http://docs.jquery.com/Downloading_jQuery) if you haven’t done yet. For e.g. if you have a form like one below

<% using(Html.BeginForm()){%>
  <fieldset>
    <legend>Event Information</legend>
     <p>
        <label for="EventName">Event Name:</label>
        <%= Html.TextBox("EventName")%>
            </p>
            <p>
            <label for="StartDate">Start Date:</label>
            <%= Html.TextBox("StartDate")%>
            </p>
            <p>
            <label for="EndDate">End Date:</label>
            <%= Html.TextBox("EndDate")%>
            </p>
            <p>
                <input type="submit" value="Save" />
            </p>
  </fieldset>
<% }%>

and you want to attach datepicker to “StartDate” and “EndDate” input fields, what you needs to do is call the datepicker function on the these input field selector like below.

<script language="javascript">
    $(document).ready(function() {
    $('#StartDate').datepicker();
    $('#EndDate').datepicker();
    });
</script>

This works fine as we expected :)

Difference in Date format patterns

Consider a scenario where your MVC application supports localization, then the selected date displayed in the input fields also should display the in the same date format of the current culture(This format could be custom one or default one). This leads to you another issue – Datepicker plugin given by the JQueryUI supports different date formats, but it is different from one that is available in .NET. For e.g. in order to display a long day name (“Thursday”) .NET uses “dddd” its equivalent in Datepicker is “DD”. In order to solve this disparity between the .NET world and Datepicker world, I have created a html helper function, which could generate the Datepicker format from a .Net date format.

/// <summary>
/// JQuery UI DatePicker helper.
/// </summary>
public static class JQueryUIDatePickerHelper
{
    /// <summary>
    /// Converts the .net supported date format current culture format into JQuery Datepicker format.
    /// </summary>
    /// <param name="html">HtmlHelper object.</param>
    /// <returns>Format string that supported in JQuery Datepicker.</returns>
    public static string ConvertDateFormat(this HtmlHelper html)
    {
        return ConvertDateFormat(html, Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern);
    }

    /// <summary>
    /// Converts the .net supported date format current culture format into JQuery Datepicker format.
    /// </summary>
    /// <param name="html">HtmlHelper object.</param>
    /// <param name="format">Date format supported by .NET.</param>
    /// <returns>Format string that supported in JQuery Datepicker.</returns>
    public static string ConvertDateFormat(this HtmlHelper html, string format)
    {
        /*
         *  Date used in this comment : 5th - Nov - 2009 (Thursday)
         *
         *  .NET    JQueryUI        Output      Comment
         *  --------------------------------------------------------------
         *  d       d               5           day of month(No leading zero)
         *  dd      dd              05          day of month(two digit)
         *  ddd     D               Thu         day short name
         *  dddd    DD              Thursday    day long name
         *  M       m               11          month of year(No leading zero)
         *  MM      mm              11          month of year(two digit)
         *  MMM     M               Nov         month name short
         *  MMMM    MM              November    month name long.
         *  yy      y               09          Year(two digit)
         *  yyyy    yy              2009        Year(four digit)             *
         */

        string currentFormat = format;

        // Convert the date
        currentFormat = currentFormat.Replace("dddd", "DD");
        currentFormat = currentFormat.Replace("ddd", "D");

        // Convert month
        if (currentFormat.Contains("MMMM"))
        {
            currentFormat = currentFormat.Replace("MMMM", "MM");
        }
        else if (currentFormat.Contains("MMM"))
        {
            currentFormat = currentFormat.Replace("MMM", "M");
        }
        else if (currentFormat.Contains("MM"))
        {
            currentFormat = currentFormat.Replace("MM", "mm");
        }
        else
        {
            currentFormat = currentFormat.Replace("M", "m");
        }

        // Convert year
        currentFormat = currentFormat.Contains("yyyy") ? currentFormat.Replace("yyyy", "yy") : currentFormat.Replace("yy", "y");

        return currentFormat;
    }
}

So how we could make use this helper method, just replace the datepicker initialization code we have written earlier with this

<script language="javascript">
    $(document).ready(function() {
    $('#StartDate').datepicker({ dateFormat: '<%= Html.ConvertDateFormat() %>' });
    $('#EndDate').datepicker({ dateFormat: '<%= Html.ConvertDateFormat() %>' });
    });
</script>

Hope this helps.

Comments

bruce lee
bruce lee commented
I have done the implement with your code. It is very very useful and easy. Thanks a lot, man!
bobj
bobj commented
what abour the regional setting? e.g. $(selector).datepicker($.datepicker.regional['fr']);
Andrew Gunn
Andrew Gunn commented
Thanks bruv!
Rajeesh
Rajeesh commented
@Nosha, @snomag, @Arora - Thanks for all the good comments.
S Arora
S Arora commented
that was exactly what I have been looking for , thanks Rajeesh
snomag
snomag commented
Amazing, just what I needed. Thanks, keep up the good work!
Nosha
Nosha commented
Thx you were of grt help :)
developer
developer commented

hi, its a gr8 post. Working fine for me. But there is a small issue of css. The calender is opening over the other fields of the form, without css styles. It looks very bad. Can u give me link to download the CSS stylesheet file for the same. Help will be appreciated.

Thanks

Tim B.
Tim B. commented

Rajeesh, thank you for such an eye-opener!!!

I was always worried about the string-based DOM-object IDs which may go out of sync unnoticed if the model properties get renamed, so I have consolidated the code and enforced the property name verification.


        private const string ConstJQueryDatePickerFormat = @"$('#{0}').datepicker( {{dateFormat: '{1}'}} );";

    /// <summary>
    /// Helps add a jQueryUI-based DataPicker usercontrol to a DOM-object represented by a strongly-typed Model's property.
    /// </summary>
    /// <param name="html">A strongly-typed html helper to be extended.</param>
    /// <param name="propertyExpression">A property name to add the usercontrol to.</param>
    /// <param name="dateTimeFormat">Defaults to the culture of the current thread</param>
    /// <returns>An unencoded jQueryUI javascript text.</returns>
    public static HtmlString AddDatePickerFor<TModel, TProperty>(this HtmlHelper<TModel> html, 
             Expression<Func<TModel, TProperty>> propertyExpression, 
             DateTimeFormatInfo dateTimeFormat = null)
             where TModel : class
    {
        if (propertyExpression == null || propertyExpression.Body == null)
            throw new ArgumentNullException("propertyExpression", "The parameter (or its property 'Body') is not set");

        MemberExpression expression = propertyExpression.Body as MemberExpression;
        if (expression == null)
            throw new InvalidOperationException("The propertyExpression must represent a single property of the Model");

        string propertyName = expression.Member.Name;
        string dateFormatString = (dateTimeFormat ?? Thread.CurrentThread.CurrentCulture.DateTimeFormat).ShortDatePattern;

        return new HtmlString(string.Format(ConstJQueryDatePickerFormat, propertyName, 
                ConvertDateFormat(dateFormatString)));
    }

This will result in an explicit error in case a property name belonging to a strongly-typed Model is incorrect in the markup. Below is the usage (the sample below is for the Razor view engine):


$(document).ready(function () {
    @Html.AddDatePickerFor(model => model.UpdatedOn)
}
Rajeesh
Rajeesh commented

@tim wow!!! that is a nice a technique.

Thanks.

santosh
santosh commented

h Rajeesh,

I am new to Jquery. could you please help me with this. When i try to call the htmlhelper using $('#StartDate').datepicker({ dateFormat: '<%= Html.ConvertDateFormat() %>' }); its just printing the '<%= Html.ConvertDateFormat() %>' . Any idea what I might be doing wrong?

Guruuswa
Guruuswa commented

@santosh

do this $('#StartDate').datepicker({ dateFormat: '@Html.ConvertDateFormat()' });

Vinay Singh
Vinay Singh commented

This is really nice article .i have found more please check http://dotnetpools.com/Article/ArticleDetiail/?articleId=43&title=Event%20Calender%20Using%20Jquery%20In%20MVC%203

Jose
Jose commented

Thanks for sharing, awesome work!

Juan Vicente
Juan Vicente commented

Very nice article. It helps me a lot

Leave your comments