Can someone please help me make my example of Country/State drop down dependency work?
I intentionally created JSON in this way because I want the dependency to be generic, so I would be able to apply it on any drop down while using only Meta Data and not HTML.
Here's a link to see an example of the code in JSFidlle
HTML
Country:<select data-ng-model="Countries" data-ng-options="country.id as country.name for country in Countries.items">
<option value="">Please select a country</option>
</select>
State: <select data-ng-model="currentItem" data-ng-options="item.id as item.name for item in currentStates.items">
<option value="">Please select a state</option>
</select>
JavaScript Code:
function Controller($scope) {
var Countries = {
"id": "field10",
"items": [{
"id": "10",
"StateGroupID":"0",
"name": "United State"
},
{
"id": "2",
"StateGroupID":"1",
"name": "Canada"
}]
};
var States =
{ "id": "field20",
"StateGroups": [{
"items": [{ "id": "1",
"name": "Alabama"
},
{
"id": "2",
"name": "Alaska"
},
{ "id": "3",
"name": "Arizona"
},
{ "id": "4",
"name": "California"
}]},
[{ "id": "201",
"name": "Alberta"
},
{
"id": "202",
"name": "British Columbia"
},
{
"id": "303",
"name": "Manitoba"
},
{
"id": "304",
"name": "Ontario"
}]]
};
$scope.Countries = Countries;
$scope.currentStates = States.StateGroups[0];
$scope.$watch('currentStates', function(value, oldValue){
//alert(value);
//alert(JSON.stringify(value));
//$scope.currentStates = (value == "10") ? States.StateGroups[0] : States.StateGroups[1];
});
}
first, I think there is a little mistake in your JSON, you should have one "items" before the Canadian states
{"items": [{ "id": "201",
"name": "Alberta"
}, .....
After doing this, I would modify your HTML in order to have 2 different model names (the way you did, at the first click you overwrite the list of countries). Then I'll use a different syntax for the ng-repeat, in order to force the value to the StateGroupId
<select data-ng-model="selectedCountry">
<option ng-repeat='country in Countries.items' value='{{country.StateGroupID}}'>{{country.name}}</option>
</select>
Doing this allows you to create a function to get the states of the selected group ID :
$scope.getStates=function(){
console.log($scope.selectedCountry)
return $scope.backupStates.StateGroups[$scope.selectedCountry].items;
}
Then you can use this function to display them using ng-repeat
<select data-ng-model="selectedState" >
<option value="">Please select a state</option>
<option ng-repeat='state in getStates()'>{{state.name}}</option>
</select>
I modified your fiddle here : http://jsfiddle.net/DotDotDot/TsxTU/14/ , I hope this is the kind of behavior you wanted :)
I suggest you a bit of refactoring to your data model - it seems tangled. Let's store counties and states in two arrays:
$scope.countries = [{
"name": "USA",
"id": 1
},{
"name": "Canada",
"id": 2
}];
$scope.states = [{
"name": "Alabama",
"id": 1,
"countryId": 1
}, {
"name": "Alaska",
"id": 2,
"countryId": 1
}, {
"name": "Arizona",
"id": 3,
"countryId": 1
}, {
"name": "Alberta",
"id": 4,
"countryId": 2
}, {
"name": "British columbia",
"id": 5,
"countryId": 2
}];
Having this, we can write selects for data:
<select data-ng-model="country" data-ng-options="country.name for country in countries" data-ng-change="updateCountry()">
<option value="">Select country</option>
</select>
<select data-ng-model="state" data-ng-options="state.name for state in availableStates">
<option value="">Select state</option>
</select>
It's a pity we cannot use if expressions in selectors - if we can, we do not need a single line of JS! But we need:
$scope.updateCountry = function(){
$scope.availableStates = [];
angular.forEach($scope.states, function(value){
if(value.countryId == $scope.country.id){
$scope.availableStates.push(value);
}
});
}
And that's all. Here is a working plunk for you.
The easiest way to fix is to refer the currentCountry in the 2nd select and no need to use the $watch to achieve your requirement.
<select data-ng-model="currentCountry" data-ng-options="country.name for country in Countries.items">
<select data-ng-model="currentItem" data-ng-options="item.id as item.name for item in States.StateGroups[currentCountry.StateGroupID].items">
Demo
angular-country-picker
bower install angular-country-picker (or)
npm install angular-country-picker
<script src="bower_components/angular-country-picker/country-picker.js"></script>
<script src="node_modules/angular-country-picker/country-picker.js"></script>
angular.module('webApp', ['puigcerber.countryPicker']);
<select ng-model="selectedCountry" pvp-country-picker="name"></select>
angular.module('myApp', ['puigcerber.countryPicker'])
.config(function(pvpCountriesProvider) {
pvpCountriesProvider.setCountries([
{ name: 'Abkhazia', alpha2: 'AB'},
{ name: 'Kosovo', alpha2: 'XK'},
{ name: 'Nagorno-Karabakh', alpha2: 'NK'},
{ name: 'Northern Cyprus', alpha2: 'KK'},
{ name: 'Somaliland', alpha2: 'JS'},
{ name: 'South Ossetia', alpha2: 'XI'},
{ name: 'Transnistria', alpha2: 'PF'}
]);
});
Related
I am trying to implement a country-city dependable drop-down using AngularJS
<div>
Country:
</br>
<select data-ng-model="country" ng-options="country.name for country in countries" data-ng-change="updateCountry(country)">
<option value="">Select country</option>
</select>
</div>
<div>
City</br>
<select data-ng-model="city" data-ng-options="city.name for city in countryItem">
<option value="">Select city</option>
</select>
</div>
Controller Code
$scope.updateCountry = function(selectedCountry)
{
console.log("The selected country is
"+JSON.stringify(selectedCountry));
HomeFactory.setTappedCountryData(selectedCountry);
$scope.countryItem = HomeFactory.getTappedCountryData();
console.log("The country Item is "+JSON.stringify($scope.countryItem));
}
Factory Code
function setTappedCountryData(data){
console.log(JSON.stringify(data));
selectedCountry = data;
};
function getTappedCountryData(data){
console.log(JSON.stringify(data));
return selectedCountry;
};
JSON Data
[{
"id": "1", "name":"USA",
"cities": [{
"id": "1",
"name": "New York"
}, {
"id": "2",
"name": "Los Angeles"
}]
}, {
"id": "2", "name":"UK",
"cities": [{
"id": "3",
"name": "London"
}, {
"id": "4",
"name": "Glasgow"
}]
},
{
"id": "3", "name":"Russia",
"cities": [{
"id": "5",
"name": "Moscow"
}, {
"id": "6",
"name": "St. Petersburg"
}]
},
{
"id": "4", "name":"Spain",
"cities": [{
"id": "7",
"name": "Madrid"
}, {
"id": "8",
"name": "Barcelona"
}]
},
{
"id": "5", "name":"India",
"cities": [{
"id": "9",
"name": "Delhi"
}, {
"id": "10",
"name": "Mumbai"
}]
}]
I cannot get the cities for a particular country in the 2nd dropdown. Where I am making mistake?
Hadi Jeddizahed has solved the problem
Only problem is the code is not working in Chrome develper mobile emulator ( for mobile device like iphone6, Nexus 6 etc)
Try like this.
you can also do this in controller in simple way
$scope.updateCountry = function(selectedCountry) {
$scope.countryItem = selectedCountry.cities
}
and in view similar to this
<select data-ng-model="city" data-ng-options="city.name for city in country.cities">
<option value="">Select city</option>
</select>
DEMO
I have the following data structure thats coming from an API.
$scope.cityList = [{
"_id": {
"$oid": "584ebd7f734d1d55b6dd4e5e"
},
"cityName": "New York",
"region": "north",
"people": [
{ "id": 1, "name": "x" },
{ "id": 2, "name": "y" },
{ "id": 3, "name": "z" },
{ "id": 4, "name": "a" },
{ "id": 5, "name": "b" },
{ "id": 6, "name": "c" }
]
},
{
"_id": {
"$oid": "584ebd7f734d1d55b6dd4e5e"
},
"cityName": "New Jersey",
"region": "South",
"people": [
{ "id": 1, "name": "x" },
{ "id": 2, "name": "y" },
{ "id": 3, "name": "z" },
{ "id": 4, "name": "a" },
{ "id": 5, "name": "b" },
{ "id": 6, "name": "c" }
]
}]
I'm trying to setup two dropdowns:
the first one displays a list of the cityNames
the second displays the list of all people names from the selected city.
I also want to save the id of the selected user name into a variable.
I've tried this so far:
<select ng-model="city">
<option ng-repeat="city in cityList" value="{{city.cityName}}">{{city.cityName}}</option>
</select>
<select ng-model="selectedItem">
<optgroup ng-repeat="option in cityList | filter: city">
<option ng-repeat="x in option.people">{{x}}</option>
</select>
You should use ng-options:
<select ng-model="selectedCity"
ng-options="c as c.cityName for c in cityList">
</select>
<select ng-model="selectedPerson"
ng-options="p as p.name for p in selectedCity.people">
</select>
Demo on JSFiddle.
This my json data how to set a selected option of a dropdown list control using angular JS
$scope.alltoys=[
{
"dId": "570b886545034f0001718247",
"dName": "Toys",
"dSubName": "Comics",
"users": [
{
"name": "Superman",
"id": "570b9e3a45034f000171827b"
},
{
"name": "Batman",
"id": "570ba00045034f000171828a"
}]
},
{
"dId": "5767c68c52faff0001fb8555",
"dName": "Toys",
"dSubName": "General",
"users": [
{
"name": "Jack",
"id": "570b9e3a45034f000171827b"
},
{
"name": "Sparrow",
"id": "570ba00045034f000171828a"
}]
}
]
How to populate this select box using angular js
I want to populate like this
Toys-Comics
Batman
Superman
Toys-General
Jack
Sparrow
In here Toys-Comics & Toys-General are only title of that selected content
I want to sort users array when populate.
<div class="controls">
<select class="form-control" ng-model="toy"
ng-options="eachtoy as eachtoy.dName+' - '+eachtoy.dSubName group by eachtoy for eachtoy in alltoys">
<option value="">---------------Select---------------</option>
</select>
</div>
I tried this but its not working.
Couple of changes. First, make sure $scope.alltoys is a collection (array), like this:
$scope.alltoys = [{
"dId": "570b886545034f0001718247",
"dName": "Toys",
"dSubName": "Comics",
"users": [{
"name": "Superman",
"id": "570b9e3a45034f000171827b"
}, {
"name": "Batman",
"id": "570ba00045034f000171828a"
}]
}, {
"dId": "5767c68c52faff0001fb8555",
"dName": "Toys",
"dSubName": "General",
"users": [{
"name": "Jack",
"id": "570b9e3a45034f000171827b"
}, {
"name": "Sparrow",
"id": "570ba00045034f000171828a"
}]
}];
Then change your html to handle groups with optgroup, like this:
<select class="form-control" ng-model="toy">
<option value="">---------------Select---------------</option>
<optgroup ng-repeat="eachtoy in alltoys | orderBy: 'dName + dSubName" label="{{eachtoy.dName+' - '+eachtoy.dSubName}}">
<option ng-repeat="user in eachtoy.users | orderBy: 'name'">{{user.name}}</option>
</optgroup>
</select>
Here's a working plunk
I have this code:
<!DOCTYPE html>
<html>
<head>
<title>Lists Test</title>
<script src="https://code.angularjs.org/1.1.1/angular.min.js"></script>
<script>
function Controller($scope) {
$scope.backupCountries = {
"id": "field10",
"items": [{
"id": "10",
"StateGroupID": "0",
"name": "United State"
}, {
"id": "2",
"StateGroupID": "1",
"name": "Canada"
}]
};
$scope.backupStates = {
"id": "field20",
"StateGroups": [{
"items": [{
"id": "1",
"name": "Alabama"
}, {
"id": "2",
"name": "Alaska"
}, {
"id": "3",
"name": "Arizona"
}, {
"id": "4",
"name": "California"
}]
},
{
"items": [{
"id": "201",
"name": "Alberta"
}, {
"id": "202",
"name": "British Columbia"
}, {
"id": "303",
"name": "Manitoba"
}, {
"id": "304",
"name": "Ontario"
}]
}]
};
$scope.Countries = $scope.backupCountries;
$scope.getStates = function () {
console.log($scope.selectedCountry);
return $scope.backupStates.StateGroups[$scope.selectedCountry].items;
};
//$scope.currentStates = $scope.backupStates.StateGroups[0];
/*$scope.$watch('currentStates', function(value, oldValue){
//alert(value);
//alert(JSON.stringify(value));
//$scope.currentStates = (value == "10") ? States.StateGroups[0] : States.StateGroups[1];
});*/
};
</script>
</head>
<body>
<div ng-app ng-controller="Controller">
<h2 class="page-title">Model</h2>
<div class="row-fluid">
<div class="span4">
<label for="cboGroup">Countries</label>
<select data-ng-model="selectedCountry">
<option value="">Please Select a Country</option>
<option ng-repeat='country in Countries.items' value='{{country.StateGroupID}}'>{{country.name}}</option>
</select>
</div>
<div class="span4">
<label for="cboItem">States</label>
<select data-ng-model="selectedState">
<option value="">Please select a state</option>
<option ng-repeat='state in getStates()'>{{state.name}}</option>
</select>
</div>
<div class="well">what I am trying to archive is that the items are changing each time the group changes.</div>
<div>Countries : {{Countries.items | json}}</div>
<div>States : {{getStates()}}</div>
</div>
What I have been struggling with is migrating this code to Angular 1.4.But I don't know what's wrong with my code or what to change in it. The code is working flawlessly in Angular 1.1.1 but when I change the angular source to a js with upper version, all goes black.
A couple of odd things stand out:
You can use ng-model, without the data-* prefix.
$scope.selectedCountry is not initialized anywhere.
need to connect your app with the ng-app directive: ng-app="my_app" id="ng-app"
you don't have a module or controller definition
My recommendation is to figure out which version of AngularJS starts to break your code and what the most recent one is that your code still works with. Then read the release docs and see what changes were made that may be breaking your code.
I have an array of objects. I have three properties attorneyId, attorneyName and attorneyList. The attorneyList array should be a drop down. If attorneyId = attorneyName = null then
dropdown will only show Choose attorney. If attorneyId != null and attorneyName != null, the dropdown should display what ever the value is present in attorneyId and attorneyName.
For this i am preparing an object selectedAttorney = {id:list.attorneyId, name:list.attorneyName} and passing this to ng-model of select. When i change the value in dropdown, i am getting the correct values into the selectedAttorney. But if there some value present for attorneyId and attorneyName, the dropdown is not pre populating the value.
HTML :
<div ng-repeat = 'list in List'>
<div class="width-200" ng-init="selectedAttorney = {id:list.attorneyId, name:list.attorneyName}">
{{selectedAttorney}}
<select ng-model="selectedAttorney" ng-options="attorney.name for attorney in list.attorneyList">
<option value="">-- choose attorney --</option>
</select>
</div>
</div>
JS
$scope.List = [ {
"attorneyId": "3",
"attorneyName": "Robert",
"attorneyList": [
{ "id": 1, "name": "sue" },
{ "id": 2, "name": "anthony" },
{ "id": 3, "name": "Robert" },
{ "id": 4, "name": "George" },
{ "id": 5, "name": "Bruce" }
]
},
{
"attorneyId": null,
"attorneyName": null,
"attorneyList": [
{ "id": 1, "name": "sue" },
{ "id": 2, "name": "anthony" },
{ "id": 3, "name": "Robert" },
{ "id": 4, "name": "George" },
{ "id": 5, "name": "Bruce" }
]
}
];
Here is the plunker link.
http://plnkr.co/edit/eqBkX0DNleiFmlO5sm7J?p=preview
Thanks in advance.
Though your approach is right, I prefer writing my select boxes in this manner.
<select ng-model="selectedAttorney">
<option
ng-repeat="attorney in list.attorneyList"
title="{{attorney.name}}"
ng-selected="{{attorney.id == selectedAttorney.id}}"
value="{{attorney}}">{{attorney.name}}
</option>
</select>
and here is the updated working demo : http://plnkr.co/edit/vCNOAPWlR6Mj1kFOgCKT?p=preview