A jQuery UI-Based Date Picker for ASP.NET MVC 5

by Brady Kelly


This article provides guidance on how to use the jQuery UI Datepicker widget for date fields in MVC forms.

I assume you have a working knowledge of Visual Studio, C#, ASP.NET MVC, and Razor. You should know to add a controller and view to a new or existing project, and how to run that project to observe changes made to it.

The accompanying sample code in this article was written using Visual Studio 2013 with Update 4, but it should run in most other modern versions of Visual Studio.

Just What Is an Editor Template?

To begin, you should understand what an editor template is and why you should want one. I’ll start by providing you a very plain vanilla example of date input. For this example, let’s look at an edit field for a date value. We will use my tiny PersonViewModel class, which is good only for demonstration purposes:

namespace SimpleTemplates.ViewModels
   public class PersonViewModel
      public string LastName { get; set; }
      public string FirstName { get; set; }
      public DateTime? DateOfBirth { get; set; }

The DateOfBirth property is nullable because we don’t want to require people to divulge more personal detail than absolutely necessary.

Now, to add an edit view for Person, you should, for this example at least, delegate most of the work to Visual Studio’s Add View Wizard, as in Figure 1.

Figure 1: Add an Edit View

Adding a view in this manner causes Visual Studio to scaffold the view for you; in other words, automatically generate appropriate Razor mark-up for an Edit view for the PersonViewModel. Open the Edit view, and you can see that Visual Studio has generated a call to the EditorFor HTML Helper method.

@Html.EditorFor(model => model.DateOfBirth,
   new { htmlAttributes = new
   { @class = "form-control" } })

The EditorFor HTML helper method is what is known as a templated helper. This means the MVC runtime will dynamically choose a template to determine how it should render the HTML required for a field. More comprehensive coverage of template helpers and editor templates is beyond the scope of this article, but there are several walkthroughs on this subject

Without being told otherwise, and for web UI purposes, the MVC framework treats DateTime properties as text, meaning the HTML output by the helper method ends up along the following lines:

<input class="form-control text-box single-line
   input-validation-error" data-val="true"
   data-val-date="The field DateOfBirth must
      be a date."
   id="DateOfBirth" name="DateOfBirth"
   type="datetime" value="1969/12/13 12:00:00 AM">

This is rather unfortunate, because a DateTime value is not formatted, and the end user is free to type what they want, regardless of whatever format we have chosen for DateTime values, as in Figure 2.

Figure 2: Default Edit Person

Although the built-in jQuery validation catches obvious errors, this application will still be vulnerable to, for example, a very common issue with date values. The confusion of day and month can occur, because for some locales, the standard is dd/MM/yyyy, and for others it is MM/dd/yyyy, and for days of the month less than or equal to 12, there is no way to discern between day and month.

HTML 5 Input Type : Date

Fortunately, the HTML 5 standard provides some relief from this date format chaos, in that when a compatible browser finds an input element with type date, it renders a Date Picker ‘dialogue’. Now, we are stuck on the question of how to get Razor to output such an input element for the DateOfBirth property, versus the text type input it outputs by default.

The EditorFor helper method will render HTML mark-up based on a few factors, being:

  • The .NET data type of the source property
  • View model metadata for the source property
  • A custom editor template for the source property

First, the data type: Just to be clear, this “data type” is the .NET DateTime data type, not the data annotations ‘data type’. For our DateOfBirth property, the Razor engine will generate an input element with type=”datetime”. However, it seems browsers don’t currently deal very well with this new-fangled input element, so they simply treat this input element the same as a raw text input, as seen in Figure 2. I tried Chrome, IE11, and FireFox, to no avail. This StackOverflow answer suggests browsers have little confidence in this type.

Then, the metadata: In ASP.NET MVC, we can attach metadata to viewmodel (or model) properties by using data annotation attributes; for example:

public class PersonViewModel
   public string LastName { get; set; }
   public string FirstName { get; set; }

   [DisplayFormat(DataFormatString =
       ApplyFormatInEditMode = true)]
   public DateTime? DateOfBirth { get; set; }

Here, you are telling MVC to treat the DateOfBirth property as a Date value, and thus render an input element with type=”datetime”. You also tell MVC what format you want the date in. The browser handles this input type better, and it renders a date picker:

Figure 3: Chrome’s Date Picker

As nice as Chrome’s date picker is, it is quite the black box, and it allows hardly any customisation regarding date format, scheming, what it allows the user to change, and more. For this kind of configuration, we have to turn to third party date pickers, and for its cost (zero), the jQuery UI Datepicker is a shining example.

The jQuery UI Date Picker

