8

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?

Mikhail Tulubaev
  • 4,141
  • 19
  • 31
  • If your using MVC-5.1+, then you can use the `@Html.EnumDropDownListFor()` helper, other wise refer [these answers](http://stackoverflow.com/questions/388483/how-do-you-create-a-dropdownlist-from-an-enum-in-asp-net-mvc) for an example. –  Mar 04 '16 at 11:31
  • 1
    @StephenMuecke answers for this question mean dropdownlist with single selectable value and single return value. In my question I mean that I want to get multiselect dropdown list with single return value. – Mikhail Tulubaev Mar 04 '16 at 11:37
  • It was just the example of how to implement it I was referring to :) But you would probably be better off using a checkboxlist for this implementation anyway. –  Mar 04 '16 at 11:51
  • @MikhailNeofitov you probably meant you want to select multiple values and return an array or list of values. So, like Stephen Muecke said, you should either use checkboxes with the same name parameter instead or a javascript plugin like [Select 2](https://select2.org/) if you really want to keep the dropdown element. – Tiramonium Oct 02 '17 at 13:03
  • @Tiramonium No, I meant multiselect for flagged enum. I've already solved it by passing a sum of all selected values, but still interested at more universal solution – Mikhail Tulubaev Oct 03 '17 at 03:47
  • @MikhailNeofitov what is a little unclear in your question is if you want a single value from a single selected option, or multiple values from multiple selected options. Selecting multiple options and returning just one value makes no sense. That's why I thought you meant an array or List. – Tiramonium Oct 03 '17 at 11:13
  • @Tiramonium I want a single value from multiple selected options. It makes sense for flagged enum. Expected behaviour is in the question. – Mikhail Tulubaev Oct 04 '17 at 04:54

2 Answers2

1

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();
}
Mikhail Tulubaev
  • 4,141
  • 19
  • 31
  • Well, if you had explained properly in your question you actually wanted a sum of values, I would have given you the answer you were after. – Tiramonium Oct 05 '17 at 11:20
  • 1
    @Tiramonium Well, I don't want a sum of values, I I've searched for built-in or common solution of multiselect dropdown for flagged enum! A sum of values is a simple workaround for it. In my opinion expected behaviour in my question properly explains what exactly should be. – Mikhail Tulubaev Oct 05 '17 at 16:12
0

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();
}
Tiramonium
  • 557
  • 5
  • 15