Are you trying to get the jQuery DatePicker to use the dd/MM/yyyy format in MVC4 but having no luck? Me too. I wasted hours on this! Luckily for you I have the solution below :)

Setting up the Model

Add a DataAnnotation to your date field and also add the namespace reference at the top of you class: using System.ComponentModel.DataAnnotations;

[DataType(DataType.Date)]
public DateTime StartDate { get; set; }

Setting up the View

More likely than not MVC should have scaffolded this correctly for you but for completeness your view should look like the following. The important part is the EditorFor line.

<div class='editor-label'>
    @Html.LabelFor(model => model.StartDate)
</div>
<div class='editor-field'>
    @Html.EditorFor(model => model.StartDate)
    @Html.ValidationMessageFor(model => model.StartDate)
</div>

Setting up a custom EditorTemplate

Now create a new folder called /Views/Shared/EditorTemplates and a new razor file called Date.cshtml within it. Add the following code to Date.cshtml:

@model DateTime?
@{
    var value = '';
    if (Model.HasValue) {
        value = String.Format('{0:d}', Model.Value.ToString('dd/MM/yyyy'));
    }
}
@Html.TextBox('', value, new { @class = 'datefield', type = 'text' })

We are doing a number of things here.

  1. making sure we can handle null values with Model.HasValue check.
  2. defaulting the display date in the textbox to dd/MM/yyyy.
  3. overriding the textbox type from 'date' to 'text'. This disables the HTML5 date textbox which is in my opinion ghastly as each browser renders it differently.

Adding jQuery DatePicker

Make sure you have includes for jquery-ui{version-no}.js and jquery.ui.datepicker.css. By default MVC4 should have already included these for you.

Also create your own javascript file to contain the specifics that we want to do with the jQuery date picker. I created the file ~/Scripts/datepicker.js and add the following:

$(function () {
    $(".datefield").datepicker({ dateFormat: 'dd/mm/yy', changeYear: true });
});

The $(".datefield") selector matches the class we assigned our custom Date EditorTemplate. So now any textbox with a class of "datefield" will have a jQuery DatePicker attached to it. In our case that is any field that has been adorned with the [DataType(DataType.Date)] data annotation. Nice!

We are also telling jQuery to use the day/month/year date format to fill our textbox with.

Unfortunately whilst this all works nicely as soon as a user moves away from the textbox jQuery fires a validation error because it is not taking into account localization so assumes we are using US dates! What to do!? Well onto the secret sauce :)

The Secret Sauce

I found this solution on stackoverflow which was a perfect workaround for the localization issue.

To work in with our solution change ~/Scripts/datepicker.js to the following:

$(function () {
    $.validator.addMethod('date',
    function (value, element) {
        if (this.optional(element)) {
            return true;
        }
        var ok = true;
        try {
            $.datepicker.parseDate('dd/mm/yy', value);
        }
        catch (err) {
            ok = false;
        }
        return ok;
    });
    $(".datefield").datepicker({ dateFormat: 'dd/mm/yy', changeYear: true });
});

This overrides the default way that jQuery will parse a date (mm/dd/yy) to dd/mm/yy. If you try now the jQuery validation should accept the dd/mm/yyyy format and it should save to the database correctly. Awesome!



comments powered by Disqus