Steve
Steve

Reputation: 14922

AngularJS filter repeater with multiple values

I have a repeater which I need to filter by the text entered into a text field, so I have done this

<tr ng-repeat="i in filteredItems = (iso3166 | filter: {alpha_2: countryQuery})">

The data is a json array of objects, $scope.iso3166:

  [{
  "name": "Afghanistan",
  "alpha_2": "AF",
  "alpha_3": "AFG",
  "country-code": "004",
  "iso_3166-2": "ISO 3166-2:AF",
  "region": "Asia",
  "sub-region": "Southern Asia",
  "region-code": "142",
  "sub-region-code": "034",
  "license": "unclassified",
  "prohibited": "unclassified",
  "size": "unclassified"
}, ...

So you can type "af" and the table filters to show Afghanistan.

Now I need to have what is typed into the field return matches not just against the alpha_2 key but the name one as well. For example, "af" should match not just "Afghanistan" but also "Central African Republic".

I looked at the Angular 1.4.1 docs and saw the comma method, but it seems to perform an AND comparison. As in

<tr ng-repeat="i in filteredItems = (iso3166 | filter: {alpha_2: countryQuery, name: countryQuery })">

Is there a way do do an "or" in this case, so that whatever is typed filters to any items where the query is in "alpha_2" or "name"?

UPDATE: If anyone is curious, I wound up using a filter as suggested in an answer below:

  $scope.countryFilter = function (value) {
    if (angular.isUndefined($scope.countryQuery) || $scope.countryQuery === '') {
      return true;
    }
    return value.name.indexOf($scope.countryQuery) >= 0 || value.alpha_2.indexOf($scope.countryQuery) >= 0;
  };

Upvotes: 0

Views: 395

Answers (2)

Rob
Rob

Reputation: 1860

You can apply properties to the ng-repeat filter like this:

https://jsfiddle.net/pzek3tmy/

Controller

function Controller($scope) {
      var vm = this;

      vm.regions = [{
        "name": "Afghanistan",
        "alpha_2": "AF",
        "alpha_3": "AFG",
        "country-code": "004",
        "iso_3166-2": "ISO 3166-2:AF",
        "region": "Asia",
        "sub-region": "Southern Asia",
        "region-code": "142",
        "sub-region-code": "034",
        "license": "unclassified",
        "prohibited": "unclassified",
        "size": "unclassified"
      }, {
        "name": "Germany",
        "alpha_2": "GN",
        "alpha_3": "AFG",
        "country-code": "004",
        "iso_3166-2": "ISO 3166-2:AF",
        "region": "Asia",
        "sub-region": "Europe",
        "region-code": "143",
        "sub-region-code": "034",
        "license": "unclassified",
        "prohibited": "unclassified",
        "size": "unclassified"
      }];
    }

HTML

<div ng-controller="Controller as ctrl">
  <input type="text" ng-model="region_filter">
  <ul>
    <li ng-repeat="region in ctrl.regions | filter:{'alpha_2':region_filter} | filter:{'name':region_filter}">{{region.name}}       </li>
  </ul>
</div>

Upvotes: 0

Austin
Austin

Reputation: 1291

Instead of doing it this way, you could specify the name of a function to filter the results and then implement the filtering logic in your controller.

<tr ng-repeat="i in filteredItems = (iso3166 | filter: filterFn)">

In controller:

scope.filterFn = function(item) {
    if(//item meets criteria) {
        //returning true will put the item into the ng-repeat data
        return true;
    }
    return false;
}

Upvotes: 2

Related Questions