when i use .ToShortTimeString()....templates can only be used? - c#

#Html.TextBoxFor(x => x.ActiveDevice.LastUseDate, new { #readonly = "readonly" })
Displays my date textbox as read only, which is fine, however it shows both date and time. I only want date so iv used .ToShortTimeString() with:
#Html.TextBoxFor(x => x.ActiveDevice.LastUseDate.ToShortTimeString(), new { #readonly = "readonly" })
and I get the error:
Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
Anyone know how to resolve this?
Thanks

You can insert formatted date with HtmlAttributes:
#Html.TextBoxFor(x => x.ActiveDevice.LastUseDate, new { #readonly = "readonly", #Value = Model.ActiveDevice.LastUseDate.ToShortTimeString() })

This happens because TextBoxFor (as well as other template extensions) needs an expression that refers to a model property, so that the model binder could serialize the data:
Need to verify the expression is valid; it needs to at least end in
something that we can convert to a meaningful string for model
binding purposes
(Check out the relevant code in ModelMetadata.FromLambdaExpression)
There are several ways to solve this, one is adding DisplayFormat attribute to your model:
[DataType(DataType.Date)] //try this as well? maybe Orchard intervenes into rendering...
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime LastUseDate { get; set; }
And then you use the property as usual is the view:
#Html.TextBoxFor(x => x.ActiveDevice.LastUseDate, new { #readonly = "readonly" })

Thanks to help from andreister I was able to solve the problem. Changing it to a 'textBox', removing the lamba, ad adding in the name of the textbox in quotes:
#Html.TextBox("LastUseDate", Model.ActiveDevice.LastUseDate.ToShortDateString(), new { #readonly = "readonly" })

Related

Nullable Datetime in .NET CORE MVC

I have a view which is used for "Create" and "Update" a database model. The database model has a property which is a DateTime? (nullable). Now I am trying to use this nullable datetime in an ASP.NET Core MVC view which looks like the following:
#Html.TextBoxFor(model => model.MyNullableDate,"{0:dd.MM.yyyy}", new { placeholder = "dd.MM.yyyy", #class = "form-control form-control-sm", type = "date" })
This works very well for the "Create" process. If a date is set, it is written correctly into the database. But now I want to update the already existing database value model.MyNullableDate.
I read the value from the database and pass the value again to the view. The property MyNullableDate is set correctly and I saw in the debugger that the correct date is written into it.
But in the view, nothing is shown... it's only an empty textbox without the passed in value of MyNullableDate.
The property looks like this:
[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}")]
[DataType(DataType.Date)]
public DateTime? MyNullableDate{ get; set; }
What am I doing wrong? How can I show the value of MyNullableDate in the TextBoxFor?
This is related to the date format rather than the nullability.
See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date
The displayed date format will differ from the actual value — the
displayed date is formatted based on the locale of the user's browser,
but the parsed value is always formatted yyyy-mm-dd.
When I passed the format as below, the date displayed :)
#Html.TextBoxFor(
expression: model => model.MyNullableDate,
format: "{0:yyyy-MM-dd}",
htmlAttributes: new
{
placeholder = "dd.MM.yyyy",
#class = "form-control form-control-sm",
type = "date"
})

Why storing the date like dd-MMM-yyyy is getting converted to dd-MM-yyyy?

I have a very different kind of problem.
I have deployed my mvc application to live server.
It has date time format like this '01/07/2019'.
I have a textbox which is populated from jquery datetimepicker. It populates like this 27/Jul/2019 but in sql table it stores like 2019-07-17 00:00:00.000
and after binding the data from database to textboxfor, it appears like this 27-07-2019.
And upon saving it throws error for all the dates that are greater than 12 as a day e.g. 13/07/2019 but for 13/Jul/2019 it works good.
how to tackle this?
#Html.EditorFor(model => model.InspectionReport.InspectionDate, new { htmlAttributes = new { #class = "form-control input-sm pull-right text-box single-line" } })
jquery:
$("#InspectionReport_InspectionDate").datepicker({ dateFormat: 'dd/M/yy' });
class:
[Required]
[Display(Name = "Inspection Date")]
[DisplayFormat(DataFormatString = "{0: dd-MMM-yyyy}")]
public DateTime InspectionDate { get; set; }
In a date field of data type DateTime(2), a date value is stored as a value with no format.
Thus, to display the value, apply the format you wish, or a default format will be applied.
Try this,
#Html.TextBoxFor(model => model.InspectionReport.InspectionDate, "{0:dd-MMM-yyyy}", htmlAttributes: new { #type="date" })

Change class of #Html.EditorFor / customize template | ASP .NET MVC 4

