When using the following I lose the binding on the field
#Html.EditorFor(model => model.Quote.DiscountRate, new { #class = "form-control pull-left " })
And the model field looks like this:
[DisplayFormat(DataFormatString = "{0:P2}",ApplyFormatInEditMode =true)]
public double? DiscountRate { get; set; }
if I remove the DisplayFormat the binding still works.
I also tried the following with the same result:
#Html.TextBoxFor(model => model.Entity.DiscountRate, "{0:P2}", new { #class = "form-control pull-left" })
In both cases if I remove the formatting I get my binding back
What I have discovered is that when you apply a DisplayFormat, it is as the name suggests, for display. If you want to display a decimal value with formatting and make it available for editing, you have to handle the conversion from text back to decimal at post time -- or whenever you need the actual value.
Related
I am trying to populate #Html.EditorFor helper. I have created a view model with the below property
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yy}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
and my helper is set up as below (a)
#Html.ValidationMessageFor(m => m.YearBought)
#Html.EditorFor(model => model.YearBought, new { #type = "date" })
I have also tried (b)
#Html.ValidationMessageFor(m => m.YearBought)
#Html.EditorFor(model => model.YearBought.Value.Date)
Using the above format (a) nothing is displayed. Using the above format (b) 12/05/2014 00:00:00 is displayed in textbox format.
I am trying to achieve a datepicker format without a time displayed
I have reviewed several other questions but cant see what i've done different.
When I look in my database, the value is save as 2014-05-12 and when I am saving the value the EditorFor helper generates the required input facility
questions reviewed
first second third....the list goes on
EDIT
just opened the console in chrome dev tools and so this message
The specified value "12/05/14" does not conform to the required format, "yyyy-MM-dd"
I thought DisplayFormat(DataFormatString = "{0:dd/MM/yy}" was defining how to display my date?
You need to use the ISO format when using type="date"
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
This will display the date in the browsers culture.
Note there is no need to add #type = "date". The EditorFor() method will add that because of the DataType attribute. Note also that type="date" is only supported in Chrome (FireFox and IE will just generate a normal textbox)
If you do want to display the format dd/MM/yyyy in a standard textbox then you can use
#Html.TextBoxFor(m => m.YearBought, "{0:dd/MM/yyyy}")
As it says in Stephen's answer, you have to make your formats match between the tags in your model to what is shown in the View, and it should be of the yyyy-MM-dd (ISO) format, regardless of how you actually want to display the date:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
// .... your namespace .... your class....
[DisplayName("Year Bought")]
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
And he's right, because we have [DataType(DataType.Date)], we don't need #type = date in our HtmlAttributes on the View.
Where my answer differs from his is how to actually apply the value from the Model to the control on the View. Since YearBought is a Nullable<DateTime>, we have to set it with its value a certain way, using .Value:
#Html.EditorFor(model => model.YearBought,
new { htmlAttributes = new { #class = "form-control datepicker",
#Value = Model.YearBought.Value.Date.ToString("yyyy-MM-dd") } })
Paying close attention to set the .ToString("yyyy-MM-dd"). It's not going to display in the box like that, though - at least for me - probably because my U.S. Regional settings on my computer take over and display it as MM/dd/yyyy regardless. This might confuse some, but it's better to just "do" and not worry about it.
If YearBought was just a straight DateTime instead of a DateTime?, it would be without the .Value:
#Html.EditorFor(model => model.YearBought,
new { htmlAttributes = new { #class = "form-control datepicker",
#Value = Model.YearBought != null ?
Model.YearBought.Value.Date.ToString("yyyy-MM-dd") : null } })
I would make your view model's YearBought property a String for the easiest manipulation. The server can format the date, it can do the parsing on postback, and you can still use the DataType.Date data annotation for jQuery validation. This also ensures that the display value will be exactly what you want prior to being submitted to the view.
Alternative to the HTML type attribute, you can use an EditorTemplate in MVC to put the markup, CSS, and JS needed to render a custom editor for a known C# datatype like DateTime.
Here is a walkthrough for creating a custom 'EditorTemplate' in MVC (although not for a Date data type, but concept is the same)
I am trying to properly display a (nullable) Date-type-only field. For this field, my Model and ViewModel classes are defined as....
[DisplayFormat(DataFormatString = "{0:M/dd/yyyy}")]
[DataType(DataType.Date)]
public DateTime? PeriodEnd { get; set; }
In my details view (based on model), it's showing the date properly (excluding the time element):
#Html.DisplayNameFor(model => model.PeriodEnd)
Problem: In my edit view (based on ViewModel), it's showing the time also, which I'm trying to exclude. Here's how it's defined.
#Html.TextBoxFor(model => model.PeriodEnd, new { #class = "datepicker" })
I also tried....
#Html.TextBoxFor(model => model.PeriodEnd.Value().ToShortDateString(),
new { #class = "datepicker" })
... but that produced an error.
Is there a better way to accomplish this?
Well, first, you're not utilizing the data annotation. Something like DataType.Date doesn't do anything on its own. Using editor templates (Html.EditorFor), it can be utilized to provide an date type input, but if you use Html.TextBoxFor, it's basically ignored.
You can fix that by either 1) using Html.EditorFor instead or 2) explicitly setting the type: #Html.TextBoxFor(m => m.PeriodEnd, new { type = "date", #class = "datepicker" }).
This was the solution:
#Html.TextBoxFor(m => m.PeriodEnd, "{0:M/d/yyyy}", new { #class = "datepicker" })
Thanks to all for your feedback!
#if (Model.RecDateFrom.HasValue)
{
#Html.EditorFor(model => model.RecDateFrom,
new {htmlAttributes =
new {#Value = Model.RecDateFrom.Value.ToString("yyyy-MM-dd"),
#class = "form-control input-sm small-input-fix"}})
}
else
{
#Html.EditorFor(model => model.RecDateFrom,
new {htmlAttributes = new {#class = "form-control input-sm small-input-fix"}})
}
#Html.ValidationMessageFor(model => model.RecDateFrom, "", new {#class = "text-danger"})
You can see above how I have to handle if the datetime is null before setting the value. I have to set the value because MVC uses the incorrect format for a date input, making it so chrome doesn't have the correct default value.
I do not want to use the accepted solution in this question because that changes the format of the display for also.
I've tried using editor templates, but it seems like you have to start from scratch, rather than extending the built in editor template for Date datatypes (this seems like a large flaw of MVC, unless I'm missing something).
If you are wanting to render the browsers HTML5 datepicker, you just need to apply the correct attributes to you property. Note the format string must be in the ISO format.
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime RecDateFrom { get; set; }
and then in the view
#Html.EditorFor(m => m.RecDateFrom, new { htmlAttributes = new { #class = "form-control input-sm small-input-fix" } })
Side note: The HTML5 datepicker is not supported in older browsers and not yet at all in FireFox, so it may be better (at least in the short term) to use a jquery plugin (and set the format in the plugin initializer). For example, using the jquery ui datepicker - $('#datepicker').datepicker({ dateFormat: 'dd-mm-yy' })
I have a textbox on my view and I'm only looking it to display the current date and time(in readonly..how can this be done?
Currently I have this in the view:
<div class="editor-field">
#Html.EditorFor(model => model.Opened, new { #value = System.DateTime.Now, #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.Opened)
</div>
..And this in the model:
[Required]
public DateTime Opened
{
get;
set;
}
How can this be implemented in MVC?
Thanks,
I recommend you using a Label. I think it's unusual display dates and time at TextBoxes.
Regards.
Well, you can do that, but #Angel Manuel Garcia Car's suggest is what you should be doing logically.
Anyways, here is the code. As long as you are creating a textbox, you should be using TextBoxFor.
#Html.TextBoxFor(model => model.Opened, new { #value = DateTime.Now, #readonly="readonly" })
I don't see any point here.
I am trying to get #String.Format("{0:0.00}",Model.CurrentBalance) into this #Html.TextBoxFor(model => model.CurrentBalance, new { #class = "required numeric", id = "CurrentBalance" })
I just want the currency to show up as .00 inside of my textbox but am having no luck. Any ideas on how I do this?
string.format("{0:c}", Model.CurrentBalance) should give you currency formatting.
OR
#Html.TextBoxFor(model => model.CurrentBalance, new { #class = "required numeric", id = "CurrentBalance", Value=String.Format("{0:C}",Model.CurrentBalance) })
#Html.TextBoxFor(model => model.CurrentBalance, "{0:c}", new { #class = "required numeric", id = "CurrentBalance" })
This lets you set the format and add any extra HTML attributes.
While Dan-o's solution worked, I found an issue with it regarding the use of form-based TempData (see ImportModelStateFromTempData and ExportModelStateToTempData). The solution that worked for me was David Spence's on a related thread.
Specifically:
[DisplayFormat(DataFormatString = "{0:C0}", ApplyFormatInEditMode = true)]
public decimal? Price { get; set; }
Now if you use EditorFor in your view the format specified in the annotation should be applied and your value should be comma separated:
<%= Html.EditorFor(model => model.Price) %>