MVC3 Unobtrusive Date Validation on a custom formatted date

mnsr picture mnsr · Nov 9, 2011 · Viewed 15k times · Source

I have a date field (i'm using the jquery ui datepicker) in a form that I've formatted, like so:

ViewModel

[DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime FooDate { get; set; }

View

@Html.EditorFor(m => m.FooDate)

This correctly shows the date the way I want it to, e.g. 09-Nov-2011

The problem I'm getting, occurs when I press submit. It keeps telling me the date is not valid.... It IS valid, you stupid thing!

Is there any way, i can get jquery/unobtrusive javascript to ignore this field or allow this format to pass? So far, the only way I can get the form to work, is if i don't format the date, or use {0:d} as a date format for it.

Edit: I've created a totally separate layout+view+controller+model for testing this stupid thing. Still doesn't work in IE/Safari. I have the latest jquery.validate/unobtrusive files from nuget.

My layout is empty. It just loads the following files:

"jquery-1.7.min.js"
"jquery-ui-1.8.16.min.js"
"jquery.validate.min.js"
"jquery.validate.unobtrusive.min.js"

My TestViewModel is simple:

public class TestViewModel
{
    [Display(Name = "Test Date:")]
    [DisplayFormat(DataFormatString = "{0:dd/MMM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? TestDate { get; set; }
}

My TestController goes as follows:

public class TestController : Controller
{
    public ActionResult Index()
    {
        var m = new TestViewModel();
        m.TestDate = DateTime.Now;
        return View(m);
    }
}

My View:

@using (Html.BeginForm())
{
    ViewContext.FormContext.ValidationSummaryId = "valSumId";
    @Html.ValidationSummary(false, "The following errors were found:");
    @Html.AntiForgeryToken()

    @Html.LabelFor(m => m.TestDate)
    <input type="date" id="TestDate" value="@Model.TestDate.Value.ToString("dd/MMM/yyyy")" />
    <input type="submit" />
}

No worky.

You know what the annoying thing is? If i change TestDate to a string, it still fails.

Answer

Piotr Lewandowski picture Piotr Lewandowski · Nov 21, 2012

I think there is a problem with hyphen ("-") in your format string:

[DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}", ApplyFormatInEditMode = true)]

It seems that unobtrusive validation does not accept hyphen for date formatting by default.

In my case I had to add custom client-side method:

$.validator.methods.date = function (value, element) {
    var s = value;
    s = value.replace(/\-/g, '/');

    return this.optional(element) || !/Invalid|NaN/.test(new Date(s));
};

as implemented here