AngularJs populate second dropdown based on first dropdown - javascript

I have two select input, first one contain countryName, i want to populate the StateName to the second select input depending on the CountryName that is chosen i.e the stateName for the selected country only.
I bind the countryName from the countryData and the State from State Data but I want the StateData to contain item based on the selected country
<select ng-model="selectedItem.CountryId" class="form-control"
ng-options="item._id as item.CountryName for item in countryData">
<option value="">Select</option>
</select>
<select ng-model="selectedItem.StateId" class="form-control"
ng-options="item._id as item.StateName for item in stateData">
<option value="">Select</option>
</select>
Here is how my stateData looks
[
{
"StateName": "State1",
"CountryName": "Country1",
},
{
"StateName": "State2",
"CountryName": "Country1",
},
{
"StateName": "State3",
"CountryName": "Country2",
},
{
"StateName": "State4",
"CountryName": "Country3",
},
{
"StateName": "State5",
"CountryName": "Country2",
},
{
"StateName": "State6",
"CountryName": "Country3",
}
]

You can disable the second drop down until the first is selected. You also need to change your JSON so that the states sit in an array. The second dropdown will only populate once you have selected a country and will then be enabled. -updated
<select ng-options="item.country for item in list" ng-model="selectedCountry"></select>
<select ng-disabled="selectedCountry === {}" ng-options="item.state for item in selectedCountry.states" ng-model="selectedState"></select>
https://jsfiddle.net/Kratos_SA/hjz27yb0/3/

Related

dependent dropdown with json data in angular js