I want to change the class/style of my #Html.EditorFor field. I read something about customizing the template, but there is no template folder in my porject (Views/Shared/ONLY_FILES_HERE). Sadly I am NOT working with MVC 5.1.
Also I DON'T want to use TextBoxFor, because of inputvalidation.
How can I achieve this?
Here is a snippet of my model:
public class CreateTableColumnModels
{
[RegularExpression(#"^[A-Za-z0-9]+$", ErrorMessage = "Use letters and numbers only please")]
[Display(Name = "Name")]
public string Name { get; set; }
I tried this:
#model QlikViewStammdaten.Models.CreateTableColumnModels
<div>
#Html.EditorFor(x => Model.Name, new { #class = "form-control" })
</div>
As already mentioned in the comments, it is better to add a class to Html.TextBoxFor and NOT #Html.EditorFor. Why? because #Html.EditorFor renders a template and that template could contain multiple controls (now to which one of those controls do you want to add the class?)... see Adding a class to EditorFor
If you want numeric type, then add #type = "number"
#Html.TextBoxFor(m => m.Name, new { #class = "form-control", #type = "number" })
Note: it is not x => Model.Name but m => m.Name
I am sure you already know this, but [Display(Name = "Name")] is redundant in your model, as the default display name is the variable name itself.

Dynamically Modify value of #Html.HtmlHelper

I am trying to modify a behavior for DataAttributes (Maxlength[int] or StringLength[int]), where it would add a "maxlength" attribute inside (textarea) tag along with its "int" value. I have already performed some research, and the closest answers I obtained were this post and that question.
However, I hope to go one step further.
I already know that StringLength adds "data-val-length-max" and "data-val-length" attributes to the tag.
I spent a lot of time trying to implement solution in JavaScript unobtrusive validation file by using logic
if tag has data-val-length-max attribute
add maxlength attribute to this tag
assign its value equal to data-val-length-max value
However, in my project, Javascript files are constantly loaded/unloaded and it is extremely time-consuming to keep track of the logic flow, so I decided to change the approach, and try to implement it within C#.
Inside my .cshtml file, there are lines like following:
#Html.myLabelFor(model => model.Project.ProjectDescription, new { #title = "Enter a description for this project" })
#Html.TextAreaFor(model => model.Project.ProjectDescription, new { #class = "textfield_Paragraph", #id = "ProjectDescription" })
#Html.ValidationMessageFor(model => model.Project.ProjectDescription)
I learned that it successfully adds maxvalue if it adds #maxlength at the end:
#Html.TextAreaFor(model => model.Project.ProjectDescription, new { #class = "textfield_Paragraph", #id = "ProjectDescription", #maxlength = 50 })
However, I do not want to manually add #maxlenght this line to every TextAreaFor line in solution; I want to turn it into reusable code, that would dynamically perform such action to every variable within TextAreaFor inside the .cs file, which are marked like following:
[MaxLength(50)]
[Display(Name = "Project Description")]
public string ProjectDescription { get; set; }
So I am thinking of implementing it by using the logic
if metadata has a MaxLength flag
htmlAttributes += " ', #maxlength = ' + maxLengthValue"
So, physically it will still be
#Html.TextAreaFor(model => model.Project.ProjectDescription, new { #class = "textfield_Paragraph", #id = "ProjectDescription" })
while the final value that will be loaded will be
#Html.TextAreaFor(model => model.Project.ProjectDescription, new { #class = "textfield_Paragraph", #id = "ProjectDescription", #maxlength = 50 })
I want to know if something like this is even possible to implement, so I know beforehand if I should continue thinking in that direction.
Again, links I have posted above were the closest answers I could get, so I am curious if it is as far as I can get, or there is even more room to improve. My huge preference would be NOT touching .js files unless I absolutely HAVE to.

ASP.Net MVC custom datatype passing additional values

I have created the custom "DataType" annotation to use on the model object to tell this is the date field on the view. ([DataType("Date")]) If I use #Html.EditorFor(model => model.DateCreated), it will act as a date field and pup up the JavaScript date picker. This is the template I am using under EditorTemplates
#inherits System.Web.Mvc.WebViewPage<DateTime>
<div class="input-append date" data-date="12-02-2012">
<input type="text" class="span2">
</div>
View -
<div class="control-group">
#Html.LabelFor(model => model.DateCreated, new { #class = "control-label" })
<div class="controls" id="date-container">
#Html.EditorFor(model => model.DateCreated, new { #class="input-append date"})
#Html.ValidationMessageFor(model => model.DateCreated, null, new { #class = "help-inline" })
</div>
</div>
Model -
[Display(Name = "Date Created")]
[DataType("Date")]
public DateTime DateCreated { get; set; }
Controller -
public ActionResult Create(int id)
{
// Attempt to get new customer object
GetPaymentResponse paymentResponse = _BillingService.GetPayment(id);
// Check whether response was successful
if (paymentResponse.State == BaseResponseState.Valid)
{
paymentResponse.Payment.Type.AvailableOptions = paymentResponse.Payment.Type.AvailableOptions.Where(x => x.Value != "BalancingTransaction").ToList();
ViewData.Model = paymentResponse.Payment;
return View();
}
}
I need to pass some additional value to my view via datatype from the model.
E.g. [DataType("Date"), Format("dd/mm/yy"), StartDate("12-02-2012")]
Could you please let me know how can I grab these additional value from the template? (I am new to ASP.Net MVC and I am using MVC 3)
Thanks
If you specify extra information using attributes, the information must be constant for all the instances of the class in which you define the member. I.e. the StartDate will be the same for all instances of your model, becasue the start date specified in the attribute must be a constant.
If that serves your purpoes, you can use a custom metadata provider to get specific metadata in your model from your custom attributes.
If you need to pass different data fro each case, you have to use any of the overloads of EditorFor which allows to pass extra view data. Then you can read that extra information from the ViewData in your template.
Be warned that there are some caveats in the metadata providers and custom template implementations, and registration. Take into account if your type can be made nullable, like DateTime?
If you use the Model Binding it should take the value properly I believe.
In your view, set the model on the first line, line this:
#model MyViewModel
and then in your controller, instead of passing the Model through the ViewData, do something like this:
var model = new MyViewModel();
// do stuff with your model here
return View(model);
Assuming that StartDate is a property of Payment
<div class="control-group">
#Html.LabelFor(model => model.StartDate, new { #class = "control-label" })
<div class="controls" id="date-container">
#Html.EditorFor(model => model.StartDate, new { #class="input-append date"})
#Html.ValidationMessageFor(model => model.StartDate, null, new { #class = "help-inline" })
</div>
</div>

Categories