When I enter one word, it looks fine, but if you need to find, for example, by two values, for example Name and Country, then the filter is not looking. I understand that you need to write a custom filter. I rummaged everything I can not understand which way to look

<div class="gradientborder"> <input class="search" type="text" placeholder="$search" ng-model="searchPlayers" > </div> <div class="items" ng-controller="ctrl2"> <div ng-repeat="todo in players | filter:searchPlayers" class="item"> <div class="player-name"> {{todo.name}} </div> <div class="player-info"> id: {{todo.id}}, position: {{todo.position}}, jerseyNumber: {{todo.jerseyNumber}}, dateOfBirth: {{todo.dateOfBirth}}, nationality: {{todo.nationality}}, contractUntil: {{todo.contractUntil}} , <br> marketValue: {{todo.marketValue}} </div> </div> </div> 

js file below

 var SearchApp = angular.module('SearchApp',[]); SearchApp.controller('ctrl2', function($scope, $http) { $http.get('players.json') .then(function(res){ $scope.players = res.data; }); }); 

Sample data

 { "id":242, "name":"Abdul Rahman Baba", "position":"Left-Back", "jerseyNumber":6, "dateOfBirth":"1994-07-02", "nationality":"Ghana", "contractUntil":"2020-06-30", "marketValue":"10,000,000  " }, { "id":435, "name":"Falcao", "position":"Centre Forward", "jerseyNumber":9, "dateOfBirth":"1986-02-10", "nationality":"Colombia", "contractUntil":"2016-06-30", "marketValue":"35,000,000  " }, 

Need to find: Abdul Rahman Baba Left-back. you need to search all through one input. Search must find this player here. Either this: Need to find: Left-back England The search should find all England players in the Left-back position

  • vicatto.com/json - test server - Egor Krotenko
  • does not give an answer to how to find for example John London - Egor Krotenko
  • You look at the vidos there - very well explained there - user33274
  • 6
    So, this is a test task and you need to do it yourself !!! We will evaluate your ability to use Stackoverflow separately :) - user215399

2 answers 2

The bottom line is that you need to implement 2 filters technically, not just one. Because There is a selection of two values: by name and by country.

How to implement collection filtering by more than one property

The variable for the filter ( searchPlayers ) must be an object with properties that match by name with the fields that should be filtered.

 <input type="text" ng-model="searchPlayers.name"> <input type="text" ng-model="searchPlayers.city"> <div ng-repeat="player in players | filter:searchPlayers"> <p> Имя: {{player.name}} Страна: {{player.city}} </p> </div> 

UPDATE

"Crutch option" to use one input field

For each element of the collection, add a property that contains all the values ​​that should be searched.

For example:

 players.push({ name: 'Вася', surname: 'Пупкин', sity: 'Москва', searchString: 'Вася Пупкин Москва' }); 

Then, filter exactly by the searchString property searchString

I am NOT a supporter of this option, because there is a duplication of information that a priori wrong approach to solving problems.

The best options are:

  • creating a filter for each filter
  • write a function that will parse the string entered into one input and, for some specific conditions, assign values ​​to the various necessary Saint-you objects for filtering.
  • <input type = "text" ng-model = "searchPlayers.name"> <input type = "text" ng-model = "searchPlayers.city"> - but this is how it turns out to be two inputs? Do I need one, or do I not understand something? - Yegor Krotenko
  • @ YegorKrotenko I wrote to you how to do filtering by more than one property - a sufficient basis for solving your problem. Data assignment can also occur in js-code ($ scope.searchPlayers.name). In your case, you will need a function that parses the data entered in the input, and in some way assigns some values ​​to certain Saint-you $ scope.searchPlayers. 1) The simplest option is to have input for each filter 2) The most difficult (with 1 input) is the development of the string parser 3) Not the most correct, but solving the problem (with 1 input) - see the updated answer. - RostD
  • thanks, I will think - Yegor Krotenko

The filtering task, when using only one input field, becomes quite non-trivial. Since it is not known how to break the entered string to search for specific fields.

For example:

Permission - Abdul Rahman Ghana
How to determine that Ghana is not a part of a name, but a nationality?

In the simplest case, you can break into spaces and search for the obtained substrings, but this does not give any indication as to which of the fields should be checked.

For example:

 var SearchApp = angular.module('SearchApp', []); SearchApp.controller('ctrl2', function($scope, $http) { $scope.players = [{ "id": 242, "name": "Abdul Rahman Baba", "position": "Left-Back", "jerseyNumber": 6, "dateOfBirth": "1994-07-02", "nationality": "Ghana", "contractUntil": "2020-06-30", "marketValue": "10,000,000" }, { "id": 435, "name": "Falcao", "position": "Centre Forward", "jerseyNumber": 9, "dateOfBirth": "1986-02-10", "nationality": "Colombia", "contractUntil": "2016-06-30", "marketValue": "35,000,000" }, { "id": 435, "name": "Falcao", "position": "Left", "jerseyNumber": 9, "dateOfBirth": "1986-02-10", "nationality": "Colombia", "contractUntil": "2016-06-30", "marketValue": "35,000,000" }, { "id": 435, "name": "Falcao", "position": "Left", "jerseyNumber": 9, "dateOfBirth": "1986-02-10", "nationality": "Colombia", "contractUntil": "2016-06-30", "marketValue": "35,000,000" }]; $scope.search = function(o, i, a) { if (!$scope.searchPlayers) return true; var filter = $scope.searchPlayers.split(' '); var keys = Object.keys(o); return filter.every(function(f) { return keys.some(function(key) { return !key.startsWith('$$') && (this[key] + '').indexOf(f) > -1; }, o); }); }; }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script> <div ng-app="SearchApp" ng-controller="ctrl2"> <div class="gradientborder"> <input class="search" type="text" placeholder="$search" ng-model="searchPlayers"> </div> <div class="items" ng-controller="ctrl2"> <div ng-repeat="todo in players | filter:search" class="item"> <div class="player-name"> {{todo.name}} </div> <div class="player-info"> id: {{todo.id}}, position: {{todo.position}}, jerseyNumber: {{todo.jerseyNumber}}, dateOfBirth: {{todo.dateOfBirth}}, nationality: {{todo.nationality}}, contractUntil: {{todo.contractUntil}} , <br>marketValue: {{todo.marketValue}} </div> </div> </div> </div>