web-dev-qa-db-ja.com

AngularJSの単一の入力を使用して複数のフィールドをフィルタリングする

私は次のようなJSONオブジェクトを持っています

[{
    "id": 1,
    "firstName": "Jennifer",
    "middleName": null,
    "lastName": "Aniston",
    "address": "New York City",
}, {
    "id": 2,
    "firstName": "Angelina",
    "middleName": null,
    "lastName": "Jolie",
    "address": "Beverley Hills",
}, {
    "id": 3,
    "firstName": "Emma",
    "middleName": null,
    "lastName": "Watson",
    "address": "London",
}]

Ng-repeatを使用して、このデータをビューに入力しています。

<td ng-repeat="row in list | filter:filterBeauties">
{{row.firstName}} {{row.lastName}}
</td>

これで、これらの名前をフィルタリングするために使用したい入力ボックスができました。同じ入力ボックスを使用してfirstNameをフィルタリングし、次にlastNameをフィルタリングし、他には何もフィルタリングしません(アドレスなど)。

<input type="text" placeholder="Filter" ng-model="filterBeauties.firstName">

どうすればそれを達成できますか?

6
Kuldeep Daftary

さて、これは私がそれを解決するためにしたことです。

Jsonオブジェクトに新しいアイテムを追加し( angular.forEach 関数を使用)、それによってフィルタリングしました。

$scope.list = beauties.query(function(response) {
    angular.forEach(response, function(value, key) {
          var fullName = value.firstName + ' ' + value.lastName;
          $scope.list[key].fullName = fullName;
   });
});

入力ボックスコード:

<input type="text" placeholder="Filter" ng-model="filterBeauties.fullName">

ng-repeat

<td ng-repeat="row in list | filter:filterBeauties">
{{row.firstName}} {{row.lastName}}
</td>
4
Kuldeep Daftary

これを試してください フィドル

基本的に、表示されているデータ構造内でフィルタリングするためのサブ構造を作成し、そのプロパティでのみフィルタリングします(例: 'filterTerms'):

HTML:

<div ng-controller="MyCtrl">
   <input type="text" ng-model="search.filterTerms">
   <table border="1">
      <tr ng-repeat="row in list | filter:search">
         <td>{{row.firstName}} {{row.lastName}}</td>
      </tr>
   </table>
</div>

JavaScript:

var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.list = [{
    "id": 1,
    "address": "New York City",
    "firstName": "Jennifer",
    "middleName": null,
    "lastName": "Aniston",
    "filterTerms": {
        "firstName": "Jennifer",
        "middleName": null,
        "lastName": "Aniston",
    }
}, {
    "id": 1,
    "address": "New York City",
    "firstName": "Jennifer",
    "middleName": null,
    "lastName": "Leela",
    "filterTerms": {
        "firstName": "Jennifer",
        "middleName": null,
        "lastName": "Leela",            
    }
}, {
    "id": 2,
    "address": "Beverley Hills",
    "firstName": "Angelina",
    "middleName": null,
    "lastName": "Jolie",
    "filterTerms": {
        "firstName": "Angelina",
        "middleName": null,
        "lastName": "Jolie",            
    }
}, {
    "id": 3,
    "address": "London",
    "firstName": "Emma",
    "middleName": null,
    "lastName": "Watson",
    "filterTerms": {
        "firstName": "Emma",
        "middleName": null,
        "lastName": "Watson",            
    }
}];
}