You can see a demo of the jQuery UI Datepicker. Figure 4 shows the demo page for this widget, configured to open when its calendar icon is clicked:

Figure 4: Datepicker Demo

This demo page also includes other examples of common configurations and styles for this cool little widget. You can click the “view source” link, at the bottom of the page, to see how simple it is to use this control. You can view more technical reference information by clicking the “API documentation” link.

Adding jQuery UI to the Project

While there are many different ways of setting an MVC project up to include jQuery UI, I have opted for, in my opinion, the simplest method, which is installing the necessary files via Nuget:

Step 1

In Visual Studio’s Package Manager Console, enter the following command:

Install-Package jQuery.UI.Combined

Step 2

Your project should now have the jQuery UI JavaScript and style sheet files, as seen in Figures 5 and 6:

Figure 5: jQuery UI Stylesheets

Figure 6: jQuery UI Scripts

All the CSS files under the ‘Content/themes’ folder belong to jQuery UI, as do the two ‘jquery-ui-1.11.4’ files under the ‘Scripts’ folder.

Step 3

Nuget does a fine job of adding the required jQuery UI files to the project, but it doesn’t do anything to actually include these files in the Razor views. To do this, you must:

  1. Include these files in the web app’s styles and scripts bundles.
  2. Reference these files in views where they are required.

Step 4

To include required files in the app’s bundles, edit the BundleConfig.cs file:

Figure 7: BundleConfig Location

Step 5

Add the following two code snippets to the RegisterBundles method in BundleConfig:

bundles.Add(new ScriptBundle("~/bundles/jqueryui")

bundles.Add(new StyleBundle("~/Content/jqueryui")

Step 6

Now, to reference the required files in views. Because you are aiming at providing the same user experience wherever a date-time value is edited, you can reference the jQuery UI files in the master layout for our application; for example:

Figure 8: _Layout Location

Step 7

At the top of _Layout.cshtml, in the head element, add the line shown in bold:

<meta charset="utf-8" />
<meta name="viewport"
   content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>

Step 8

At the bottom of _Layout.cshtml, add the line shown in bold:

   @RenderSection("scripts", required: false)

Step 9

Now, you can get the long awaited Datepicker widget working in your edit view. To do this, call the datepicker method on all input elements with a CSS class of datepicker. Add the highlighted code, near the bottom of _Layout.cshtml:

Figure 9: Datepicker JavaScript

Step 10

This code tells the Datepicker widget to:

  1. Provide all elements that have the CSS class datepicker with Datepicker functionality.
  2. Use the date format “dd/mm/yy”. This translates to a .NET format of “dd/MM/yyyy”.
  3. Allow users to change the selected year. By default, the user is only allowed to change the selected month and day.
  4. Show the calendar dropdown when the user clicks the “button”.

Step 11

The “button” functionality of this widget is rather convoluted. In its raw form, we developers must provide a relative URL to an image file for the button icon, but the jQuery UI library provides no such icon.

Step 12

All icons in the jQuery UI library are provided by CSS sprites, where multiple icons are grouped together in large image files. To access a calendar icon in one of these sprites, we call upon the jQuery UI button widget, which allows us to configure its icons property with a reference into the icon’s sprite.

Step 13

Now, we need to add the datepicker CSS class to the input element for our DateOfBirth property. In fact, we rather need to tell the Razor view engine that all properties decorated with the [DataType(DataType.Date)] attribute should include this CSS class. We do this by defining an Editor Template for such properties.

Step 14

Start by adding a new folder and file to our project, under the built-in ‘Views/Shared’ folder:

Figure 10: Adding the Date template

Step 15

Please note that exact naming is critical here. The folder under ‘Shared’ must be called ‘EditorTemplates‘, and the template file must be called ‘Date.cshtml‘. This file name corresponds to the value of Date used in the DataType attribute, in our view model.

Step 16

Add the following code, without alteration of any kind, to the Date.cshtml file:

@model DateTime?
@Html.TextBoxFor(model => Model,
   new { @class = "form-control
   jqueryui-marker-datepicker" })

Step 17

I use a nullable DateTime for the model, so this template applies to both nullable and non-nullable DateTime properties, and I include a format string, to ensure that the initial format of the date input matches the format of the Datepicker widget.

Step 18

If you run our project now, and navigate to the Person/Edit view, you should be able to see the new widget in action, like Figure 11:

Figure 11: End result

About the Author

Brady Kelly is a software developer in Johannesburg, South Africa. He specialises in C# and ASP.NET MVC, with SQL Server, with special fondness for MVC and jQuery. He has been in this business for about eighteen years, and is currently trying to master Angular and WCF, and somehow find a way to strengthen his creative faculties.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read