Daniel Pinkpank Daniel Pinkpank - 3 months ago 26
AngularJS Question

Multiple filter values in one input field (seperated by space) with AngularJS

I have an array of persons wich I display like that:

<div ng-repeat="person in persons | filterBy:filter">
<div>{{person.name}}</div>
<div>{{person.age}}</div>
<div>{{person.city}}</div>
<div>{{person.country}}</div>
</div>


My filter is bound to a text input field.

Now I would like to type multiple search criterias into my input field (seperated by space). Something like "peter 28 berlin". Now Angular should only display persons named "peter" at the age of "28" livin in "berlin".

Is there an easy way to achieve that?

Answer

You will have to write custom filter if you want this functionality. It's not really that complicated though.

var app = angular.module('filter', [])
app.controller('MainController', function($scope) {
    $scope.persons = [
        {name: 'Peter', age: 28, city: 'Berlin'},
        {name: 'Malik', age: 23, city: 'London'},
        {name: 'Sofia', age: 31, city: 'Paris'},
    ];
});


// filterBy implementation
app.filter('filterBy', function() {
    return function(array, query) {
    
        var parts = query && query.trim().split(/\s+/),
            keys = Object.keys(array[0]);
    
        if (!parts || !parts.length) return array;
    
        return array.filter(function(obj) {
            return parts.every(function(part) {
                return keys.some(function(key) {
                    return String(obj[key]).toLowerCase().indexOf(part.toLowerCase()) > -1;
                });
            });
        });
    };
});
.section {padding: 10px; margin-top: 10px; background: #EEE;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.js"></script>
<div ng-app="filter" ng-controller="MainController">
    <input type="text" ng-model="filter">
    <div class="section" ng-repeat="person in persons | filterBy:filter">
        <div>{{person.name}}</div>
        <div>{{person.age}}</div>
        <div>{{person.city}}</div>
    </div>
</div>