Multi select drop down list for enum

Viewed 4761

Which way I can implement dropdown list for enum values?

I have a enum like this:

public enum ValueEnum : byte
{
    [Description("Value 1")]
    Value1 = 1,
    [Description("Value 2")]
    Value2 = 2,
    [Description("Value 3")]
    Value3 = 4
}

and I want to get single value from multiple select on server side instead of list of selected values:

    public ActionResult ValueAction(ValueEnum result)
    {
        //too many code
        return View();
    }

where result can be ValueEnum.Value1 or ValueEnum.Value1 | ValueEnum.Value3

Is there a way to do it without client side sum?

2 Answers

I solved it on the client side with the following behaviour:

Get method:

[HttpGet]
public ActionResult ValueAction(ValueEnum result)
{
    //irrelevant code
    ViewBag.Values = Enum.GetValues(typeof(ValueEnum))
                    .OfType<ValueEnum>()
                    .Select(x => new SelectListItem 
                        { 
                            Text = x.GetCustomAttribute<DescriptionAttribute>().Description,
                            Value = ((byte)x).ToString()
                        });
    return View();
}

Razor:

@using(Html.BeginForm())
{   
    @*irrelevant code*@

    @Html.DropDownList("valueEnum", (IEnumerable<SelectListItem>)ViewBag.Values, new { multiple="multiple", id="enumValues" })
    @*Here would be stored result value for this flagged enum*@
    <input type='hidden' name='resultValue' id='hidden-enum-value' />

    @*irrelevant code*@
    <input type="submit" value="Submit" />
}

JS:

$(function() {
    $('form').submit(function() {
        var vals = $('#enumValues').val();
        var result = 0;

        for(let i = 0; i < vals.length; i++) {
            result += Number(vals[i]);
        }

        $('#hidden-enum-value').val(result);
    });
});

Post method:

[HttpPost]
public ActionResult ValueAction(ValueEnum resultValue)
{
    //irrelevant code
    return View();
}

You create a List out of your Enum like this thread suggests or this one and make a new SelectList with it and keep it in a ViewBag, then in your View make a DropDownList or DropDownListFor helper and use the same name for both the ViewBag variable as for the select element.

//GET: ~/ValueController/ValueAction
public ActionResult ValueAction() {
    Array values = Enum.GetValues(typeof(ValueEnum));
    List<ListItem> items = new List<ListItem>(values.Length);

    foreach(var i in values)
    {
        items.Add(new ListItem
        {
            Text = Enum.GetName(typeof(ValueEnum), i),
            Value = ((int)i).ToString()
        });
    }

    ViewBag.valueEnum = new SelectList(items);
}

View:

@Html.DropDownList("valueEnum", null, htmlAttributes: new { @class = "form-control" })

MVC will then automatically assign the ViewBag contents to the select element.

Then in your Post Action you set its parameters to receive a simple integer.

//POST: ~/ValueController/ValueAction
[HttpPost]
public ActionResult ValueAction(int valueEnum) {
    //less code
    return View();
}
Related