28

I'm doing a simple MVC4 Internet application, which allows to add some items to the categories.

Here is what i've done so far.

I've a datepicker in mvc view. The script for the datepicker is like this.

<script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.20.min.js")" type="text/javascript"></script>
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
    $(function () {
        $('#dtItemDueDate').datepicker({
            dateFormat: 'dd/mm/yy',
            minDate: 0
        });
    });
</script>

My model property :

        [DisplayName("Item DueDate")]
        [Required]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}",ApplyFormatInEditMode = true)]
        [DataType(DataType.DateTime)]
        public DateTime? dtItemDueDate { get; set; }
        public char charCompleted { get; set; }

and in my view i've done this:

@Html.TextBoxFor(m => m.dtItemDueDate)
@Html.ValidationMessageFor(m => m.dtItemDueDate)

The error is like this:

The field Item DueDate must be a date.

The strange this is that it does work in IE and mozilla, but doesnot work in Chrome.

I found many posts on SO, but none of them help

Any ideas/suggestions ?

Karthik Chintala
  • 5,465
  • 5
  • 30
  • 60

6 Answers6

48

Without changing jquery.validate.js, you can use the code snip below in $(document).ready():

jQuery.validator.methods.date = function (value, element) {
    var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
    if (isChrome) {
        var d = new Date();
        return this.optional(element) || !/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
    } else {
        return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
    }
};
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Mahesh
  • 2,731
  • 2
  • 32
  • 31
  • 1
    Seems to be the best solution, without modifying the jquery file which is not recomended – Pinte Dani Apr 11 '15 at 12:01
  • I would give you a million up votes if I could - works perfectly! Thank you :) – Novastorm Aug 15 '16 at 10:43
  • great answer!! thanks Kyle – Jay Sep 28 '16 at 13:38
  • This fails normal validation on other fields so [here](http://stackoverflow.com/questions/12633471/mvc4-datatype-date-editorfor-wont-display-date-value-in-chrome-fine-in-interne) is the **working solution** , hope helps. – Shaiju T Oct 05 '16 at 10:26
30

Editor note: This answer is no longer valid, as of jQuery 1.9 (2013) the $.browser method has been removed


According to this post it's a known quirk with Webkit-based browsers.

One solution is to modify jquery.validate.js by finding the function date: function (value, element) and put this code in it:

if ($.browser.webkit) {
    //ES - Chrome does not use the locale when new Date objects instantiated:
    var d = new Date();
    return this.optional(element) || !/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
}
else {
    return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
}
Community
  • 1
  • 1
Rowan Freeman
  • 15,724
  • 11
  • 69
  • 100
  • +1 to the user who posted answer and to you as well for finding the threading, coz i didn't find that thread :P – Karthik Chintala Mar 29 '13 at 16:35
  • 8
    The $.browser method has been deprecated for a while and has been removed as of jQuery 1.9. – SimonGates May 28 '13 at 11:52
  • 8
    The above is not the correct approach for fixing this problem. Firstly you should never change the jquery validate source code secondly as stated above $.browser.webkit is deprecated. The way to achieve this fix for this is to simply add this jQuery.validator.methods.date = function (value, element) { if (value) { try { $.datepicker.parseDate('dd/mm/yy', value); } catch (ex) { return false; } } return true; }; – Maxim Gershkovich Aug 14 '14 at 23:59
  • @MaximGershkovich that doesn't work for me, as `$.datapicker` is null which throws me into the exception, returning false for "02/05/2003" (Chrome 38). – Zhaph - Ben Duguid Oct 14 '14 at 12:00
  • **I do not recommend this method.** As has been stated many times now this solution is not ideal and completely outdated. If you still have this issue please find a better solution. – Rowan Freeman May 13 '16 at 11:17
  • This fails normal validation on other fields so [here](http://stackoverflow.com/questions/12633471/mvc4-datatype-date-editorfor-wont-display-date-value-in-chrome-fine-in-interne) is the **working solution** , hope helps. – Shaiju T Oct 05 '16 at 10:26
  • This work for my dates dd/mm/yyyy: //Corrige o BUG de validação do chrome do campo Date no formato dd/mm/yyyy jQuery.validator.methods.date = function (value, element) { var d = value.split("/"); return this.optional(element) || !/Invalid|NaN/.test(new Date((/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())) ? d[1] + "/" + d[0] + "/" + d[2] : value)); }; – EBENEZER CURVELLO Jul 11 '17 at 13:07
  • This work for my dates dd/mm/yyyy: //Corrige o BUG de validação do chrome do campo Date no formato dd/mm/yyyy //fonte https://stackoverflow.com/questions/18546971/mvc-4-how-to-validate-a-non-us-date-with-client-validation jQuery.validator.methods.date = function (value, element) { return this.optional(element) || moment(value, "DD/MM/YYYY", true).isValid(); }; – EBENEZER CURVELLO Jul 11 '17 at 13:38
8

Rowan Freeman solution wont work for me since .toLocaleDateString(value) doesn't parse value strings

here's the solution i came up with => in jquery.validate.js find this function definition: "date: function (value, element)" and replace the code with:

// http://docs.jquery.com/Plugins/Validation/Methods/date
date: function (value, element) {
    var d = value.split("/");
    return this.optional(element) || !/Invalid|NaN/.test(new Date((/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())) ? d[1] + "/" + d[0] + "/" + d[2] : value));
},
Chtioui Malek
  • 11,197
  • 1
  • 72
  • 69
  • This works if you are using jQuery 1.9, but it needs tweaking if you use different date format and/or separator. – berzinsu Aug 22 '13 at 08:13
  • 10
    You can fix it without changing jquery itself like so, overriding the default behaviour: `jQuery.validator.addMethod('date', function (value, element, params) { if (this.optional(element)) { return true; }; return /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2} \d{2}:\d{1,2}:\d{1,2}$/.test(value); }, '');` – Pawel Gorczynski Sep 20 '13 at 11:38
  • 2
    Nice catch. Same issue for me, this one is working! – Jelle Oosterbosch Jul 16 '14 at 13:57
  • Great comment @PawełG. Finally helped solve my problem! – Ben Smith Feb 02 '16 at 14:50
8

Below is the working code that may helpful for some one to fix the date picker issue in chrome and safari: Model:

public DateTime? StartDate { get; set; }

View:

@Html.TextBoxFor(model => model.StartDate, "{0:dd/MM/yyyy}", new { @type = "text", @class = "fromDate" })

js:

$(function () {
    checkSupportForInputTypeDate();

    $('#StartDate').datepicker({        
        changeMonth: true,
        changeYear: true,
        dateFormat: 'dd/mm/yy'
    });    
});

//Function to configure date format as the native date type from chrome and safari browsers is clashed with jQuery ui date picker.
function checkSupportForInputTypeDate() {
    jQuery.validator.methods.date = function (value, element) {
        var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
        var isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);
        if (isSafari || isChrome) {
            var d = new Date();
            return this.optional(element) || !/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
        } else {
            return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
        }
    };
}
bummi
  • 27,123
  • 14
  • 62
  • 101
KSK
  • 81
  • 1
  • 1
7

Here's Maxim Gershkovich's solution spelled out a little more:

jQuery.validator.methods.date = function (value, element) {
    if (value) {
        try {
            $.datepicker.parseDate('dd/mm/yy', value);
        } catch (ex) {
            return false;
        }
    }
    return true;
};

Notes:

  • This depends on the jQuery datepicker method that comes with jQuery UI
  • This is actually more robust that the native date validation that comes with jQueryValidate.

    According to the docs on date validation:

    Returns true if the value is a valid date. Uses JavaScript's built-in Date to test if the date is valid, and therefore does no sanity checks. Only the format must be valid, not the actual date, eg 30/30/2008 is a valid date.

    Whereas parseDate will check that the date is valid and actually exists.

Community
  • 1
  • 1
KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • Great thanks @KyleMit this is the only one which worked for me both in Chrome & Firefox (both were causing issue) – nickornotto Apr 26 '17 at 16:42
0

I solved this issue by changing from DateTime to String.

This is the best solution for a good maintance that I can think at the moment.

alansiqueira27
  • 8,129
  • 15
  • 67
  • 111