Using the DropDownList Helper with ASP.NET MVC

by Rick Anderson

This tutorial will teach you the basics of working with the DropDownList helper and the ListBox helper in an ASP.NET MVC Web application. You can use Microsoft Visual Web Developer 2010 Express Service Pack 1, which is a free version of Microsoft Visual Studio to follow the tutorial. Before you start, make sure you've installed the prerequisites listed below. You can install all of them by clicking the following link: Web Platform Installer. Alternatively, you can individually install the prerequisites using the following links:

If you're using Visual Studio 2010 instead of Visual Web Developer 2010, install the prerequisites by clicking the following link: Visual Studio 2010 prerequisites. This tutorial assumes you have completed the Intro to ASP.NET MVC tutorial or theASP.NET MVC Music Store tutorial or you are familiar with ASP.NET MVC development. This tutorial starts with a modified project from the ASP.NET MVC Music Store tutorial.

A Visual Web Developer project with the completed tutorial C# source code is available to accompany this topic. Download.

What You'll Build

You'll create action methods and views that use the DropDownList helper to select a category. You will also use jQuery to add an insert category dialog that can be used when a new category (such as genre or artist) is needed. Below is a screenshot of the Create view showing links to add a new genre and add a new artist.

Image using drop down list helper

Skills You'll Learn

Here's what you'll learn:

  • How to use the DropDownList helper to select category data.
  • How to add a jQuery dialog to add new categories.

Getting Started

Start by downloading the starter project with the following link, Download. In Windows Explorer, right click on the DDL_Starter.zip file and select properties. In the DDL_Starter.zip Properties dialog box, select Unblock.

Image of properties dialog box select unblock

Right click the DDL_Starter.zip file and select Extract All to unzip the file. Open the StartMusicStore.sln file with Visual Web Developer 2010 Express ("Visual Web Developer" or "VWD" for short) or Visual Studio 2010.

Press CTRL+F5 to run the application and click the Test link.

Image of application test link

Select the Select Movie Category (Simple) link. A Movie Type Select list is displayed, with Comedy the selected value.

Image of movie type select list

Right click in the browser and select view source. The HTML for the page is displayed. The code below shows the HTML for the select element.

<form action="/Home/CategoryChosen" method="get">

<fieldset>Movie Type <select id="MovieType" name="MovieType">

<option value=""></option>

<option value="0">Action</option>

<option value="1">Drama</option>

<option selected="selected" value="2">Comedy</option>

<option value="3">Science Fiction</option>

</select>

<p><input type="submit" value="Submit" /> </p>

</fieldset>

</form>

You can see that each item in the select list has a value (0 for Action, 1 for Drama, 2 for Comedy and 3 for Science Fiction) and a display name (Action, Drama, Comedy and Science Fiction). The code above is standard HTML for a select list.

Change the select list to Drama and hit the Submit button. The URL in the browser is http://localhost:2468/Home/CategoryChosen?MovieType=1 and the page displays You Selected: 1.

Image of U R L in browser

Open the Controllers\HomeController.cs file and examine the SelectCategory method.

public ActionResult SelectCategory() {

     List<SelectListItem> items = new List<SelectListItem>();

     items.Add(new SelectListItem { Text = "Action", Value = "0"});

     items.Add(new SelectListItem { Text = "Drama", Value = "1" });

     items.Add(new SelectListItem { Text = "Comedy", Value = "2", Selected = true });

     items.Add(new SelectListItem { Text = "Science Fiction", Value = "3" });

     ViewBag.MovieType = items;

     return View();

 }

The DropDownList helper used to create an HTML select list requires a IEnumerable<SelectListItem >, either explicitly or implicitly. That is, you can pass the IEnumerable<SelectListItem > explicitly to the DropDownList helper or you can add the IEnumerable<SelectListItem > to the ViewBag using the same name for the SelectListItem as the model property. Passing in the SelectListItem implicitly and explicitly is covered in the next part of the tutorial. The code above shows the simplest possible way to create an IEnumerable<SelectListItem > and populate it with text and values. Note the ComedySelectListItem has the Selected property set to true; this will cause the rendered select list to show Comedy as the selected item in the list.

