Reputation: 4318
I have taken the example from Angular documentation into a Plunker for a quick demonstration of what I am trying to do. What I have is a name and lastName as part of an object in array. When I start to filter the input, it works well until I start to type the lastName after I have typed the name. How would I go about having it so that the search results would include the name and the lastName? I have been stumped on this and can't get past figuring this out so I am looking for a little help.
<div ng-controller="repeatController">
I have {{friends.length}} friends. They are:
<input type="search" ng-model="q" placeholder="filter friends..." aria-label="filter friends" />
<ul class="example-animate-container">
<li class="animate-repeat" ng-repeat="friend in friends | filter:q as results">
[{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
</li>
<li class="animate-repeat" ng-if="results.length === 0">
<strong>No results found...</strong>
</li>
</ul>
</div>
Here is the Plunker: https://plnkr.co/edit/SS2X2ZmguxNxQ4Txz3BN
Thank you in advance for any help given.
EDIT: What I am looking for is that if I was to type John Doe, the result would not say "No results found". It works fine if I am typing in one property, but once I start to do the lastName, there are no results found.
Upvotes: 1
Views: 370
Reputation: 1509
To show the lastName, you can do the exact same thing as you're doing with both the friend's name
and age
.
<li class="animate-repeat" ng-repeat="friend in friends | filter:q as results">
[{{$index + 1}}] {{friend.name}} {{friend.lastName}} who is {{friend.age}} years old.
</li>
I've updated your plunkr: https://plnkr.co/edit/gocfrflA6VKUDBwBcYKK?p=preview
Edit: As you're also interested to search over a combination of multiple fields, you need to implement a custom filter function.
$scope.search = function (friend) {
var fullName = friend.name + ' ' + friend.lastName;
return !$scope.q || fullName.indexOf($scope.q) !== -1;
};
and
<li class="animate-repeat" ng-repeat="friend in friends | filter: search">
I've created a plunkr for this aswell: https://plnkr.co/edit/fr3XH3ghMw0hidceXDVx?p=preview
An even better approach would be to make use of a custom filter. Be sure to read: https://toddmotto.com/everything-about-custom-filters-in-angular-js/ and https://docs.angularjs.org/guide/filter
Upvotes: 3
Reputation: 3830
In another approach I'd like to modify the list which I'm iterating, friends
in your case.
<input type="search" ng-model="q" placeholder="filter friends..." aria-label="filter friends" />
<ul class="example-animate-container">
<!-- instead of using the list directly I'd like to call a function which would return me the filtered list, hence getFriends()-->
<li class="animate-repeat" ng-repeat="friend in getFriends()">
[{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
</li>
<li class="animate-repeat" ng-if="getFriends().length === 0">
<strong>No results found...</strong>
</li>
</ul>
Now in my controller I'd implement the function as following-
$scope.$watch('q', function () {
$scope.getFriends = function(){
var friends = $scope.friends;
var params;
if( $scope.q.indexOf(' ') > -1 ){
var q = $scope.q.split(" ");
params = {
name: q[0],
lastName: q[1]
};
}
else{
params = $scope.q;
}
// You can modify params for even more powerful filter... if you need actually...
return $filter("filter")(friends, params);
}
}
I use this approach so that I've full access to the filter right in my controller. Most of the cases I need this type of customised filter not more than once, so I'd rather put them in my controller.
One tiny glitch though, you need to define $scope.q
somewhere in the controller, otherwise it'd through a Reference Error
https://plnkr.co/edit/7FTgkXOtldihFBy7cuSP?p=preview
UPDATE
@FrederikPrijck guided me through a great example about how to eliminate calling this function in every digest cycle. I've updated my answer reflecting that. Another thing is I use this approach when I need very extensive control to my filter like you don't have room for multiple input field but you need to filter by multiple properties, or sometimes I needed to update the list based on $broadcast
. If you need to use a simple filter like this question, please use the accepted answer.
Upvotes: -1
Reputation: 95
**Hey i have changed json object of $scope.friends**
I have added one more key **fullName** now it will search on fullName
angular.forEach($scope.friends,function(value,key)
{
value['fullName'] = value.name +" " + value.lastName;
})
Upvotes: -1