Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to fix 'The field must be a date' on a datetime property in mvc

I need to capture date and time both for my model property. In my model class I have the following

[Required]
[DataType(DataType.DateTime)]
public DateTime? CallBackDate { get; set; }

When I enter a valid date time (e.g. 28/05/2015 15:55) I keep getting this error The field CallBackDate must be a date.

I have seen similar question and tried various answers but nothing seems to get rid of this. I m using unobtrusive client side validation and I can't disable it.

The source of the input field has the following markup

<input autocomplete="off" class="jquery_datetimepicker form-control hasDatepicker" data-val="true" data-val-date="The field CallBackDate must be a date." data-val-required="The CallBackDate field is required." id="CallBackDate" name="CallBackDate" placeholder="Enter your CallBackDate" type="text" value="">

And jquery datetime picker has the following markup

$('.jquery_datetimepicker').datetimepicker({
    dateFormat: 'dd/mm/yy',
    minDate: 0,
    showWeeks: true,
    showStatus: true,
    highlightWeek: true,
    numberOfMonths: 1,
    showAnim: "scale",
    showOptions: {
        origin: ["top", "left"]
    },
    timeFormat: 'hh:mm tt'
});

Any ideas? thanks

like image 509
rumi Avatar asked May 28 '15 15:05

rumi


5 Answers

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. It is not caused by datepicker nor browsers. 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();
    }
});
like image 169
lukyer Avatar answered Nov 07 '22 01:11

lukyer


I added the fix for date format parser, but I needed to set the format to 'L' so it could be work in all Locales:

$(function () {
$.validator.methods.date = function (value, element) {
    return this.optional(element) || moment(value, "L", true).isValid();
}
});
like image 32
scae2201 Avatar answered Nov 07 '22 00:11

scae2201


In the model for example:

    [Display(Name = "Insert Start Date")]
    [Required(ErrorMessage = "You must specify the date of the event!")]
    [DataType(DataType.DateTime, ErrorMessage = "Podaj prawidłową datę wydarzenia")]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm}", ApplyFormatInEditMode = true)]
    public DateTime StartDate { get; set; }

    [Display(Name = "Insert End Date")]
    [Required(ErrorMessage = "You must specify the date of the event!")]
    [DataType(DataType.DateTime, ErrorMessage = "Podaj prawidłową datę wydarzenia")]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm}", ApplyFormatInEditMode = true)]
    public DateTime EndDate { get; set; }

And View my example code:

<script>
$('#startDate').datetimepicker({
    onClose: function (dateText, inst) {
        var endDateTextBox = $('#endDate');
        if (endDateTextBox.val() != '') {
            var testStartDate = new Date(dateText);
            var testEndDate = new Date(endDateTextBox.val());
            if (testStartDate > testEndDate)
                endDateTextBox.val(dateText);
        }
        else {
            endDateTextBox.val(dateText);
        }
    }, dateFormat: 'yy-mm-dd',
    onSelect: function (selectedDateTime) {
        var start = $(this).datetimepicker('getDate');
        $('#endDate').datetimepicker('option', 'minDate', new Date(start.getTime()));
    }
}); ....

This caused positive effects: dateFormat: 'yy-mm-dd',

like image 6
voltdev Avatar answered Nov 07 '22 00:11

voltdev


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

Put this code in a file datepicker.js and include this file in html

like image 4
Vaibhav Nagar Avatar answered Nov 07 '22 01:11

Vaibhav Nagar


You need to make sure your application's Culture is properly set.

Example

The following example shows how cultures affect date parsing: https://dotnetfiddle.net/vXQTAZ

DateTime dateValue;
string dateString = "28/05/2015 15:55";

if (DateTime.TryParse(dateString, CultureInfo.CreateSpecificCulture("en-US"), DateTimeStyles.None, out dateValue))
{
    Console.WriteLine("Valid en-US date.");
}
else
{
    Console.WriteLine("Not a valid en-US date.");
}

if (DateTime.TryParse(dateString, CultureInfo.CreateSpecificCulture("fr-FR"), DateTimeStyles.None, out dateValue))
{
    Console.WriteLine("Valid fr-FR date.");
}
else
{
    Console.WriteLine("Not a valid fr-FR date.");
}

Output

Not a valid en-US date.

Valid fr-FR date.

Client Side Settings

You may also need to make sure that your client side validators are using properly cultures/globalization. If you are using jQuery validate plugin with MVC, see this extension to help modify that plugin to meet your needs: http://blog.icanmakethiswork.io/2012/09/globalize-and-jquery-validate.html

like image 2
kspearrin Avatar answered Nov 07 '22 00:11

kspearrin