Reputation: 12447
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.
Upvotes: 9
Views: 15533
Reputation: 68
As lukyer posted, there can be issues relating to the jquery.validate*.min.js files, especially if you have added your own validation in to those files. The simple answer I found that worked for me when the final release system failed to validate dates in IE (Chrome worked without issue) was to simply remove the pre-packaged minified validation files altogether and let the beast handle it's own minification from the "master" files. Only shame was that I didn't connect lukyer's reply to the solution earlier...
(I'd probably post this as a comment but apparently I've not yet gained quite enough rep: must try harder!)
Upvotes: 1
Reputation: 8023
Actually it is not bug in browser, client validation issues can occur because of MVC bug (even in MVC 5) in jquery.validate.unobtrusive.min.js which does not accept date/datetime format in any way. Unfortunately you have to solve it manually.
My finally working solution:
You have to include before:
@Scripts.Render("~/Scripts/jquery-3.1.1.js")
@Scripts.Render("~/Scripts/jquery.validate.min.js")
@Scripts.Render("~/Scripts/jquery.validate.unobtrusive.min.js")
@Scripts.Render("~/Scripts/moment.js")
You can install moment.js using:
Install-Package Moment.js
And then you can finally add fix for date format parser:
$(function () {
$.validator.methods.date = function (value, element) {
return this.optional(element) || moment(value, "DD.MM.YYYY", true).isValid();
}
});
Upvotes: 1
Reputation: 45
Quite old this thread. Just landed here having similar issues. In another thread I read that there could be an issue with Version incompatibility by all these *.js libraries involfed somehow in the Validation. Perhaps the following link can help other Readers landig here: https://stackoverflow.com/a/16551039
Hope this helps
Upvotes: 0
Reputation: 385
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
Upvotes: 4
Reputation: 1
I was having the same issue, it was driving me bananas! Basically, mvc validation will always render DateTime objects to require a value on the textbox. Why? Because it is directly associated with a DateTime
object. If you declare your ViewModel
with a ? symbol, you will make it nullable. This way it won't bother you requiring validation:
public class MyViewModel
{
DateTime? StartDate { get; set; }
}
Hope this helps
Upvotes: -1
Reputation: 101
Just wanted to make a little comment on this line if someone else has trouble with this later:
<input type="date" id="TestDate" value="@Model.TestDate.Value.ToString("dd/MMM/yyyy")" />
In some cases (at least my case earlier) this would translate into this format: "01.01.2012", because with some cultures you can't specify slashes like that to actually get it formatted like that, it will just turn them into dots, so I had to write:
@Model.TestDate.Value.ToString("dd\/MMM\/yyyy");
Which gave me "01/01/2012".
Upvotes: 0
Reputation: 2794
For my case, I use the text field for the date, so it didnt cause problem for jquery validation:
<div class="editor-field">
@Html.TextBox("ExpiryDate", String.Format("{0:ddd, dd MMM yyyy}", DateTime.Now), new { id = "expirydate" })
@Html.ValidationMessageFor(model => model.ExpiryDate)
</div>
So why not you try format your date like this instead of using the input type=date?
Hope this help :)
Upvotes: 1
Reputation: 12447
So it looks like jquery.validate.unobtrusive has a problem with input type="date"
. This must be a bug that only occurs in IE and Safari.
When i removed the unobtrusive js file, it submitted the form fine. When i added the unobtrusive js file back in and changed the input type to text, it worked.
Annoying bug. Needs to be fixed.
Upvotes: 3
Reputation: 93
Have you tried simply changing the type to:
@Html.TextBoxFor(model => model.startDate, new { @class = "date" })
I was having the same issue with EditorFor... so I changed it to this and then applied my jquery datepicker to the 'date' class added to the textbox.
Upvotes: 0
Reputation: 1039538
There are really two things here:
Both should use the same format for this to work. Let's first deal with the server side validation. You could write a custom model binder for the DateTime fields which will use the format specified for displaying when binding them back. Here's an example of such model binder.
Next we must deal with client side validation. For this you could write a custom rule which will be attached to the given elements:
<script type="text/javascript">
$.validator.addMethod(
'myDateFormat', function (value, element) {
// TODO: put your validation logic here that will parse the string
// and validate it
return false;
},
'Please enter a date in the format dd-MMM-yyyy'
);
$(function () {
// we attach the custom validation rule to the given input element
$('#FooDate').rules('add', 'myDateFormat');
});
</script>
You could also use adapters with a custom attribute.
Upvotes: 2