简体   繁体   中英

Date model in jQuery datepicker

I need to store in th SQL-Server DB a date format "29-12-2014" using datepicker but I get the message The field XXX must be a date.

My last try was Regular Expression:

Model #1:

[RegularExpression(@"([3][0,1]|[0-2]\d)-([1][0-2]|[0]\d)-(\d\d\d\d)", ErrorMessage = "Valor inválido.")]
public Nullable<DateTime> ETD { get; set; }

Model #2:

[DataType(DataType.DateTime)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd-MM-yyyy}")]
public Nullable<DateTime> ETD { get; set; }

View:

<div class="editor-field">
    @Html.TextBoxFor(model => model.ETD)
    @Html.ValidationMessageFor(model => model.ETD)
</div>

jQuery:

$(function () {
     $("#ETD").datepicker();
});

I always get the message "The field ETD must be a date."

Any idea?

Thanks.

Its my understanding that the format 'dd-MM-yyyy' is the problem, here. The jquery unobtrusive validation is trying to instantiate a new Date(strVal) object, and it doesn't know what to do with the string '29-12-2014'.

See Unobtrusive validation in Chrome won't validate with dd/mm/yyyy

magritte answered that redefining the unobtrusive validator's date method, using the jQuery Globalize library, to parse with the desired format string should solve the issue:

$.validator.methods.date = function (value, element) {
    return this.optional(element) || Globalize.parseDate(value, "dd-MM-yyyy", "en");
}

Update

I recreated your problem locally, and was able to replicate the 'required field validation not firing prior to form post' issue, when the Globalization library was not installed. Once I installed and loaded the library, the front-end worked as expected, with unobtrusive validation accepting the modified dd-MM-yyyy date.

The library can be installed using the NuGet package manager and the following package: http://www.nuget.org/packages/jquery-globalize/ . Then you need to update your html to include the globalize.js script.

The back-end was another story, which is going to rely on your local machine's globalization profile. I am assuming you are running a non-en/us machine where this format might parse? My machine is english/us and does not natively parse the modified date format, however using the below command, I successfully got a valid datetime:

DateTime.ParseExact(Request.Form["ETD"], "dd-MM-yyyy", System.Globalization.CultureInfo.InvariantCulture);

This should work to set your format in the box:

$("#ETD").datepicker({
    dateFormat    : 'dd-mm-yy'
});

Is the validation message coming from jQuery or C#? See this answer with respect to the former: https://stackoverflow.com/a/19519745/1803682

With the help of @DanS I was able to elaborate a solution for the Date Validation for my country, Portugal (pt-PT) and here is the complete solution for anybody that have a problem validating a date:

First of all, you need to install the nuget package:

http://www.nuget.org/packages/jquery-globalize/

Then include in the page where you want to make the validation (or in the Bundle like me) the links to the core library and your country's culture file (note:put always first the core and then the culture file or else you will get an undefined error)

bundles.Add(new ScriptBundle("~/bundles/saida").Include(
            "~/Scripts/Presenter/Saida/create.js",
            "~/Scripts/Globalize/globalize.js",
            "~/Scripts/Globalize/Cultures/globalize.culture.pt-PT.js",
            "~/Scripts/Common/date.js"));

Set the Model:

[Required(ErrorMessage = "Preenchimento obrigatório.")]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd-MM-yyyy}")]
[Display(Name = "Data da DAU")]
public DateTime? DAUData { get; set; }

I did not put any ErrorMessage in the DataType property because it's not passed to the View, instead, you can put a custom message in the View:

<div class="editor-field">
    @Html.EditorFor(model => model.DAUData)
    @Html.ValidationMessageFor(model => model.DAUData, "Formato de data inválido.")
</div>

But if you use the jQuery datepicker function with the definition of the format, you don't need to worry about the format:

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

The property changeYear is to presente a dropdown to choose the year (not mandatory, only a nice option to garanty that the value is always valid), and don't forget to inlcude the jQuery and jQueryUI references in your file to presente the calendar correctly.

To complete the client side script, I have the culture's format validation:

$.validator.methods.date = function (value, element)
{
    return this.optional(element) || Globalize.parseDate(value, "dd-MM-yyyy", "pt-PT");
 }

I also have a template for the date format in the View (place it in the Shared/EditorTemplates/ folder and don't forget to user the @Html.EditorFor razor method in the View:

@{
    var value = "";

    if (Model.HasValue) 
    {
        value = String.Format("{0:d}", Model.Value.ToString("dd-MM-yyyy"));
    }
}

@Html.TextBox("", value, new { @class = "datefield", type = "text", autocomplete = "off"     })

Now anytime that you will need a date, use the Template, and the class "datepicker", and that's it!

Thanks again DanS ;)

Have you seen this link? I believe they had a similar problem: The field date must be a date in mvc in chrome

and also this one: Jquery Datepicker Chrome

The are several things going on in localizing your app.

This Phil Haack article goes through it. It's pretty old, but I guess all the concepts are the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM