In this article I will explain with an example, how to populate Cascading i.e. Dependent Country, State and City DropDownLists using AngularJS in ASP.Net MVC Razor.
The Cascading i.e. Dependent Country, State and City DropDownLists will be populated from database by making use of Entity Framework and AngularJS in ASP.Net MVC Razor.
Database
Three tables Countries, State and City are created with the following schema.
Countries Table
States Table
Cities Table
Note: You can download the database table SQL by clicking the download link below.
Creating an Entity Data Model
Following is the Entity Data Models of the three Tables i.e. Countries, States and Cities which will be used later in this project.
Controller
The Controller consists of two Action methods.
Action method for handling GET operation
Inside this Action method, simply the View is returned.
Action method for handling AJAX POST operation
This Action method is executed when the call is made from AngularJS client in View in two cases.
1. The load event of the page to populate the Country DropDownList.
2. Changed event of the Country and State DropDownLists.
It accepts type and value parameter and based on the type i.e. Country or State, the list of States or Cities respectively are fetched from the database and returned to View as JSON.
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult AjaxMethod(string type, int value)
{
List<SelectListItem> items = new List<SelectListItem>();
CascadingEntities entities = new CascadingEntities();
switch (type)
{
default:
foreach (var country in entities.Countries)
{
items.Add(new SelectListItem { Text = country.CountryName, Value = country.CountryId.ToString() });
}
break;
case "CountryId":
var states = (from state in entities.States
where state.CountryId == value
select state).ToList();
foreach (var state in states)
{
items.Add(new SelectListItem { Text = state.StateName, Value = state.StateId.ToString() });
}
break;
case "StateId":
var cities = (from city in entities.Cities
where city.StateId == value
select city).ToList();
foreach (var city in cities)
{
items.Add(new SelectListItem { Text = city.CityName, Value = city.CityId.ToString() });
}
break;
}
return Json(items);
}
}
View
The View consists of an HTML DIV to which ng-app and ng-controller AngularJS directives have been assigned.
The HTML DIV consists of three HTML DropDownList element (SELECT), one for each Country, State and City respectively.
There is a function named LoadDropDown inside the AngularJS Controller. The LoadDropDown function is called thrice for populating the three Country, State and City DropDownLists.
Inside the LoadDropDown function, the $http service is used to make an AJAX call to the Controller’s Action method.
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width"/>
<title>Index</title>
</head>
<body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module('MyApp', [])
app.controller('MyController', function ($scope, $http, $window) {
$scope.LoadDropDown = function (type, value) {
switch (type) {
default:
$scope.SelectedCountryId = 0;
$scope.CountryDefaultLabel = "Loading.....";
$scope.Countries = null;
break;
case "CountryId":
$scope.SelectedStateId = 0;
$scope.StateDefaultLabel = "Loading.....";
$scope.CityDefaultLabel = "";
$scope.States = null;
$scope.Cities = null;
break;
case "StateId":
$scope.SelectedCityId = 0;
$scope.CityDefaultLabel = "Loading.....";
$scope.Cities = null;
break;
}
$http({
method: "POST",
url: "/Home/AjaxMethod",
dataType: 'json',
data: '{type: "' + type + '", value: ' + value + '}',
headers: { "Content-Type": "application/json" }
}).success(function (data, status) {
switch (type) {
default:
$scope.CountryDefaultLabel = "Select Country";
$scope.Countries = data;
break;
case "CountryId":
$scope.StateDefaultLabel = "";
if (data.length > 0) {
$scope.StateDefaultLabel = "Select State";
$scope.States = data;
}
break;
case "StateId":
$scope.CityDefaultLabel = "";
if (data.length > 0) {
$scope.Cities = data;
$scope.CityDefaultLabel = "Select City";
}
break;
}
}).error(function (data, status) {
$window.alert(data.Message);
});
};
$scope.LoadDropDown('', 0);
});
</script>
<div ng-app="MyApp" ng-controller="MyController">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>Country:</td>
<td>
<select name="Country" ng-model="SelectedCountryId" ng-change="LoadDropDown('CountryId',SelectedCountryId)">
<option value="0">{{CountryDefaultLabel}}</option>
<option ng-repeat="item in Countries" value="{{item.Value}}">
{{item.Text}}
</option>
</select>
</td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td>State:</td>
<td>
<select name="State" ng-model="SelectedStateId" ng-change="LoadDropDown('StateId',SelectedStateId)">
<option value="0">{{StateDefaultLabel}}</option>
<option ng-repeat="item in States" value="{{item.Value}}">
{{item.Text}}
</option>
</select>
</td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td>City:</td>
<td>
<select name="City">
<option value="0">{{CityDefaultLabel}}</option>
<option ng-repeat="item in Cities" value="{{item.Value}}">
{{item.Text}}
</option>
</select>
</td>
</tr>
</table>
</div>
</body>
</html>
Screenshot
Browser Compatibility
The above code has been tested in the following browsers.
* All browser logos displayed above are property of their respective owners.
Downloads