The IEnumerable<SelectListItem > created above is added to the ViewBag with the name MovieType. This is how we pass the IEnumerable<SelectListItem > implicitly to the DropDownList helper shown below.

Open the Views\Home\SelectCategory.cshtml file and examine the markup.

@{

    ViewBag.Title = "Category Select";

    Layout = "~/Views/Shared/_Simple_Layout.cshtml";

}

@using (Html.BeginForm("CategoryChosen", "Home", FormMethod.Get)) {

    <fieldset>

            Movie Type

            @Html.DropDownList("MovieType")

        <p>

            <input type="submit" value="Submit" />

        </p>

    </fieldset>

}

On the third line, we set the layout to Views/Shared/_Simple_Layout.cshtml, which is a simplified version of the standard layout file. We do this to keep the display and rendered HTML simple.

In this sample we are not changing the state of the application, so we will submit the data using an HTTP GET, not HTTP POST. See the W3C section Quick Checklist for Choosing HTTP GET or POST. Because we are not changing the application and posting the form, we use the Html.BeginForm overload that allows us to specify the action method, controller and form method (HTTP POST or HTTP GET). Typically views contain the Html.BeginForm overload that takes no parameters. The no parameter version defaults to posting the form data to the POST version of the same action method and controller.

The following line

@Html.DropDownList("MovieType")

passes a string argument to the DropDownList helper. This string, "MovieType" in our example, does two things:

  • It provides the key for the DropDownList helper to find a IEnumerable<SelectListItem > in the ViewBag.
  • It is data-bound to the MovieType form element. If the submit method is HTTP GET, MovieType will be a query string. If the submit method is HTTP POST, MovieType will be added in the message body. The following image shows the query string with the value of 1.

Image of query string with value of 1

The following code shows the CategoryChosen method the form was submitted to.

public ViewResult CategoryChosen(string MovieType) {

    ViewBag.messageString = MovieType;

    return View("Information");

}

Navigate back to the test page and select the HTML SelectList link. The HTML page renders a select element similar to the simple ASP.NET MVC test page. Right click the browser window and select view source. The HTML markup for the select list is essentially identical. Test the HTML page, it works like the ASP.NET MVC action method and view we previously tested.

Improving the Movie Select List with Enums

If the categories in your application are fixed and will not change, you can take advantage of enums to make your code more robust and simpler to extend. When you add a new category, the correct category value is generated. The avoids copy and paste errors when you add a new category but forget to update the category value.

Open the Controllers\HomeController.cs file and examine the following code:

public enum eMovieCategories { Action, Drama, Comedy, Science_Fiction };

private void SetViewBagMovieType(eMovieCategories selectedMovie) {

    IEnumerable<eMovieCategories> values = 

                      Enum.GetValues(typeof(eMovieCategories))

                      .Cast<eMovieCategories>();

    IEnumerable<SelectListItem> items =

        from value in values

        select new SelectListItem

        {

            Text = value.ToString(),

            Value = value.ToString(),

            Selected = value == selectedMovie,

        };

    ViewBag.MovieType = items;

}

public ActionResult SelectCategoryEnum() {

    SetViewBagMovieType(eMovieCategories.Drama);

    return View("SelectCategory");

}

The enum eMovieCategories captures the four movie types. The SetViewBagMovieType method creates the IEnumerable<SelectListItem > from the eMovieCategoriesenum, and sets the Selected property from the selectedMovie parameter. The SelectCategoryEnum action method uses the same view as the SelectCategory action method.

Navigate to the Test page and click on the Select Movie Category (Enum) link. This time, instead of a value (number) being displayed, a string representing the enum is displayed.

Posting Enum Values

HTML Forms are typically used to post data to the server. The following code shows the HTTP GET and HTTP POST versions of the SelectCategoryEnumPost method.

public ActionResult SelectCategoryEnumPost() {

    SetViewBagMovieType(eMovieCategories.Comedy);

    return View();

}

[HttpPost]

