This project is read-only.

DateTimeFor control not working

Apr 27, 2016 at 9:01 AM
I am trying to use two related @Html.DateTimeFor controls in a partial view of which the html is dynamically loaded into a bootstrap Modal div by a jQuery Ajax call.
After injecting the partial view I execute $.validator.unobtrusive.parse(...);
Without the DateTimeFor controls everything works as expected.

With the DateTimeFor controls the app freezes for 15 seconds and then displays an error popup in VS complaining about some code in MVCControlToolkit.Controls.Datetime-3.0.0.js:

Unhandled exception at line 157, column 13 in http://localhost:50592/Scripts/MVCControlToolkit.Controls.Datetime-3.0.0.js
0x800a1391 - JavaScript runtime error: 'DateTimeMonthes' is undefined
The strange thing is that the .js file contains no other reference to DateTimeMonthes
Also a search in the .js file on DateTimeMonths gives no result...

The relevant parts of my model:
[DateRange(DynamicMaximum = "EndDate", RangeAction = RangeAction.Verify, 
    DynamicMaximumDelay = "Delay", SMaximum = "9999-9-9", SMinimum = "2016-1-1")]
public DateTime StartDate { get; set; }

[DateRange(SMaximum = "9999-9-9", SMinimum = "2016-1-1")]
public DateTime EndDate { get; set; }

public TimeSpan Delay { get; set; }
And the relevant parts of my partial .cshtml:
<div class="form-group">
    @Html.LabelFor(m => m.StartDate, new { @class = "col-md-3 control-label" })
    <div class="col-md-9">
        @{ var dtStart = Html.DateTimeFor(m => m.StartDate, DateTime.Now);  }
        @dtStart.Date() &nbsp;&nbsp; @dtStart.Time()

        @Html.ValidationMessageFor(m => m.StartDate, "", new { @class = "text-danger" })

<div class="form-group">
    @Html.LabelFor(m => m.EndDate, new { @class = "col-md-3 control-label" })
    <div class="col-md-9">
        @{ var dtEnd = Html.DateTimeFor(m => m.StartDate, new DateTime(9999,9,9));  }
        @dtEnd.Date() &nbsp;&nbsp; @dtEnd.Time()

        @Html.ValidationMessageFor(m => m.EndDate, "", new { @class = "text-danger" })
Apr 27, 2016 at 9:28 AM
Sorry, I discovered my error: I referenced StartDate in both DateTimeFor controls.
After correcting this error the modal popup opens correctly and rapidly.
Apr 27, 2016 at 10:14 AM
But unfortunately the Day and Month dropdown controls only contain one single option element (the actual value's). So I can't use them to set a new date.

Another concern is how to read the values from the html when I want to save? Up till now I use
var data = $('#form').serialize();
to retrieve the values of all input controls in the form. This creates a regular querystring with a key/value pair for each input element. The keys correspond with the name attribute of each input element.
The normal model driven MVC razor Html helpers produce html input elements with the name attribute equal to the corresponding property name in the model.
But the MVC Controls Toolkit Html.DateTimeFor() helper does something completely different.
I find a hidden control with attr. name = display.$$, two javascript script tags, two select input elements with attr. name=$.day and $.month and then a textbox input with attr. name = $.year.

I could of course try to add new properties to my model to retrieve the values in $.day, $.month and $.year, but that will not work because in C# propery names can not start with a dollar sign and the may not contain dots.
Another problem is that the second DateTimeFor control uses exactly the same name attributes.
And a last strange thing is that these input controls do not have an id attribute.

So I have two questions:
  1. Why can't I replace the actual date parts with new values?
  2. How can I send the form values in an elegant way to the server with a jQuery Ajax call?
Apr 27, 2016 at 11:52 AM
Edited Apr 27, 2016 at 11:53 AM
I think I discovered the problem: one of the dates I was testing with was outside of the range defined by SMinimum and SMaximum.
After correcting this the controls seem to work OK and $('#form).serialize() also works as expected.

One issue remains though: opening my modal popup with these controls in it takes at least 20 seconds, not only the first time but every time...
That is clearly unacceptable.
If I change my code to use the bootstrap datepicker I have a delay of 2 seconds the first time, but after that the modal popups open very rapidly.
Apr 27, 2016 at 12:57 PM
20 seconds appears too much! See if the javascript consolle display an error. Anyway the DateTimeFor control is slow and shouldnt be used with dynamically created Html. Use the TypedTextBoFor, instead, that is faster and diplays a bootstrap date picker, and has similar functionality

Anyway your 20s second is not normal! Something "bad" is happening in your modal.

Aniway with the new Mvc Controls Toolkit all simple controls like DateTimeFor will disappear since each input control will automatically (and efficiently) display a widget adequate for the input type/ or an Html5 native controls, based on some configuration infos fornished once and forall in a JSON file.
Apr 27, 2016 at 1:05 PM
About, var data = $('#form').serialize(); You dont need to care about these strange fields, they are automatically takent into account by MvcControlsToolkit custom modelbinder. Just use the same model you would use normally. Everything should work since the model binder transform all these data in the right format. However, you should send everything with a POST to the server.

If you use a TypedTextBoxFor you avoid these strange fields anyway, and you may continue using the DateRange attribute in exactly the same way.