Reputation: 177
I have a list of about 1400 locations around the world and displaying them using ng-repeat. I want to have dropdowns to narrow the list down using the filter feature so I can only see locations in Region: Americas, Country:Canda for example. I have gotten the dropdown filters to work properly but my issue is changing the values of the dropdowns. If I select the Region option in the first dropdown, the country dropdown should only have countries in that Region.
Here is my Template:
Region:<select ng-model='RegionLocation.Region' ng-options="location.Region for location in RegionOptions.Regions"></select>
Country:<select ng-model='CountryLocation.Country' ng-options="location.Country for location in CountryOptions.Countries"></select>
<div>
<md-card data-ng-repeat="location in LocationCtrl.Locationlist | filter:RegionFilter | filter:CountryFilter ">
<md-card-content>
<h2>{{::location.LID}}</h2>
</md-card-content>
</md-card>
</div>
Here is my Controller.js
function LocationController(LocationList, $scope) {
var LocationCtrl = this;
LocationCtrl.Locationlist = LocationList;
LocationCtrl.Regions = filterRegions(LocationList);
LocationCtrl.Regions.unshift({
Region: 'Show All'
})
$scope.RegionOptions = {
Regions:LocationCtrl.Regions,
}
$scope.RegionLocation = {
Region: $scope.RegionOptions.Regions[0],
}
$scope.CountryOptions = {
Countries:getCountries()
};
$scope.CountryLocation = {
Country: $scope.CountryOptions.Countries[0]
};
$scope.RegionFilter = function (data) {
if($scope.RegionLocation.Region.Region == 'Show All'){
return true;
} else if(data.Region == $scope.RegionLocation.Region.Region){
return true;
} else{
return false;
}
};
$scope.CountryFilter = function (data) {
if($scope.CountryLocation.Country.Country == 'Show All'){
return true;
} else if(data.Country == $scope.CountryLocation.Country.Country){
return true;
} else{
return false;
}
};
function getCountries(){
LocationCtrl.Countries = filterCountries(LocationList);
LocationCtrl.Countries.unshift({
Country: 'Show All'
});
return LocationCtrl.Countries;
};
function filterRegions(arr) {
var f = []
return arr.filter(function(n) {
return f.indexOf(n.Region) == -1 && f.push(n.Region)
})
};
function filterCountries(arr){
var f = [];
return arr.filter(function(n) {
return f.indexOf(n.Country) == -1 && f.push(n.Country)
})
};
}
I also understand my code is not super clean nor simple so suggestions to simplify it are more than welcome.
Thank you!!
Upvotes: 0
Views: 1021
Reputation: 116
You were on the right track with using a filter on the ng-repeat, here is how I managed to get it working based of some mock data. Its really simple to get this done using a filter. I hope this helps.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $filter) {
$scope.name = 'Sup World';
$scope.list = [{
"LID": "AB02",
"City": "Calgary",
"State": "Alberta",
"Country": "Canada",
"Region": "Americas",
"Latitude": "XXXXXX",
"Longitude": "XXXXX"
}, {
"LID": "AB08",
"City": "Canmore",
"State": "Alberta",
"Country": "Canada",
"Region": "Americas",
"Latitude": "XXXXXX",
"Longitude": "XXXXXXX"
}, {
"LID": "AB09",
"City": "Cape Town",
"State": "Western Cape",
"Country": "South Africa",
"Region": "Africa",
"Latitude": "XXXXXX",
"Longitude": "XXXXXXX"
}, {
"LID": "AB12",
"City": "Eish",
"State": "Somewhere",
"Country": "Zimbabwe",
"Region": "Africa",
"Latitude": "XXXXXX",
"Longitude": "XXXXX"
}, {
"LID": "AB18",
"City": "Lusaka",
"State": "Zambia?",
"Country": "Zambia",
"Region": "Africa",
"Latitude": "XXXXXX",
"Longitude": "XXXXXXX"
}, {
"LID": "AB19",
"City": "Durban",
"State": "Kwazulu Natal",
"Country": "South Africa",
"Region": "Africa",
"Latitude": "XXXXXX",
"Longitude": "XXXXXXX"
}, {
"LID": "AB13",
"City": "Pretoria",
"State": "JoJo",
"Country": "South Africa",
"Region": "Africa",
"Latitude": "XXXXXX",
"Longitude": "XXXXXXX"
}];
$scope.region = [];
//get unique regions
$scope.regions = $filter('unique')($scope.list, "Region");
$scope.country = [];
//get unique countries
$scope.countries = $filter('unique')($scope.list, "Country");
});
app.filter('unique', function() {
return function(arr, field) {
var o = {},
i, l = arr.length,
r = [];
for (i = 0; i < l; i += 1) {
o[arr[i][field]] = arr[i];
}
for (i in o) {
r.push(o[i]);
}
return r;
};
})
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="[email protected]" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
Region:
<select ng-model='region' ng-options="location.Region for location in regions"></select>
Country:
<select ng-model='country' ng-options="location.Country for location in countries | filter:{'Region': region.Region }"></select>
<div>
<md-card data-ng-repeat="location in list | filter:{'Region':region.Region,'Country':country.Country} ">
<md-card-content>
<h2>{{::location.LID}}</h2>
</md-card-content>
</md-card>
</div>
</body>
</html>
Upvotes: 1