public ActionResult SelectCategoryEnumPost(eMovieCategories MovieType) {

    ViewBag.messageString = MovieType.ToString() +

                            " val = " + (int)MovieType;

    return View("Information");

}

By passing a eMovieCategories enum to the POST method, we can extract both the enum value and the enum string. Run the sample and navigate to the Test page. Click on the Select Movie Category(Enum Post) link. Select a movie type and then hit the submit button. The display shows both the value and the name of the movie type.

Image of value and name of movie type

Creating a Multiple Section Select Element

The ListBox HTML helper renders the HTML <select> element with the multiple attribute, which allows the users to make multiple selections. Navigate to the Test link, then select the Multi Select Country link. The rendered UI allows you to select multiple countries. In the image below, Canada and China are selected.

Image of multiple selections drop down list

Examining the MultiSelectCountry Code

Examine the following code from the Controllers\HomeController.cs file.

private MultiSelectList GetCountries(string[] selectedValues) {

    List<Country> Countries = new List<Country>()

        {

            new Country() { ID = 1, Name= "United States" },

            new Country() { ID = 2, Name= "Canada" },

            new Country() { ID = 3, Name= "UK" },

            new Country() { ID = 4, Name= "China" },

            new Country() { ID = 5, Name= "Japan" }

        };

    return new MultiSelectList(Countries, "ID", "Name", selectedValues);

}

public ActionResult MultiSelectCountry() {

    ViewBag.Countrieslist = GetCountries(null);

    return View();

}

The GetCountries method creates a list of countries, then passes it to the MultiSelectList constructor. The MultiSelectList constructor overload used in the GetCountries method above takes four parameters:

public MultiSelectList(

    IEnumerable items,

    string dataValueField,

    string dataTextField,

    IEnumerable selectedValues

)
  1. items: An IEnumerable containing the items in the list. In the example above, the list of Countries.
  2. dataValueField: The name of the property in the IEnumerable list that contains the value. In the example above, the ID property.
  3. dataTextField: The name of the property in the IEnumerable list that contains the information to display. In the example above, the name property.
  4. selectedValues: The list of selected values.

In the example above, the MultiSelectCountry method passes a null value for the selected countries, so no countries are selected when the UI is displayed. The following code shows the Razor markup used to render the MultiSelectCountry view.

@{

    ViewBag.Title = "MultiSelect Country";

    Layout = "~/Views/Shared/_Simple_Layout.cshtml";

}

@if (ViewBag.YouSelected != null) {

    <div> You Selected:  @ViewBag.YouSelected</div>

}

@using (Html.BeginForm()) {

    <fieldset>

        <legend>Multi-Select Demo</legend>

        <div class="editor-field">

            @Html.ListBox("Countries", ViewBag.Countrieslist as MultiSelectList

            )

        </div>

        <p>

            <input type="submit" value="Save" />

        </p>

    </fieldset>

}

The HTML helper ListBox method used above take two parameters, the name of the property to model bind and the MultiSelectList containing the select options and values. The ViewBag.YouSelected code above is used to display the values of the countries you selected when you submit the form. Examine the HTTP POST overload of the MultiSelectCountry method.

[HttpPost]

public ActionResult MultiSelectCountry(FormCollection form) {

    ViewBag.YouSelected = form["Countries"];

    string selectedValues = form["Countries"];

    ViewBag.Countrieslist = GetCountries(selectedValues.Split(','));

    return View();

}

The ViewBag.YouSelected dynamic property contains the selected countries, obtained for the Countries entry in the form collection. In this version the GetCountries method is passed a list of the selected countries, so when the MultiSelectCountry view is displayed, the selected countries are selected in the UI.

Making a Select Element Friendly with the Harvest Chosen jQuery Plugin

The Harvest Chosen jQuery plugin can be added to an HTML <select> element to create a user friendly UI. The images below demonstrate the Harvest Chosen jQuery plugin with MultiSelectCountry view.

Image of Harvest Chosen j Query plugin

In the two images below, Canada is selected.

Image of Canada selected

Image of Canada selected with X to remove

In the image above, Canada is selected, and it contains an x you can click to remove the selection. The image below shows Canada, China, and Japan selected.

