Cascading dropdown with angularjs is easier than MVC and ASP.Net. In Angularjs ng-change is the best event to hook the function to get the second dropdown list items. In this article, we will try to fill the state dropdown on selection change of country and then fill the city dropdown on change of state dropdown. We will fetch only those records from database which match the criteria rather than filtering in controller. I already create a codepen example so you can check it here
See the demo, here is the image of this example
I am going to use dummy json data which you can use the fetch the data from database, so you need to change the conde only in the service and not the controller and HTML, enough talked let's see the sevice methods to fetch the data
// Get Country list
service.getCountry = function(){
return countrylist;
};
// Get State list for country
service.getCountryState = function(countryId){
var states = ($filter('filter')(statelist, {countryId: countryId}));
return states;
};
// Get city list for state
service.getStateCity = function(stateId){
var items = ($filter('filter')(citylist, {stateId: stateId}));
return items;
};
Let's say you are creating the customer page to add new customer or update existing customer so we need to keep that customer on the scope, if new a blank customer object on the scope and it's properties will be bind with ng-model. Since we need to show the country select list by default so we will get the complete list of country from service and put it on scope with name $scope.countries in our controller
myApp.controller('dropdownCtrl', ['$scope','CustomerService',
function($scope, CustomerService) {
$scope.customer ={
Name:'',
Country:'',
State: '',
City: ''
};
$scope.countries = CustomerService.getCountry();
}]);
Here I am creating the customer object manually, you can create an object directly from you class, like in Web API and return that like return new Customer();
Next I am calling the getCountry method in my service CustomerService which we already seen in above code. Now let's see the country dropdown in HTML and it's bindings
<select ng-model="customer.Country"
ng-options="obj.id as obj.country for obj in countries"
ng-change="getCountryStates()"
class="form-control"
ng-required="true"
id="country">
<option value="">-- Choose Country --</option>
</select>
So far it is good, nothing complicated, not on ng-change I am calling a method in controller to get the state list, doesn't have any parameter, so how we know which country is selected, note the ng-model which we already bind with customer country property, so we can use $scope.customer.Country
, every time you change the country, country property in customer refreshed, see at the bottom where I am showing the selected values, here is the getCountryStates function
$scope.getCountryStates = function(){
$scope.sates = CustomerService.getCountryState($scope.customer.Country);
$scope.cities =[];
}
$scope.sates
Here is the state select HTML code
<select ng-model="customer.State"
ng-options="x.Id as x.state for x in sates"
ng-change = "getStateCities()"
class="form-control"
ng-required="true"
id="state">
<option value="">-- Choose State --</option>
</select>
It is very similar to country dropdown, it also contain ng-change event to fill the city by using getStateCities()
function in controller
$scope.getStateCities = function(){
$scope.cities = CustomerService.getStateCity($scope.customer.State);
}
Again in the same way we are calling a service method to get the list of cities for selected state and put it on scope `$scope.cities' which we use to bind the cities in our view, here is the simplest city dropdown HTML
<select ng-model="customer.City"
ng-options="x.Id as x.city for x in cities"
class="form-control"
ng-required="true"
id="city">
<option value="">-- Choose City --</option>
</select>
That's all we need for these three cascade dropdown, in HTML rest of the code is for designing the page and align the controls, all of the CSS and classes using the bootstrap. Here is the complete controller code:
angular.module("myApp")
.controller('dropdownCtrl', ['$scope','CustomerService',
function($scope, CustomerService) {
$scope.customer ={
Name:'',
Country:'',
State: '',
City: ''
};
$scope.countries = CustomerService.getCountry();
$scope.getCountryStates = function(){
$scope.sates = CustomerService.getCountryState($scope.customer.Country);
$scope.cities =[];
};
$scope.getStateCities = function(){
$scope.cities = CustomerService.getStateCity($scope.customer.State);
}
}]);
Since I am using dummy data in service so It is not very useful for you but just adding here in case it can help anyone to understand the concept
angular.module("myApp")
.factory("CustomerService", ['$filter',
function($filter){
var service = {};
var countrylist = [
{ "id": 1, "country": "USA" },
{ "id": 2, "country": "Canada" },
{ "id": 3, "country": "India" },
];
var statelist = [
{"Id":1, "state":"Alaska", "countryId": 1},
{"Id":2, "state":"California", "countryId": 1},
........................
];
var citylist = [
{"Id":1, "city":"Anchorage", "stateId": 1},
{"Id":2, "city":"Fairbanks", "stateId": 1},
........................
];
service.getCountry = function(){
return countrylist;
};
service.getCountryState = function(countryId){
var states = ($filter('filter')(statelist, {countryId: countryId}));
return states;
};
service.getStateCity = function(stateId){
var items = ($filter('filter')(citylist, {stateId: stateId}));
return items;
};
return service;
}]);
Do you want to see the HTML, ok it is here:
<div ng-app="myApp" class="container">
<h3>Angularjs Cascading Dropdown/Select</h3>
<form class="form-horizontal" ng-controller="dropdownCtrl">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">
Customer Name </label>
<div class="col-sm-7">
<input ng-model="customer.Name"
type="text"
class="form-control"
ng-required="true"
id="name" />
</div>
</div>
<div class="form-group">
<label for="country" class="col-sm-2 control-label">Country </label>
<div class="col-sm-7">
<select ng-model="customer.Country"
ng-options="obj.id as obj.country for obj in countries"
ng-change="getCountryStates()"
class="form-control"
ng-required="true"
id="country">
<option value="">-- Choose Country --</option>
</select>
</div>
</div>
<div class="form-group">
<label for="state" class="col-sm-2 control-label">State </label>
<div class="col-sm-7">
<select ng-model="customer.State"
ng-options="x.Id as x.state for x in sates"
ng-change = "getStateCities()"
class="form-control"
ng-required="true"
id="state">
<option value="">-- Choose State --</option>
</select>
</div>
</div>
<div class="form-group">
<label for="city" class="col-sm-2 control-label">City </label>
<div class="col-sm-7">
<select ng-model="customer.City"
ng-options="x.Id as x.city for x in cities"
class="form-control"
ng-required="true"
id="city">
<option value="">-- Choose City --</option>
</select>
</div>
</div class="form-group">
<div class="col-lg-offset-2">
<button class="btn btn-success"> Save </button>
</div>
<div class="form-group">
<div class="col-lg-offset-2">
<b>name:</b> {{customer.Name}}
<b>Country:</b> {{customer.Country}}
<b>State:</b> {{customer.State}}
<b>City:</b> {{customer.City}}
</div>
</div>
</form>
</div>
When I copied every thing then why not the CSS :)
input[type="text"].ng-invalid,
input[type="password"].ng-invalid,
input[type="date"].ng-invalid,
input[type="number"].ng-invalid,
select.ng-invalid{
border-left: 5px solid #ff0000;
background-color: #FFEBD6;
}
input[type="text"].ng-valid,
input[type="password"].ng-valid,
input[type="date"].ng-valid,
input[type="number"].ng-valid,
select.ng-valid{
background-color: #FFFFFF;
border-left: 5px solid #088b0b;
}
input[type="text"]:disabled.ng-valid{
background-color: #efefef;
border: 1px solid #ccc;
}
![]() |
Having 13+ years of experience in Microsoft Technologies (C#, ASP.Net, MVC and SQL Server). Worked with Metaoption LLC, for more than 9 years and still with the same company. Always ready to learn new technologies and tricks.
|
By Ali Adravi On 06 Aug, 15 Viewed: 57,780 |
Paging on table is the basic requirement and most of us look for some grid so it can provide the complete feature of paging and sorting but in Angularjs it is so easy that anyone can achieve it by writing some code. I checked and found most of the available code give the paging feature in for 1 to... By Ali Adravi On 14 Aug 2015 Viewed: 20,946
Add/Edid Customer in Modal Popup --- In previous article we discussed how to search, delete and show detail of customer and contact list. In this article we will try to open the modal popup to add new customer and edit an existing customer record. I divided article in two parts because of the... By Ali Adravi On 29 Jul 2015 Viewed: 19,718
Angularjs custom directives are the common to avoid the duplicate code, it is easy powerful and really nice. There are already too many directive have been created by experts but as a developer we need to write our own to achieve our specific goal. ng-model, ng-if, ng-show, ng-repeat all these are... By Ali Adravi On 29 Jul 2015 Viewed: 4,497
Search sort Insert update and delete are the basic features we need to learn first to learn any language, In this article we will try to create these features with Web API, bootstrap modal popup and ui.router. We will use enetity framework code first to save and retrieve data from database. We... By Ali Adravi On 28 Jul 2015 Viewed: 31,462
Progress bar for Angularjs application by using directives is simple and real easy. I was googling and could not found any directive way, if you will check most of the people says before call the http method open the progress bas and close once you get the result or get any error. Do you think it... By Ali Adravi On 24 Jul 2015 Viewed: 14,201