MVC 2 Editor Template with DateTime

One of the cool new features of MVC 2 is the ability to automatically pick an editor template based on the meta data of each property. This meta data can be as simple as the data type of the property itself.  Take an example where we have a Contact object that has a DateTime? property for DateOfBirth.

public partial class Contact  
    [DisplayName("First Name")]
    public string FirstName { get; set; }
    [DisplayName("Last Name")]
    public string LastName { get; set; }
    [DisplayName("Date of Birth")]
    public DateTime? DateOfBirth { get; set; }

We can then display the property using markup like this:

<%=Html.LabelFor(m => m.Contact.DateOfBirth) %>
<%=Html.EditorFor(m => m.Contact.DateOfBirth)%>

This results in a view that looks something like this:

This is ugly.  It's not user friendly for the user to have to type this and in many cases (like date of birth) we don't care about the time portion – only the date.  With MVC 2 we can now, by convention, change the display for all of our DateTime data types just by adding a partial view called "DateTime.ascx" to a well-known folder called "EditorTemplates":

Notice the EditorTemplates folder is in the Shared folder of views but you could scope this to a specific view folder as well. Now I can add my own partial view for DateTime. In fact, this will work for a nullable DateTime as well:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>" %>
<%=Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty), new { @class = "datePicker" }) %>

The aspect that I really like about this functionality is the rendered HTML:

<input class="datePicker" id="Contact_DateOfBirth" name="Contact.DateOfBirth" type="text" value="4/1/1975" />

Notice how that "id" and "name" attributes were still correctly set despite that fact this this was in a partial view where we were just referring to the "Value" property of a nullable DateTime. This would have been tricky to do just using partial views with MVC 1 but here the framework is taking care of this for me. This means that the model binders will "just work" when the form is posted.

Another thing to note is that I've added a class attribute of "datePicker" because I'm using the jQuery datepicker to give a nice little calendar UI for the end user.

<script src="../../Scripts/jquery-datepicker.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function() {
        $(".datePicker").datepicker({ showOn: 'both', buttonImage: "/images/calendar.gif" });

This gives a much nicer user experience:

MVC 2 editors result in a much nicer development experience. My call to the EditorFor() HTML helper method remains unchanged. But rather than just rendering a simple HTML text box with no formatting of the DateTime, it will now automatically pick up my DateTime editor template for ALL my DateTime properties and show a nice UI with better formatting.  Also note that if you have a date time that is an exception to this and you want to display a different editor, you can still use the [UIHint] attribute to control the meta data and therefore select a different editor for a DateTime.