MVC DisplayFormat Date + Time - c#

I'm trying to display the date in this format: yyyy-MM-dd HH:mm, but it doesn't work (of course yyyy-MM-dd works fine, problem is with time)
MODEL:
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm}", ApplyFormatInEditMode = true)]
public DateTime eventstart { get; set; }
VIEW:
<div class="form-group">
#Html.LabelFor(model => model.eventstart, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.eventstart, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.eventstart, "", new { #class = "text-danger" })
</div>
</div>

I'm assuming that you're generating an input with type="date". There's going to be two issues to be aware of with that:
As #JonSkeet pointed out, if you want to work with date and time, then you need to use DataType.DateTime. That will cause the input to be rendered as type="datetime". With an input of type "date", any time component will be discarded at best or at worst will not allow the value to parsed correctly for the browser date control, which brings us to:
The HTML5 datetime input types ("datetime", "date", "time") require the value to be in ISO format, i.e. YYYY-MM-DDTHH:MM:SSZ. The browser control will display the date/time in the user's local format based on parsing the ISO-formatted date, but it must be given the value in ISO format, first. If it's not, then it treats it as null, and will show the input value as empty.

Change:
#Html.EditorFor(model => model.eventstart,
new { htmlAttributes = new { #class = "form-control" } })
To:
#Html.EditorFor(model => model.eventstart,
new { htmlAttributes = new { #class = "form-control", #type="date" } })
Sure it will work.

Related

Client-side validation of US currency

I have an ASP.Net MVC 5 web application and I need to accept user input of US currency. Some valid inputs might be:
100
$100.21
$ 1,234
$1,234.56
Invalid inputs might be:
10,12
1o0.21
My (simplified) model looks like:
public class Claim {
[DisplayName("$ Amount)]
[DataType(DataType.Currency)]
[Required]
[Range(0.0, 200000.0)]
public decimal? DollarAmount { get; set; }
}
My cshtml markup looks like:
#Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9">
#Html.EditorFor(model => model.DollarAmount, new { htmlAttributes = new { #class = "form-control margin-bottom" } })
#Html.ValidationMessageFor(model => model.DollarAmount, "", new { #class = "text-danger" })
</div>
I used this advice this advice to build a binder that converts user input to a decimal, but client-side validation won't let the user enter a dollar-sign or commas. What do I need to do to allow the user to enter valid currency values, but warns her if she enters an invalid value? I'd prefer to do as much validation on the client-side as possible.
You Might want to look at https://github.com/globalizejs/globalize#currency-module. Helps allot with this kind of stuff. As for your Question to be able to use the Dollar Symbol you would not be able to store this Value as a decimal format in the database, only as a string.
There are a few things you can do, Use bootstrap to place a Dollar symbol in front of your TextBox using input-group-addon. Not sure if it will work properly as i see you have set Margin-bottom on your Textbox, telling me you might not be using bootstrap form tags above.
You may want to look into AutoNumeric jQuery plugin, It's well-maintained and they've basically "thought of everything" I could want for currency.
// View
#Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9 input-group">
<span class="input-group-addon">$</span>
#Html.EditorFor(model => model.DollarAmount, new { htmlAttributes = new { #class = "form-control margin-bottom" } })
#Html.ValidationMessageFor(model => model.DollarAmount, "", new { #class = "text-danger" })
</div>
// Class
public class Claim {
[DisplayName("$ Amount")]
[DataType(DataType.Currency)]
// {0:C} Will show as currency {0:N} to show Numbers
[DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true))]
[Required]
[Range(0.0, 200000.0)]
public decimal? DollarAmount { get; set; }
}
Another option is to have a hidden field with javascript that will duplicate the field from a string to decimal and that can be the one you submit like below.
// MODEL
public class Claim {
[DisplayName("$ Amount")]
[DataType(DataType.Currency)]
[Required]
[Range(0.0, 200000.0)]
public decimal? DollarAmount { get; set; }
}
// View
#Html.HiddenFor(model => model.DollarAmount, new { #id = "DollarAmount" })
#Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9 input-group">
<span class="input-group-addon">$</span>
<input id="DollarSave" type="text" name="DollarSave" pattern="^\$?([0-9]{1,3},([0-9]{3},)*[0-9]{3}|[0-9]+)(.[0-9][0-9])?$" title="You must enter in proper currency">
#Html.ValidationMessageFor(model => model.DollarAmount, "", new { #class = "text-danger" })
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
$('#DollarSave').change(function(){
var sourceField = $("#DollarSave").val(); //source field key
$("#DollarAmount").val(sourceField); //destination field key
$("#DollarAmount").change(); //destination field key
});
});
</script>
Pool pro's answer was a great help in solving my problem but I couldn't get his input tag pattern to display a message. It worked in JSFiddles, but not in my Asp.Net view template. So, I did the pattern validation and message update in javascript. I also used a different regex. For completeness, I'm posting my solution here:
#Html.HiddenFor(model => model.DollarAmount, new { #id = "DollarAmount" })
#Html.LabelFor(model => model.DollarAmount, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9">
<input id="DollarSave" type="text" name="DollarSave" class="form-control text-box single-line">
<p id="BadDollarSave" class="text-danger"></p>
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
$('#DollarSave').on('blur', function () {
validateDollarSave();
});
function validateMoney(inputId) {
var errorMsg = '';
var currency = $('#DollarSave').val();
var good = currency.match(/^(\$|\$ )?[0-9]{1,3}(?:(,[0-9]{3})*|([0-9]{3})*)(?:(\.|\.[0-9]{2}))?$/);
if (!good) {
errorMsg = "$ Amount must be US currency";
} else {
var num = currency.replace(/[, $]/g, "");
$('#DollarAmount').val(num);
}
document.getElementById('BadDollarSave').innerHTML = errorMsg;
};
});
</script>

MVC project: Convert user input date mmddyyyy to yyyy/mm/dd

I have a textbox in a MVC project that prompts a user to enter a date as mmddyyyy. I have the code set up so that the user can only input numbers (ie, no "/"s or "-"s). I need to then convert this data to yyyy-mm-dd to ensure that correct data is being added to the database once the form is submitted.
I realize I will probably need to use DateTime.Parse to do this, but I can't for the life of me figure out how to add it to the following code:
<div class="form-group">
#Html.LabelFor(model => model.Buy2IDExpireDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.Buy2IDExpireDate, new { id = "coBuyerIDExpireDate", #class = "form-control" })
#Html.ValidationMessageFor(model => model.Buy2IDExpireDate, "", new { #class = "text-danger" })
</div>
</div>
Would it look something like this?
string str = Date.Parse(Buy2IDExpireDate).ToString("yyyy-MM-dd");
If so where do I put it in the above code, and do I need to write extra code to ensure that the newly formatted date is stored by the database?
You can add value attribute like this:
#Html.TextBoxFor(model => model.Buy2IDExpireDate,
new { #Value = Model.Buy2IDExpireDate.ToString("yyyy-MM-dd") })

How do you make a HTML.EditorFor textbox exist on multiple lines?

I have a text area where users have to write a description. I was wondering how to set a text box so that it is on multiple lines, allowing the user to see what they are writing. What I am looking for is similar to the environment that I am writing this question in.
<div class="form-group">
<div class="col-md-10">
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
In your model you need to add MultilineText as below:
[DataType(DataType.MultilineText)]
public string Title { get; set; }
Or you code have just changed the EditorFor to TextAreaFor like Below
#Html.TextAreaFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })

Using Data annotation in Model for DateTime

I am using following code to popup calendar for date in my razor view
Model
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
[DataType(DataType.Date)]
public Nullable<System.DateTime> EndTime { get; set; }
View
<div class="form-group">
#Html.LabelFor(model => model.EndTime, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.EditorFor(model => model.EndTime, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EndTime, "", new { #class = "text-danger" })
</div>
</div>
Now I want to use DateTime instead of Date.What should be the DataFormat String?
My Try
Display(Name = "End Date Time")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}{1:HH/mm}")]
[DataType(DataType.DateTime)]
I am getting format exception?
Your EditorFor() method renders an input with type="date" because of the [DataType(DataType.Date)] attribute, which will generate the browsers HTML-5 datepicker (but this is only supported in Chrome and Edge).
To generate a HTML-5 datetimepicker, you need to render an input with type = "datetime-local" but there is no data annotation attribute for that. Instead you need to generate the type attribute yourself.
#Html.TextBoxFor(m => m.EndTime, "{0:s}", new { #type = "datetime-local", #class = "form-control" })
Note "{0:s}" is shortcut for "{0:yyyy-MM-ddTHH:mm:ss}" and will display the date and time in the browsers culture. Note also that you do not need your [DataType] attribute or the ApplyFormatInEditMode = true property in the [DisplayFormat] attribute since they apply only to EditorFor()

Editing input field when Html.ValidationMessageFor outputs error message

I'm using C#/.NET in Visual Studio and the MVC framework.
I have a form that I'm working with, and I was able to get it to output the correct error message at the appropriate time. My issue is that the input field of the form is supposed to highlight red with a has-error class when the field is either not filled in or filled in incorrectly. I could do this if I was using regular form tags, but because this is connected to an Umbraco project, I have to use Html.EditorFor and Html.ValidationMessageFor.
Is there a way (either using jQuery or modifying the existing code) to add a class to the Html.EditorFor field upon Html.ValidationMessageFor deciding it should display the message?
Here is a portion of my View:
<div class="name-field">
<label>Name</label>
#Html.EditorFor(m => m.Name, new { htmlAttributes = new { #class = "form-control", #id = "contact_name", #name = "contact_name", #placeholder = "Name" } })
#if (#Html.ValidationMessageFor(model => model.Name) != null)
{
#Html.ValidationMessageFor(model => model.Name, null, new { #class = "contact-form-error-msg text-danger small-sized", #id = "contact-form-name-error-1", #style = "display:block;" })
}
</div>
and here is the attribute in my Model:
[Required(ErrorMessage = "Please enter a contact name.")]
public string Name { get; set; }
Like I said, the error message shown in the model is showing up correctly. My issue is just applying the has-error class to the Html.EditorFor field which I have a feeling is going to require jQuery; however, I'm not sure how to access the existing code in a jQuery block.
Thank you.
Edit: I was notified that my question could be a possible duplicate of the question here (How can I check if my model is valid from inside the razor view?). With some modification I was able to find the solution to my problem.
#if (!ViewData.ModelState.IsValidField("Name")) {
<div class="name-field has-error">
#Html.EditorFor(m => m.Name, new { htmlAttributes = new { #class = "form-control", #id = "contact_name", #name = "contact_name", #placeholder = "Name" } })
#if (#Html.ValidationMessageFor(model => model.Name) != null)
{
#Html.ValidationMessageFor(model => model.Name, null, new { #class = "contact-form-error-msg text-danger small-sized", #id = "contact-form-name-error-1", #style = "display:block;" })
}
</div>
} else {
<div class="name-field">
#Html.EditorFor(m => m.Name, new { htmlAttributes = new { #class = "form-control", #id = "contact_name", #name = "contact_name", #placeholder = "Name" } })
</div>
}

Categories