AngularJS filter for multiple strings

后端 未结 6 919
时光取名叫无心
时光取名叫无心 2020-12-14 23:32

I\'m working through the AngularJS tutorial, and understand the basics of

However, the out of the box implementation seems limited to just filter the list of items

相关标签:
6条回答
  • 2020-12-14 23:59

    Not a one liner but still quite short and fun

    app.filter("filterall",function($filter) {
        return function(arr,t){
            (t?t.split(/\s+/):[]).forEach(function(v){ arr = $filter('filter')(arr,v); });
            return arr;
        };
    });
    
    0 讨论(0)
  • 2020-12-15 00:06

    Here's my version. It uses JonoWilko's method of using the built in filterFilter combined with surfbud's AND/OR flag (defaulted to "AND").

    JavaScript

    angular.module('filters').filter('searchFilter', function($filter) {
    
        return function(inputArray, searchText, booleanOp) {
            booleanOp = booleanOp || 'AND';
    
            var searchTerms = (searchText || '').toLowerCase().split(/\s+/);
    
            if (booleanOp === 'AND') {
                var result = inputArray;
                searchTerms.forEach(function(searchTerm) {
                    result = $filter('filter')(result, searchTerm);
                });
    
            } else {
                var result = [];
                searchTerms.forEach(function(searchTerm) {
                    result = result.concat($filter('filter')(inputArray, searchTerm));
                });
            }
    
            return result;
        };
    });
    

    CoffeeScript

    angular.module('filters').filter 'searchFilter', ($filter)->
    
        (inputArray, searchText='', booleanOp = 'AND')->
            searchTerms = searchText.toLowerCase().split(/\s+/)
    
            if booleanOp is 'AND'
                result = inputArray
                searchTerms.forEach (word)->
                    result = $filter('filter')(result, word)
    
            else
                result = []
                searchTerms.forEach (word)->
                    result = result.concat $filter('filter')(inputArray, word)
    
            result
    

    'AND' Usage (default)

    <div ng-repeat="product in products | searchFilter: searchInputText"></div>
    

    'OR' Usage

    <div ng-repeat="product in products | searchFilter: searchInputText : 'OR'"></div>
    
    0 讨论(0)
  • 2020-12-15 00:10

    Some improvements to the above custom filter:

    Instead of using a loop within a loop, counts, and indexOf, this one uses regular expressions to achieve a logical AND and also a logical OR depending on the third argument to the filter (input array of strings, search terms, AND or OR).

    Have a look at the forked Fiddle with the two types of filter and results:

    http://jsfiddle.net/jonjon/Cx3Pk/23/

    angular.module('app', [])
        .filter("myFilter", function () {
        return function (input, searchText, AND_OR) {
            var returnArray = [],
                // Split on single or multi space
                splitext = searchText.toLowerCase().split(/\s+/),
                // Build Regexp with Logical AND using "look ahead assertions"
                regexp_and = "(?=.*" + splitext.join(")(?=.*") + ")",
                // Build Regexp with logicial OR
                regexp_or = searchText.toLowerCase().replace(/\s+/g, "|"),
                // Compile the regular expression
                re = new RegExp((AND_OR == "AND") ? regexp_and : regexp_or, "i");
    
            for (var x = 0; x < input.length; x++) {
                if (re.test(input[x])) returnArray.push(input[x]);
            }
            return returnArray;
        }
    });
    
    0 讨论(0)
  • 2020-12-15 00:10

    You can do a multiple word search on a object as follows:

    .filter("myFilter", function(){
        return function(input, searchText){
             var returnArray = [];
             var searchTextSplit = searchText.toLowerCase().split(' ');
            for(var x = 0; x < input.length; x++){
                 var count = 0;
                for(var y = 0; y < searchTextSplit.length; y++){
                    angular.forEach(input[x], function(item){
                        if(item.toLowerCase().indexOf(searchTextSplit[y]) !== -1){
                            count++;
                        }
                    });
    
                }
                if(count == searchTextSplit.length){
                     returnArray.push(input[x]);   
                }
            }
            return returnArray;
        }
    });    
    

    Working demo in js fiddle

    0 讨论(0)
  • 2020-12-15 00:18

    Please see surfbuds answer below as it is superior

    Just roll with your own filter:

    .filter("myFilter", function(){
        return function(input, searchText){
            var returnArray = [];
            var searchTextSplit = searchText.toLowerCase().split(' ');
            for(var x = 0; x < input.length; x++){
                var count = 0;
                for(var y = 0; y < searchTextSplit.length; y++){
                    if(input[x].toLowerCase().indexOf(searchTextSplit[y]) !== -1){
                        count++;
                    }
                }
                if(count == searchTextSplit.length){
                     returnArray.push(input[x]);   
                }
            }
            return returnArray;
        }
    });
    

    jsfiddle: http://jsfiddle.net/Cq3PF/

    This filter makes sure that all search words are found.

    0 讨论(0)
  • 2020-12-15 00:18

    Alternatively you could use the default Angular filter within your custom filter like so:

    angular.module('app').filter("multiWordFilter", function($filter){
        return function(inputArray, searchText){
            var wordArray = searchText ? searchText.toLowerCase().split(/\s+/) : [];
            var wordCount = wordArray.length;
            for(var i=0;i<wordCount;i++){
                inputArray = $filter('filter')(inputArray, wordArray[i]);
            }
            return inputArray;
        }
    });
    

    This could be embellished further with user2005009's AND_OR comparator.

    0 讨论(0)
提交回复
热议问题