Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

filter multiple fields using single input in AngularJS

I have a JSON object which is as follows

[{
    "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",
}]

I'm populating this data in view using ng-repeat.

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

Now I have an input box which I'd like to use to filter these names. I would like to use same input box to filter firstName and then filter lastName and don't filter anything else (eg. address).

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

Any idea how can I achieve it?

like image 513
Kuldeep Daftary Avatar asked Jan 07 '14 17:01

Kuldeep Daftary


2 Answers

Try this fiddle.

Essentially, I created a sub-structure for filtering within the data structure being displayed and filter only on that property (e.g. '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",            
    }
}];
}

You could simplify this even further for this case by putting all the names into one field (see 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"
    }]
}
like image 158
Trevor Avatar answered Nov 16 '22 00:11

Trevor


Considering that your user have this form:

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

If you want to search one of your user by his firstname, his lastname or both at the same time, you need to concat them together.

$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;
};

This function will return true if the current user satisfies your query and false if not. Inside of the function, I recommend to put your query in lowercases so you won't have to deal with the uppercases your user will enter in the search input.

Here is the 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>

This technic will only work if you try to search Angelina Jolie, Angelina, Jolie or even InA JOLIe (why not after all). If you try to search first the lastname like Jolie Angelina, it won't work. You can easily fix it by creating a second fullname in your function (e.g. a reverseFullname), concat in first the lastName and then the firstName and test it just like the first fullname string.

like image 22
Jean-Baptiste Louazel Avatar answered Nov 16 '22 01:11

Jean-Baptiste Louazel