dropdownlist-mvc

I find the Html helper APIs for ASP.NET MVC ackward and confusing. That’s why I like creating these little examples to figure out what is going on.

Here is a simple example of how to create a drop down list in ASP.NET MVC using Html.DropDownListFor.

You can do it like this all inlined in your *.cshtml file like so:

@Html.DropDownListFor(model => model.Package.State, new SelectList(
                  new List<Object>{ 
                       new { value = 0 , text = "Red"  },
                       new { value = 1 , text = "Blue" },
                       new { value = 2 , text = "Green"}
                    },
                  "value",
                  "text",
                   2))

With produces this:

<select id="Package_State" name="Package.State"><option value="0">Red</option>
<option value="1">Blue</option>
<option value="2">Green</option>
</select>

The model => model.Package.State expression is used to generate the id and name on the select.

The string value and text matter as they need to match the model attributes of the listItem in the list.

Or you can create your own List collection (with different fields for value and text) in your controller, set it on you model, and then use in your view like this:

    @Html.DropDownListFor(model => model.Package.State.Id, new SelectList(
                  Model.PackageStates,
                  "id",
                  "name",
                  Model.Package.State.Id))

Longer version

Here is a more indepth example with break down using modesl, view and controller.

Model

I basically have x3 models.

PackageState – contains the state of my package (fake domain object I made up).
Package – contains the PackageState and whatever else I want to throw in there.
DashboardIndexModel – this is how I bundle everything in the controller to send to the view.

PackageState.cs

    [Serializable]
    public class PackageState
    {
        private PackageState(int id, string name)
        {
            this.Id = id;
            this.Name = name;
        }

        public int Id { get; set; }
        public string Name { get; set; }

        public static PackageState Received = new PackageState(1, "Received");
        public static PackageState Processing = new PackageState(2, "Processing");
        public static PackageState Complete = new PackageState(3, "Complete");
    }

Package.cs

    public class Package
    {
        public PackageState State { get; set; }

        public Package(PackageState state)
        {
            State = state;
        }
    }

DashboardIndexModel.cs

    public class DashboardIndexModel
    {
        public Package Package { get; set; }
        public IEnumerable<SelectListItem> PackageStates { get; set; } // dropdown
    }

Controller

Here is where I prepare my dropdown list. I could do the work in the view (like the short example above). But here I have chosen to do it in the controller to keep the view clean and because I want to be able to set which element in my drop down should be selected.

    public class DashboardController : Controller
    {
        //
        // GET: /Dashboard/

        public ActionResult Index()
        {
            PackageRepository.Package = new Package(PackageState.Complete);
            IList<PackageState> states = new List<PackageState>
                                             {PackageState.Received, PackageState.Processing, PackageState.Complete};

            int selectedStateId = 2; // hard code for demo

            IEnumerable<SelectListItem> selectList =
                from s in states
                select new SelectListItem
                           {
                               Selected = (s.Id == selectedStateId),
                               Text = s.Name,
                               Value = s.Id.ToString()
                           };

            // Do this if you don't care about selection
//            List<SelectListItem> selectList = states.Select(state => new SelectListItem {Value = state.Id.ToString(), Text = state.Name}).ToList();

            var model = new DashboardIndexModel { Package = PackageRepository.Package, PackageStates = selectList };
            return View(model);
        }
    }

View

And here is the view showing x2 ways to create the dropdown list.

Index.cshtml

@model Dashboard.Models.DashboardIndexModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<fieldset>
    <legend>Package</legend>

    <div class="display-field">
        @Html.DisplayFor(model => model.Package.State.Name)
    </div>
    
    @Html.DropDownListFor(model => model.Package.State.Id, new SelectList(
                  new List<Object>{ 
                       new { value = 0 , text = "Red"  },
                       new { value = 1 , text = "Blue" },
                       new { value = 2 , text = "Green"}
                    },
                  "value",
                  "text",
                   2))
    
    
    
    @Html.DropDownListFor(model => model.Package.State.Id, Model.PackageStates)
    
</fieldset>

So that’s it. A simple of a dropdown. Don’t worry if you find these helpers confusing at first (I know I did at first too). But creating little experiments like this, and viewing the HTML output helps the understanding.

Links that help

http://stackoverflow.com/questions/5554421/dropdownlist-selectlist-selectedvalue-issue
http://stackoverflow.com/questions/3057873/how-to-write-a-simple-html-dropdownlistfor
http://stackoverflow.com/questions/781987/how-can-i-get-this-asp-net-mvc-selectlist-to-work