この場合、すべての名前を1つのフィールドに入力することで、これをさらに単純化できます(fiddle here を参照してください:

HTML:

<div ng-controller="MyCtrl">
    <input type="text" ng-model="search.filterTerm" />
    <table border="1">
        <tr ng-repeat="row in list | filter:search">
            <td>{{row.first}} {{row.last}} {{row.address}}</td>
        </tr>
    </table>
</div>

JavaScript:

var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
    $scope.list = [{
        "id": 0, "first": "Jenny", "last": "Sorenson", "address": "123 W. Wallnut St.",
        "filterTerm": "Jenny Sorenson"
    },{
        "id": 0, "first": "Susan", "last": "Hinkle", "address": "456 W. Doorbell Dr.",
        "filterTerm": "Susan Hinkle"
    },{
        "id": 0, "first": "Rachel", "last": "Karlyle", "address": "789 W. Sunset Blvd.",
        "filterTerm": "Rachel Karlyle"
    },{
        "id": 0, "first": "Gwen", "last": "Lippi", "address": "0 W. Silly Cir.",
        "filterTerm": "Gwen Lippi"
    }]
}
6
Trevor

ユーザーがこのフォームを持っていることを考えると:

{
  "id": 2,
  "firstName": "Angelina",
  "middleName": null,
  "lastName": "Jolie",
  "address": "Beverley Hills"
}

ユーザーの1人をファーストネーム、ラストネーム、またはその両方で同時に検索する場合は、それらを連結する必要があります。

$scope.query = '';

$scope.search = function (user) {
  var query = $scope.query.toLowerCase(),
  fullname = user.firstName.toLowerCase() + ' ' + user.lastName.toLowerCase();

  if (fullname.indexOf(query) != -1) {
    return true;
  }
  return false;
};

この関数は、現在のユーザーがクエリを満たしている場合はtrueを返し、満たさない場合はfalseを返します。関数内では、クエリを小文字にすることをお勧めします。これにより、ユーザーが検索入力に入力する大文字を処理する必要がなくなります。

HTMLは次のとおりです。

<input type="text" placeholder="Search" ng-model="query">
<table>
   <tr ng-repeat="user in users | filter:search">
      <td>{{user.firstName}} {{user.lastName}}</td>
   </tr>
</table>

この手法は、Angelina JolieAngelinaJolie、さらにはInA JOLIeを検索しようとした場合にのみ機能します(結局のところ、そうではありません)。 Jolie Angelinaのような姓を最初に検索しようとすると、機能しません。関数に2番目のフルネーム(例:reverseFullname)を作成し、最初にlastName、次にfirstNameを連結して、最初のフルネーム文字列と同じようにテストすることで、簡単に修正できます。

6
jlouazel

3番目の引数をフィルター関数に渡すことができます。

$filter('filter')(list, {'firstName':search});

私は以下のようなことをしたでしょう:

<input type="text" ng-model="search">
<table border="1">
    <tr ng-repeat="row in list | filterBoth:search">
        <td>{{row.firstName}} {{row.lastName}}</td>
    </tr>
</table>

次に、カスタムフィルターを次のように記述します。

myApp.filter('filterBoth', function($filter) {
  return function(list, search) {
    if (!search) return list;

    var arrSearch = search.split(' '),
        lookup = '',
        result = [];

    arrSearch.forEach(function(item) {
      lookup = $filter('filter')(list, {'firstName': item});console.log(lookup);
      if (lookup.length > 0) result = result.concat(lookup);
    });

    return result;
  };
});

デモ: http://jsfiddle.net/wAp4S/1/

唯一の問題は、_.uniq underscore.jsメソッドを使用して簡単に修正できる2つの類似した配列を連結しているため、重複する行が発生することです。

3
codef0rmer

複雑なフィルターを作成する代わりに、angular-filterライブラリを試してください。ここでは、searchFieldフィルターが役立ちます。

https://github.com/a8m/angular-filter

[〜#〜]コントローラー[〜#〜]

$scope.users = [
  { first_name: 'Sharon', last_name: 'Melendez' },
  { first_name: 'Edmundo', last_name: 'Hepler' },
  { first_name: 'Marsha', last_name: 'Letourneau' }
];

[〜#〜] html [〜#〜]

<input ng-model="search" placeholder="search by full name"/>
<th ng-repeat="user in users | searchField: 'first_name': 'last_name' | filter: search">
  {{ user.first_name }} {{ user.last_name }}
</th>
<!-- so now you can search by full name -->

幸運を。

2
Akash