Adam Cox
Adam Cox

Reputation: 3661

How to show prompt as the default text in EnumDropDownList when Enum is nullable?

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:

enter image description here

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

Answers (2)

Chris Pratt
Chris Pratt

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

Rafet
Rafet

Reputation: 926

Have you tried adding the [Required] attribute to the ProcessingFrequency property?

Upvotes: 1

Related Questions