Using the DropDownList Helper with ASP.NET MVC
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:
- Visual Studio Web Developer Express SP1 prerequisites
- ASP.NET MVC 3 Tools Update
- SQL Server Compact 4.0(runtime + tools support)
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.
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.
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.
Select the Select Movie Category (Simple) link. A Movie Type Select list is displayed, with Comedy the selected value.
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.
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 Comedy
SelectListItem 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.
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 eMovieCategories
enum, 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.
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.
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
)
- items: An IEnumerable containing the items in the list. In the example above, the list of Countries.
- dataValueField: The name of the property in the IEnumerable list that contains the value. In the example above, the
ID
property. - dataTextField: The name of the property in the IEnumerable list that contains the information to display. In the example above, the
name
property. - 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.
In the two images below, Canada is selected.
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.
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.
- How jQuery Works by John Resig
- Getting Started with jQuery by Jörn Zaefferer
- Live Examples of jQuery by Cody Lindley
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:
- Download Chosen plugin from github. This step has been done for you.
- 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.
- 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.