0

I've got an MVC 5 project where there's a big form, which is serialized to Knockout using:

var vm = ko.mapping.fromJS(@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)));

Some of the form fields are textboxes using jQuery-ui-datepicker where the user can select a date:

@Html.TextBoxFor(m => m.ModelDate, "{0:d}", new { @class = "form-control", @data_bind = "value: ModelDate" })

My problem is that if ViewModel's nullable ModelDate property contains a DateTime value, the textbox displays something like 2014-04-05T18:00:00, but not 04/5/2015. The formatting (e.g. "{0:d}") is ignored.

I don't know my string-formatting parameter is being ignored, and I'm confused about what's going on behind the scenes when the C# nullable DateTime in the ViewModel is mapped into KnockoutJS. Is there a typical MVC or Knockout solution to this kind of problem?

alex
  • 6,818
  • 9
  • 52
  • 103
  • Have you tried m.ModelDate.ToShortDateString() OR it might have to be "0:dd" not single d –  Mar 18 '15 at 20:16
  • @SythnetP I haven't tried that, and that's a very good idea, but most of my dates are Nullables, which do not have the ToShortDateString() property. – alex Mar 18 '15 at 20:21
  • Only other option I would suggest would be to check if it's not null then cast it as a DateTime or convert it to a DateTime –  Mar 18 '15 at 20:24
  • @SythnetP Actually, even attempting ToString() results in the error: "Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.". – alex Mar 18 '15 at 20:26
  • Well I found this link http://stackoverflow.com/questions/13725057/formatted-date-textboxfor and they are using dd, are you sure your format is supported? –  Mar 18 '15 at 20:27
  • @SythnetP Yep, "d" represents the [C# short date](https://msdn.microsoft.com/en-us/library/az4se3k1%28v=vs.110%29.aspx#ShortDate) format. – alex Mar 18 '15 at 20:31
  • @Html.TextBoxFor(m=> m.ModelDate, String.Format("{0:d}", Model.ModelDate) - http://stackoverflow.com/questions/1961114/date-only-from-textboxfor –  Mar 18 '15 at 20:38
  • @SythnetP This also doesn't work. The textbox still displays the date the same way. – alex Mar 18 '15 at 21:02
  • 1
    Could it have something to with the data binding overriding it? Noticed @data_bind = "value: ModelDate" } could be displaying the value over what you're trying to show? –  Mar 18 '15 at 21:06

2 Answers2

0

The way that I solved this problem uses Razor, so it's a little dodgy, but it works.

In the background, this is a big form which is dynamically generated from a few partial views where the @Html.TextBoxFors reside. When the ViewModel is empty (a user is filling out a new form), there isn't an issue. When the ViewModel isn't empty (a user is reading a submitted form) , the dates don't format correctly. On SythnetP's suggestion, KnockoutJS's data bindings might be overwriting the C# formatting rules.

There seem to be some solutions using Knockout, but I decided to make the model stateful with respect to whether or not it represents a "new" form versus an "old" one.

Additionally, I made the ViewModel more viewmodel-ey by adding some strings:

public string FormattedModelDate { get; set; }

... which are populated with "short date formatted" DateTimes when the ViewModel is created.

if (vm.ModelDate.HasValue)
{
    vm.FormattedModelDate = vm.ModelDate.Value.ToShortDateString();
}

The end result is this:

@{
    if (Model.IsNewForm)
    {
        // display the Html.TextBoxFor m.ModelDate with the Knockout bindings 
    }  else {
        // display the Html.TextBoxFor m.FormattedModelDate without the Knockout bindings
    }
}
Community
  • 1
  • 1
alex
  • 6,818
  • 9
  • 52
  • 103
0

annotate your viewmodel

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? SomeDate { get; set; }

this will apply your formatting in your view.

Fran
  • 6,440
  • 1
  • 23
  • 35
  • I didn't mention this in the question, but that didn't work. I think I tried virtually every iteration of `String.format` in addition to that. – alex Mar 19 '15 at 19:43