LastBye
LastBye

Reputation: 1173

Nullable Enum helper for having a default value

I recently made an extension for binding a dropdownlist to a model, Unfortunately I couldn't make the -wanna be default- "please select..." be selected as default Always the dropdown's index is 1 and it selects the Enum's 1st item as the default item. I made the extension based on this -Darin's great answer-

I get advised to use nullable enum, I couldn't make it work yet, hope get a help on it

The specification of the default selection text in the helper:

return htmlHelper.DropDownListFor(expression, items, "Please select ...");

How to make the "please select..." selected as default in any dropdowns.

In the ViewModel I used:

public TimePlan? TimeList { get; set; }

Upvotes: 1

Views: 2857

Answers (1)

ataravati
ataravati

Reputation: 9155

You are doing it wrong. It's not the TimeList that should be nullable, but the TimePlan property that is supposed to store the selected item. Here is what you should have in your View Model:

public TimePlan? TheTimePlan { get; set; }

public IEnumerable<SelectListItem> TimeList
{
    get
    {
        var enumType = typeof(TimePlan);
        var values = Enum.GetValues(enumType).Cast<TimePlan>();

        return
            from value in values
            select new SelectListItem
            {
                Text = Enum.GetName(typeof(TimePlan), value),
                Value = value.ToString(),
            };
    }
}

Then, in your View, you'll have:

@Html.DropDownListFor(model => model.TheTimePlan, Model.TimeList, "Please select...")

UPDATE:

If you want to create a custom html helper you can do it like this:

public static IHtmlString DropDownListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, 
    Expression<Func<TModel, TEnum>> expression, string optionLabel)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    var enumType = GetNonNullableModelType(metadata);
    var values = Enum.GetValues(enumType).Cast<TEnum>();            

    var items =
        from value in values
        select new SelectListItem
        {
            Text = Enum.GetName(enumType, value),
            Value = value.ToString(),
            Selected = value.Equals(metadata.Model)
        };

    return htmlHelper.DropDownListFor(expression, items, optionLabel);
}

private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
    Type modelType = modelMetadata.ModelType;

    Type underlyingType = Nullable.GetUnderlyingType(modelType);
    if (underlyingType != null)
    {
        modelType = underlyingType;
    }
    return modelType;
}

Then, in your View, you'll have:

@Html.DropDownListForEnum(model => model.TheTimePlan, "Please select...")

Upvotes: 3

Related Questions