Marc Rasmussen
Marc Rasmussen

Reputation: 20555

angular ng-repeat searching specific fields only

This must be very common however ive been unable to find an answer (so i am hoping you guys can help)

For the purpose of this question i have created the following fiddle:

HTML:

    <div ng-controller="MyCtrl">
  <div>
      <input type="text" ng-model="search.$"/>
  </div>
  <table>
    <thead>
      <th>Name</th>
      <th>Street</th>
      <th>Number</th>
    </thead>
    <tbody>
      <tr ng-repeat="item in tableData |filter:search">
        <td>{{item.name}}</td>
        <td>{{item.street}}</td>
        <td>{{item.number}}</td>
      </tr>
    </tbody>
  </table>

</div>

JavaScript:

var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
  $scope.tableData = [];
  for (i = 0; i < 100; i++) {
    $scope.tableData.push({
      id: i,
      name: generateRandomName(),
      street: generateRandomName(),
      number: generateRandomNumber()
    })
  }

  function generateRandomName() {
    var length = 4;
    var charset = "abcdefghjknpqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";

    var retVal = "";
    for (var i = 0, n = charset.length; i < length; ++i) {
      retVal += charset.charAt(Math.floor(Math.random() * n));
    }

    return retVal;
  }

  function generateRandomNumber() {
    return Math.floor(Math.random() * 10);
  }
}

Fiddle can be found here: Fiddle

Now let me explain the issue.

As you can see the object consists of four fields in this case: id,name,street,number

However in our table we are not showing the field id

We have added all of these objects to our tableData array. in order to filter / search our table we have created an input field:

      <input type="text" ng-model="search.$"/>

Notice the ng-model="search.$" Now with this single text input we wish to search the table. However something is strange (from the user's perspective):

enter image description here

We search for the number 95 however a result displays that seems to be not connected with our search.

Problem is that search.$ searches the full object even if the values are not displayed in the table. The result showed in the picture above is actually the id field of the object that has been found. Since the maximum street number is 10 any search for a number above 10 would result in incorrect results.

So my question is how can you fix this? how can you with a single text input limit search to specific fields in the object?

Upvotes: 1

Views: 1352

Answers (2)

synh
synh

Reputation: 186

I think you need define own comparator:

{{ filter_expression | filter : expression : comparator}}

see filter

Upvotes: 1

Sharan De Silva
Sharan De Silva

Reputation: 608

Have your search variable inside controller

var myApp = angular.module('myApp', []);

//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});

function MyCtrl($scope) {

 $scope.search = "";

  $scope.tableData = [];
  for (i = 0; i < 100; i++) {
    $scope.tableData.push({
      id: i,
      name: generateRandomName(),
      street: generateRandomName(),
      number: generateRandomNumber()
    })
  }

  function generateRandomName() {
    var length = 4;
    var charset = "abcdefghjknpqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";

    var retVal = "";
    for (var i = 0, n = charset.length; i < length; ++i) {
      retVal += charset.charAt(Math.floor(Math.random() * n));
    }

    return retVal;
  }

  function generateRandomNumber() {
    return Math.floor(Math.random() * 10);
  }


}

And Filter based on the search value,

<div ng-controller="MyCtrl">
  <div>
      <input type="text" ng-model="search"/>
  </div>
  <table>
    <thead>
      <th>Name</th>
      <th>Street</th>
      <th>Number</th>
    </thead>
    <tbody>
      <tr ng-repeat="item in tableData | filter:{name:search}">
        <td>{{item.name}}</td>
        <td>{{item.street}}</td>
        <td>{{item.number}}</td>
      </tr>
    </tbody>
  </table>

</div>

Upvotes: 2

Related Questions