Reputation: 3661
For example, when enum is...
public enum TaskFrequency
{
Weekly,
[Display(Name = "Bi-weekly")]
Biweekly,
Monthly,
Quarterly
}
Used in ViewModel, like...
[Display(Name = "Processing frequency", Prompt = "Select frequency")]
public Enums.TaskFrequency? ProcessingFrequency { get; set; }
Implement like (in custom editor Enum.cshtml)...
@Html.EnumDropDownListFor(model => model,
optionLabel: ViewData.ModelMetadata.Watermark)
Expected behaviour:
Expected behavior: Show the prompt if value is null (declaration nullable), and also show this in the list. If non-nullable (required), then show the prompt, but do not include in select list items. Expected that in case of non-nullable, that validation should be required to be sure there is no null going back to the server for update to the model.
See this fiddler for desired behaviour. What is actually happening is either blank item in list when nullable and no placeholder being used, or the optionLabel becomes another list item and is not used as any placeholder.
EDIT / SOLULTION:
It appears like the EnumDropDownListFor helper is less helpful than it could be. What I have settled on as a solution is to use enum with first (0 based) item as the "Unselected" item with [Display(Name="Select item")] decorator, and then declare in the ViewModel class enum type as required (omitting the '?' on type name) and then defaulting the data values in table with '0'.
For example...
Enum:
public enum TaskFrequency
{
[Display(Name = "Select frequency")]
Unselected,
Weekly,
[Display(Name = "Bi-weekly")]
Biweekly,
Monthly,
Quarterly
}
ViewModel class declaration ('?' and Prompt removed):
[Display(Name = "Processing frequency"]
public Enums.TaskFrequency ProcessingFrequency { get; set; }
And remove the optionLabel from custom editor Enum.cshtml, leaving:
@Html.EnumDropDownListFor(model => model)
Using customer editor (above), can use in View like:
@Html.EditorFor(model => model.Frequency)
I'm open to any better ideas?
Upvotes: 1
Views: 436
Reputation: 239270
Selects don't support a placeholder or descriptive value. What MVC does is add an additional option to the select list in the form of:
<option value="">Select frequency</option>
This is a valid option like any other, though, so there's nothing inherently available to stop a user from choosing it. This is where validation comes in. If the posted value is null or empty, meaning the user either chose Select frequency
explicitly or left it at the default state of selected, then, it's treated as a null value. If your property is non-nullable, or nullable but required (via the [Required]
attribute), then an error will be added to the model state.
Upvotes: 0
Reputation: 926
Have you tried adding the [Required]
attribute to the ProcessingFrequency property?
Upvotes: 1