0

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!!

2
  • Can you show LocationList data? There can be better, efficient way to solve your issue (By searching inside object) without even writing those filter functions. Commented Aug 3, 2017 at 16:51
  • Here is a sample of 2 of the objects in the list. but again there are about 1400 in the list. @Shantanu [{"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}, Commented Aug 3, 2017 at 17:26

2 Answers 2

1

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>

Sign up to request clarification or add additional context in comments.

Comments

1

See this Plunker, i had to change the values of country and region to differentiate since the values are same in both the objects.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.