views:

1659

answers:

6

I am trying to format a date rendered by ASP.Net MVC's TextBoxFor using the value of a strongly typed view. The date is nullable so if it is null I want to see a blank value, otherwise I want to see it in the format MM/dd/yyyy.

<%= Html.TextBoxFor(model => model.BirthDate, new { style = "width: 75px;" })%>

Thanks,
Paul Speranza

A: 

Have you tried just passing in the date format that you'd like?

Html.TextBoxFor(model => model.BirthDate.ToString("MM/dd/yyyy"), 
                new { style = "width: 75px;" })
womp
If I use that<%= Html.TextBoxFor(model => model.BirthDate.Value.ToString("MM/dd/yyyy")) %>I get the exception "Templates can be used only with field and property accessor expressions."
Paul Speranza
A: 

You can use this attribute

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

iaimtomisbehave
Thanks but the data never gets formatted either way, null or with a value.
Paul Speranza
That is strange I tried both the scenarios and it worked fine.
iaimtomisbehave
I read somewhere, I think on an MVC team member's blog, that it does not work with TextBoxFor. Is that what you have it working with?
Paul Speranza
Yes but I tried with regular object it isn't a EDM.
iaimtomisbehave
My is just a POCO. I could not get this to work. I ended up with raw html and embedded the value in <% %> tags.
Paul Speranza
A: 

Have you tried to force the culture of your current thread application? You can override it in the web.config using this line (in the tag) :

<!-- Default resource files are set here. The culture will also change date format, decimal, etc... -->
<globalization enableClientBasedCulture="false" culture="en-US" uiCulture="en-US"/>
Guillaume Roy
+1  A: 

First, add this extension for getting property path:

public static string GetPropertyPath<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> property)
{                       
     Match match = Regex.Match(property.ToString(), @"^[^\.]+\.([^\(\)]+)$");
     return match.Groups[1].Value;
}

Than add this extensions for HtmlHalper:

public static MvcHtmlString DateBoxFor<TEntity>(
            this HtmlHelper helper,
            TEntity model,
            Expression<Func<TEntity, DateTime?>> property,
            object htmlAttributes)
        {
            DateTime? date = property.Compile().Invoke(model);

            // Here you can format value as you wish
            var value = date.HasValue ? date.Value.ToShortDateString() : string.Empty;
            var name = ExpressionParseHelper.GetPropertyPath(property);

            return helper.TextBox(name, value, htmlAttributes);
        }

Also you should add this jQuery code:

$(function() {
    $("input.datebox").datepicker();
});

datepicker is a jQuery plugin.

And now you can use it:

 <%= Html.DateBoxFor(Model, (x => x.Entity.SomeDate), new { @class = "datebox" }) %>
Сергій
A: 

It's a dirty hack, but it seems to work.

<%= Html.TextBoxFor(model => model.SomeDate,
    new Dictionary<string, object> { { "Value", Model.SomeDate.ToShortDateString() } })%>

You get the model binding, and are able to override the HTML "value" property of the text field with a formatted string.

Cephas
If this worked in MVC 1, it has stopped working in MVC 2. The default output seems to take priority for the value attribute. Not that I expected otherwise, but it doesn't work regardless of trying it as a `Dictionary<string, object>` or an anonymous object (e.g., `new { value = Model.SomeDate.ToShortDateString() }`).
patridge
A: 

A simple solution is to not use the strongly typed helper.

<%= Html.TextBox("StartDate", string.Format("{0:d}", Model.StartDate)) %>
andersjanmyr
For complex models (e.g., Model.SubModel.SubSubModel), you will have to do the logic for generating your id/name with the appropriate prefix. Otherwise, you break binding and validation scope within the model state.
patridge