I am trying to make dependent dropdown using JSON data
Used (for in) to get the key to integrate it in the dropdown but didn't work,whatever i searched every time json data is getting accessed by key to get the value in this structure i am able to get it in dropdown [{name:"india"},{name:"usa"}].But with current json structure i am not able to do it.
HTML:-
<div ng-controller="myCtrl3">
<select>
<option>Select Country</option>
<option ng-repeat="country in chooseCountries"></option>
<option ng-repeat="states in country"></option>
<option ng-repeat="city in states"></option>
</select>
</div>
JS:-
app.controller('myCtrl3',function($scope,$http){
$http({
url:'js/country.json',
method:'GET'
})
.then(function(response){
$scope.chooseCountries = response.data;
});
});
JSON(country.json):-
[{
"INDIA": {
"KARNATAKA": ["BANGALORE", "UDUPI", "MANGALORE"],
"TELENGANA": ["HYDERABAD", "GUNTUR", "SHANKERPALLY"]
},
"USA": {
"CALIFORNIA": ["SAN JOSE", "SAN HOSE", "NEW YORK"],
"FLORIDA": ["MIAMI", "DENVER"],
"INDIAPOLIS": ["INDIANA", "MASACHUTTEUS"]
},
"AUSTRALIA": {
"NEW SOUTH WALES": ["SYDNEY", "BRISBANE"],
"QUEENSLAND": ["PERTH", "VICTORIA"],
"WESTERN AUSTRALIA": ["MELBOURNE", "MCG"]
}
}]
i want the output first dropdown should show INDIA,USA,AUSTRALIA if i click INDIA second dropdown should show KARNATAKA AND TELENGANA in the third dropdown list if i click KARNATAKA it should show BANGALORE,UDUPI,MANGALORE.Didn't got any error but coudn't get the desired output.
I'm guessing you can't alter the format of the returned JSON. If that is the case, you don't have a nicely formed object hierarchy that you can use so instead you'll have to fall back to using (key, value). Below is a simple example of how you can accomplish what you are after.
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.countryChoices = [{
"INDIA": {
"KARNATAKA": ["BANGALORE", "UDUPI", "MANGALORE"],
"TELENGANA": ["HYDERABAD", "GUNTUR", "SHANKERPALLY"]
},
"USA": {
"CALIFORNIA": ["SAN JOSE", "SAN HOSE", "NEW YORK"],
"FLORIDA": ["MIAMI", "DENVER"],
"INDIAPOLIS": ["INDIANA", "MASACHUTTEUS"]
},
"AUSTRALIA": {
"NEW SOUTH WALES": ["SYDNEY", "BRISBANE"],
"QUEENSLAND": ["PERTH", "VICTORIA"],
"WESTERN AUSTRALIA": ["MELBOURNE", "MCG"]
}
}];
$scope.selectedCountry = {};
$scope.selectedState = {};
$scope.selectedCity = '';
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div>
<select ng-model="selectedCountry" ng-options="value as key for (key, value) in countryChoices[0]"></select>
</div>
<div>
<select ng-model="selectedState" ng-options="value as key for (key,value) in selectedCountry"></select>
</div>
<div>
<select ng-model="selectedCity" ng-options="value as value for value in selectedState"></select>
</div>
</div>
In order for that to work, your json data should be like this:
[{
country: "INDIA",
states: [
{
"KARNATAKA": {
cities: ["BANGALORE", "UDUPI", "MANGALORE"]
}
}
}]
Hope it helps...

i need to given state and district details in same select box with ngFor angular 5

This is my json value,
{
"location": [{
"state": "state1",
"cities": [{
"city1": "city1"
},
{
"city2": "city2"
}
]
},
{
"state": "state2",
"cities": [{
"city1": "city1"
},
{
"city2": "city2"
},
{
"city3": "city"
}
]
}
]
}
sample output in select box:
state1 - state name - parent
city1 - city name - child
city2
state2 - state name - parent
city1 - city name - child
city2
city3
<select>
<option *ngFor="let locations of location">
{{locations.state}}{{locations.cities.citiname}}
</option>
<select>
it is not multiselect. it is like grouping by state under cities.
Thanks in advance.
You can use optgroup attribute for select element.
<select>
<optgroup *ngFor="let location of locations" [label]="location.state">
<option *ngFor="let city of location.cities">{{Utils.keys(city)[0]}}</option>
</optgroup>
</select>
Typescript
Utils = {
keys : Object.keys
}
You cannot use directly Object.keys because Object is a part of window/global and angular cannot evaluate that expression.

Only get first level object

I have my object selected via a selection box printed out on the page as the user selects the option.
However it currently prints the parent object and all other objects nested within the parent object.
A example of my array
$scope.productsandformats = [
{
"Pname": "parent",
"format": [
{"Fname": "child", "id": "4"},
{"Fname": "second child", "id": "5"}
]
}
];
My angular and html selection box
<select ng-model="formData.ProductType"
ng-options="product.Pname for product in productsandformats">
<option value="">- Please Choose -</option>
</select>
<pre class="col-sm-12 ng-binding">
{{ formData }}
</pre>
so currently when I select parent I get
{"ProductType":{"Pname":"parent","format":[{"Fname":"child","id":"4"},{"Fname":"second child","id":"5"}]}}
What I expect to see
{"ProductType":{"Pname":"parent"}}
What I need
I just want to see the Pname so the top level objects eg parent, parent2, parent3 so on not the children objects.
How can I alter this to just show the top level object?
#George answer almost works
difficulty my second drop down should be populated with the child objects of the selected parent and the final string should read as following if select parent from first option then second child from second option.
ProductType: Pname: parent, formatType: Fname: child
**Angular code for both boxes, second populated with children of the selected parent **
<select ng-model="formData.ProductType"
ng-options="product.Pname for product in productsandformats">
<option value="">- Please Choose -</option>
</select>
<select ng-model="formData.formatType"
ng-options="format.Fname for format in formData.ProductType.format"
ng-if="formData.ProductType">
<option value="">- Please Choose -</option>
</select>
If you read the documentation on ngOptions you can use select as to specify was object gets set on the ngModel
For the second select I suggest having an ng-change on the first select to store that object in another variable on the scope that you can use for the second select.
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.productsandformats = [{
"Pname": "parent",
"format": [{
"Fname": "child",
"id": "4"
}, {
"Fname": "second child",
"id": "5"
}]
}];
$scope.formats = [];
$scope.productTypeChange = function() {
$scope.formats = $scope.productsandformats.find(ps => ps.Pname == $scope.formData.ProductType.Pname);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<select ng-model="formData.ProductType.Pname" ng-change="productTypeChange()" ng-options="product.Pname as product.Pname for product in productsandformats">
<option value="">- Please Choose -</option>
</select>
<select ng-model="formData.formatType" ng-options="format.Fname for format in formats.format" ng-if="formData.ProductType.Pname">
<option value="">- Please Choose -</option>
</select>
<pre class="col-sm-12 ng-binding">
{{ formData }}
</pre>
</div>
</div>
You can access first level object like this
<div ng-repeat='p in formData.productType'>
{{p.pname}}
</div>

Set selection options depending on another select element's value in AngularJS

I nearly struggled as much naming this question as I am with the actual problem! I have two selects:
Select 1:
<select ng-change="bankSelected()" ng-model="user.bankName">
<option selected value="">Select</option>
<option ng-repeat="bank in banks" value="{{bank.name}}">{{bank.name}}</option>
</select>
Select 2:
<select ng-model="user.branch">
<option selected value="">Select</option>
<option ng-repeat="// what to do??"></option>
</select>
The 'bankSelected()' function in my controller:
$scope.bankSelected = function () {
console.log('Bank selected: ' + $scope.user.bankName);
}
I have a JSON file that I import all the bank objects from, here's an example:
{
"banks" : [
{
"name" : "Bank A",
"branches" : [
{
"name" : "Branch 1",
"code" : "1"
},
{
"name" : "Branch 2",
"code" : "2"
}
]
},
{
"name" : "Bank B",
"branches" : [
{
"name" : "Branch 3",
"code" : "3"
},
{
"name" : "Branch 4",
"code" : "4"
},
{
"name" : "Branch 5",
"code" : "5"
}
]
}
]
}
The JSON that I'm actually using though is about 1000 lines long. So my problem, is that if the user selects 'Bank A' in the first select box, I want the second select box to display 'Branch 1' and 'Branch 2'. Likewise if the user selects 'Bank B', I want to display 'Branch 3', 'Branch 4', and 'Branch 5'. If the user has not selected anything in the first select (e.g. no Bank selected), then the second select (branches) shouldn't contain anything. I'm sure you understand what I'm getting at?
How can I make this happen in AngularJS?
bank ng-repeat
<select ng-model="user.bankName">
<option selected value="">Select</option>
<option ng-repeat="bank in banks" value="{{bank.name}}">{{bank.name}}</option>
</select>
branch ng-repeat
<select ng-model="user.branch" ng-show="user.bankName">
<option selected value="">Select</option>
<option ng-repeat="branch in getBranches(user.bankName)" value="{{branch.code}}">{{ branch.name }}</option>
</select>
source of the branch repeat is assign to getBranches() function in the scope and here we pass the bank name which selected before.
in that function
$scope.getBranches = function(selectedBank) {
// get the selected bank object from the banks array
var filteredBank = $filter('filter')($scope.banks, selectedBank);
// return the branches of the selected bank
return filteredBank[0].branches;
};
don't forget to inject the $filter service as below
app.controller('CtrlName', function($scope, $filter) {...
here is the DEMO
If you can change your select to something like below it will be more cleaner :)
this will select the whole object of the selected option.
<select ng-model="user.bankName" ng-options="bank.name for bank in banks">
</select>
here we can use selected bank object to get the branches as user.bankName.branches.
<select ng-model="user.branch" ng-if="user.bankName" ng-options="branch.code as branch.name for branch in user.bankName.branches">
</select>
so we can get rid of the getBranches().
here is the DEMO

Angular driving one Select from another. Second select showing only a single result

I have the code below and I am attempting to drive one select box from another but the subcategory select only shows one item at a time and it should show every item that has the parent category. For example, if Truck is selected in Category, Subcategory should show Telescope and Hazmat and If I choose Van, then subcategory would only have mini. What the heck am I doing wrong here?
<select name="Category" ng-model="selectedCategory"
ng-options="item.id as item.name for item in categories | unique:'name' | orderBy:'name'" ng-change="">
<option value="" disabled selected>All Categories</option>
</select>
<select name="SubCategory" ng-model="selectedSubCategory" ng-options="item.id as item.subCategory for item in categories | filter:selectedCategory | orderBy:'subCategory'" >
<option value="" disabled selected>All SubCategories</option>
</select>
$scope.selectedCategory = null;
$scope.categories = [];
$scope.$watch('selectedCategory', function() {
$scope.selectedSubCategory = null;
});
$http({
method: 'GET',
url: 'test.php?option=com_ajax&type=Category&format=json',
data: { }
}).success(function (result) {
$scope.categories = result;
});
...
{
"id": "1",
"name": "Truck",
"subCategory": "Telescope"
},
{
"id": "2",
"name": "Truck",
"subCategory": "Hazmat"
},
{
"id": "3",
"name": "Van",
"subCategory": "Mini"
}
Looking into the code I guess the ngModel selectedCategory will have the item.id and id is unique for all the items but you want to filter by item.name in the subcatagories
So one way will be to modify the parent select as below,
<select name="Category" ng-model="selectedCategory"
ng-options="item.name as item.name for item in categories">
<option value="">All Categories</option>
</select>
Sample Demo: http://plnkr.co/edit/E45B50eFmxRaep5WiWKW?p=preview

Categories