angular filter in order by letter

2.7k views Asked by At

I am pretty new to angular. I am trying to add a filter parameter to my controller that will filter a search by every letter in a word, in order of letter. So imagine my data contained the following words: horses, oranges, terminator, Motorola, floral, orthopedic. When I searched for "or" in my search engine, all words would appear in the result because they all contain "or." Instead, I'd want a filter that filters my data in strict order of letter so I would only get "oranges" and "orthopedic"

This is my current filter in my controller:

$scope.activateFilter = function(textBoxValue) {
  $scope.$apply(function() {
    if ( textBoxValue=="") {
      $scope.pages = FacebookPage.userPages;
    } else {
      $scope.pages=$filter('filter')($scope.pages,{name:textBoxValue});
    }
  });
};

This is the HTML for the filtering in case it helps:

<div id="searchEngineController" ng-controller="SearchEngineController">
    <ul class="rig">
        <li ng-repeat="page in pages">
            <a ng-click="pageClick($index)">
                <img src= "{{page.image}}" class="img-responsive img-circle" height="140" width="240">
                <p style="font-size:25px; text-align:center">{{page.name}}<p>
            </a>
        </li>
    </ul>
</div>

And my JS function:

 pagesSearchBar.pageValueDidChange = function(value) {
    angular.element(document.getElementById('searchEngineController')).scope().activateFilter(value);
 };

Thanks!

4

There are 4 answers

13
Tomas On BEST ANSWER

You are re-inventing the wheel. Checkout angular build-in filter for ng-repeat

https://docs.angularjs.org/api/ng/directive/ngRepeat

<li ng-repeat="page in pages | filter:x">

Reading your code more thoroughly I think you have some misunderstanding of angular logic there as well. For example, you don't need extra function to detect search change and then getting the scope from dom. You could simply do:

<input type="text" name="search" ng-change="activateFilter(this.value)">

Something like that

UPDATE

So If I understand correctly now, you will want to display only one result for a filter. You could achieve that by somehow combining the filter with limitTo (no time to fiddle around now)

Or even as a temporary solution use css:

.list.filtered .class-of-item {display:none;}
.list.filtered .class-of-item:first-child {display:block;}

UPDATE 2

Ok, now I understand, so you want to use strict filtering in the way that only items starting with the search phrase show up. Angular is ready for that too, check below snippet

angular.module('filterApp',[]);

angular.module('filterApp').controller('MainCtrl',['$scope',function($scope){
  $scope.items = ['Orange','Orangutan','Words','Orchid'];
  $scope.customComparator = function(actual, expected){
    return (actual.toLowerCase().indexOf(expected.toLowerCase()) === 0);
  }
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="filterApp">
  <div ng-controller="MainCtrl">
    <ul>
      <li ng-repeat="item in items | filter:'or':customComparator">{{item}}</li>
    </ul>
  </div>
</div>

Comparator reference: https://docs.angularjs.org/api/ng/filter/filter

1
Kumar Sambhav On

There a filter in AngularJS named 'filter' that can make your life a lot easier in lesser code.

You can fine tune it to perform search on all fields in the object or you can restrict the search on some specific fields.

Copy pasting example from the link mentioned above:-

<div ng-init="friends = [{name:'John', phone:'555-1276'},
                         {name:'Mary', phone:'800-BIG-MARY'},
                         {name:'Mike', phone:'555-4321'},
                         {name:'Adam', phone:'555-5678'},
                         {name:'Julie', phone:'555-8765'},
                         {name:'Juliette', phone:'555-5678'}]"></div>

<label>Search: <input ng-model="searchText"></label>
<table id="searchTextResults">
  <tr><th>Name</th><th>Phone</th></tr>
  <tr ng-repeat="friend in friends | filter:searchText">
    <td>{{friend.name}}</td>
    <td>{{friend.phone}}</td>
  </tr>
</table>
<hr>
<label>Any: <input ng-model="search.$"></label> <br>
<label>Name only <input ng-model="search.name"></label><br>
<label>Phone only <input ng-model="search.phone"></label><br>
<label>Equality <input type="checkbox" ng-model="strict"></label><br>
<table id="searchObjResults">
  <tr><th>Name</th><th>Phone</th></tr>
  <tr ng-repeat="friendObj in friends | filter:search:strict">
    <td>{{friendObj.name}}</td>
    <td>{{friendObj.phone}}</td>
  </tr>
</table>
3
Vaibhav Pachauri On

Use something like below :

<input type="search" data-ng-model="searchName">
<li ng-repeat="list in lists | filter:searchName">{{list}}</li>

This filter is already provided by angular.js which itself is very powerful and quite robust.

I have made this plnkr which has lot more features. You might find this helpful.

1
Sathiyaraj On
$scope.pages=$filter('filter')($scope.pages,{name:textBoxValue},true);

This above line will change it

$scope.pages = $filter('filter')($scope.pages,function(index, value){
 return value === textBoxValue;
},true);