ASP.NET MVC–Cascading Dropdown Lists Tutorial
- Part 1 – Defining the problem and the context
- Part 2 – Cascading using normal FORM post (Html.BeginForm helper)
- Part 3 – Cascading using Microsoft AJAX (Ajax.BeginForm helper)
- Part 4 – Cascading using FORM Hijaxing
- Part 5 – Cascading using jQuery.ajax():
- Part 6 – Creating a jQuery Cascade Select Plugin
Part 1 – Defining the problem and the context
Problem
- You want to cascade two or more dropdown lists from your view:
- You want to fill the contents of the next dropdown based on the selection in the current dropdown list.
- You want to display a list/table filtered based on the selection of the last dropdown list.
-
Context
There are several ways to achieve this, but before drilling into each of them let’s define the context:
Let’s say we want to display a list of continents and when we select a continent another list will be filled with countries from that continent. When we select a country we will show a table with information about cities from that particular country. Something like this:
For this we will use the following model:
Setup
Before going further let’s prepare the programming environment a little. What we need:
- Visual Studio 2010 with Service Pack 1 (the edition doesn’t matter):
- You can install it via Web PI (Microsoft Web Platform Installer) or download it from here
-
- ASP.NET MVC 3 Tools Update (and of course ASP.NET MVC 3 RTM):
- NuGet 1.3:
- The 1.2 version will be installed by the MVC 3 Tools Update. You can upgrade it from Visual Studio Extension Manager or from here
-
- NuGet packages relevant for this tutorial (some of them are installed when you create a new ASP.NET MVC3 project and can be updated):
- EntityFramework.4.1.10331.0 (pre-installed)
- jQuery.1.6.1 (pre-installed as version 1.5.1 and can be updated from NuGet)
- T4MVC (version at the time of writing 2.6.54)
- SqlServerCompact.(version at the time of writing 4.0.8482.1)
- EntityFramework.SqlServerCompact (version at the time of writing 4.1.8482.2)
- MvcScaffolding.(version at the time of writing 1.0.0) – this must be installed from the NuGet Package Manager Console (Tools\Library Package Manager) by running the command Install-Package MvcScaffolding
-
We will use SQL Compact 4.0 to hold the data for this sample and we will access the data using EntityFramework 4.1 and the repository pattern. Lucky for us there is the MvcScaffolding package that will generate pretty much everything. In order to do that we need to run the following commands at the NuGet Package Manager Console (Tools\Library Package Manager) :
- Scaffold Repository Continent -Area:CascadingDropDownLists
- Scaffold Repository CascadingDropDownLists.Models.Country -Area:CascadingDropDownLists
- Scaffold Repository CascadingDropDownLists.Models.City -Area:CascadingDropDownLists
The –Area parameter is optional. If you don’t have an area you can delete it.
The result of running the above commands will be 4 files:
- ContinentRepository.cs
- CountryRepository.cs
- CityRepository.cs
- AtlasContext.cs
-
Because we will only display data from the database we need to have some seed data. For this we need to create a Database Initializer as follows (see the whole class in the source code download):
public class AtlasContextInitializer : DropCreateDatabaseIfModelChanges<AtlasContext> { protected override void Seed( AtlasContext context ) { //Add continents var europe = new Continent { Name = "Europe" }; var oceania = new Continent { Name = "Oceania" }; //Add countries //Europe europe.Countries = new Collection<Country> { new Country{Name = "Russia", Population = 142200000}, new Country{Name = "Germany", Population = 83251851} }; var romania = new Country { Name = "Romania" , Population = 21698181 }; europe.Countries.Add( romania ); //Add cities romania.Cities = new Collection<City> { new City {Name = "Bucharest", Population = 1926334} }; //Add to context context.Continents.Add( europe ); context.Continents.Add( oceania ); context.SaveChanges( ); } }
In order to enable de initializer we need to add the following line in the Application_Start handler in Global.asax.cs:
System.Data.Entity.Database.SetInitializer( new AtlasContextInitializer( ) );
The database will be created when we first try to read something from it. But this is the job of the next post.
I won’t go into further details about EntityFramework 4.1 and the Repository pattern because we will move away from the scope of this post. If you want to learn more please see the links from the References section.
What we have at this moment:
-
Project setup with NuGet Packages
-
Model to work with
-
Database with seed data
We will define next a view model called Atlas that will help in the next parts:
public class Atlas { public int? SelectedContinentId { get; set; } public int? SelectedCountryId { get; set; } public IEnumerable<Continent> Continents { get; set; } public IEnumerable<Country> Countries { get; set; } public IEnumerable<City> Cities { get; set; } }
In each of the following parts we will create separate controllers, views and partial views even some of the code can be reused. This will help to see the differences from each method used to cascade the dropdown lists.
References
EntityFramework 4.1 | Repository Pattern | MvcScaffolding