Image of Canada China and Japan selected

Hooking up the Harvest Chosen jQuery Plugin

The following section is easier to follow if you have some experience with jQuery. If you have never used jQuery before, you might want to try one of the following jQuery tutorials.

The Chosen plugin is included in the starter and completed sample projects that accompany this tutorial. For this tutorial you will only need to use jQuery to hook it up to the UI. To use the Harvest Chosen jQuery plugin in an ASP.NET MVC project, you must:

  1. Download Chosen plugin from github. This step has been done for you.
  2. Add the Chosen folder to your ASP.NET MVC project. Add the assets from the Chosen plugin you downloaded in the previous step to the Chosen folder. This step has been done for you.
  3. Hook up the chosen plugin to the DropDownList or ListBox HTML helper.

Hooking up the Chosen Plugin to the MultiSelectCountry View.

Open the Views\Home\MultiSelectCountry.cshtml file and add an htmlAttributes parameter to the Html.ListBox. The parameter you will add contains a class name for the select list(@class = "chzn-select"). The completed code is shown below:

<div class="editor-field">

    @Html.ListBox("Countries", ViewBag.Countrieslist as MultiSelectList

     , new

     {

         @class = "chzn-select",

         data_placeholder = "Choose  Countries..."

     }

    )

</div>

In the code above, we are adding the HTML attribute and attribute value class = "chzn-select". The @ character preceding class has nothing to do with the Razor view engine. class is a C# keyword. C# keywords cannot be used as identifiers unless they include @ as a prefix. In the example above, @class is a valid identifier but class is not because class is a keyword.

Add references to the Chosen/chosen.jquery.js and Chosen/chosen.css files. The Chosen/chosen.jquery.js and implements the functionally of the Chosen plugin. The Chosen/chosen.css file provides the styling. Add these references to the bottom of the Views\Home\MultiSelectCountry.cshtml file. The following code shows how to reference the Chosen plugin.

<script src="@Url.Content("~/Chosen/chosen.jquery.js")" type="text/javascript"></script><script src="@Url.Content("~/Chosen/chosen.jquery.js")" type="text/javascript"></script>

<link href="@Url.Content("~/Chosen/chosen.css")" rel="stylesheet"  type="text/css" />

Activate the Chosen plugin using the class name used in the Html.ListBox code. In the example above, the class name is chzn-select. Add the following line to the bottom of the Views\Home\MultiSelectCountry.cshtml view file. This line activates the Chosen plugin.

<script >    $(".chzn-select").chosen(); </script>  @*Hookup Chosen Plugin*@

The following line is the syntax to call the jQuery ready function, which selects the DOM element with class name chzn-select.

$(".chzn-select")

The wrapped set returned from the above call then applies the chosen method (.chosen();), which hooks up the Chosen plugin.

The following code shows the completed Views\Home\MultiSelectCountry.cshtml view file.

@{

    ViewBag.Title = "MultiSelect Country";

    Layout = "~/Views/Shared/_Simple_Layout.cshtml";

}

@if (ViewBag.YouSelected != null) {

    <div> You Selected:  @ViewBag.YouSelected</div>

}

@using (Html.BeginForm()) {

    <fieldset>

        <legend>Multi-Select Demo</legend>

<div class="editor-field">

    @Html.ListBox("Countries", ViewBag.Countrieslist as MultiSelectList

     , new

     {

         @class = "chzn-select"

     }

    )

</div>

        <p>

            <input type="submit" value="Save" />

        </p>

    </fieldset>

}

<script src="@Url.Content("~/Chosen/chosen.jquery.js")" type="text/javascript"></script>

<link href="@Url.Content("~/Chosen/chosen.css")" rel="stylesheet"  type="text/css" />

<script >    $(".chzn-select").chosen(); </script> @*Hookup Chosen Plugin*@

Run the application and navigate to the MultiSelectCountry view. Try adding and deleting countries. The sample download provided also contains a MultiCountryVM method and view that implements the MultiSelectCountry functionality using a view model instead of a ViewBag.

In the next section you'll see how the ASP.NET MVC scaffolding mechanism works with the DropDownList helper.