Filter by multiple columns with ng-repeat

前端 未结 8 1474
小鲜肉
小鲜肉 2020-11-30 12:16

I\'m wondering if there\'s an easy way in Angular to filter a table using ng-repeat on specific columns using or logic, rather than and

相关标签:
8条回答
  • 2020-11-30 12:45

    Use this to search on All Columns (can be slow): search.$ AngularJS API: filter

    Any Column Search:
    <input ng-model="search.$"> 
    <table>
    <tr ng-repeat="friendObj in friends | filter:search:strict">
    ...
    
    0 讨论(0)
  • 2020-11-30 12:48

    It's not hard to create a custom filter which allows you to have as many arguments as you want. Below is an example of a filter with one and two arguments, but you can add as many as you need.

    Example JS:

    var app = angular.module('myApp',[]);
    app.filter('myTableFilter', function(){
      // Just add arguments to your HTML separated by :
      // And add them as parameters here, for example:
      // return function(dataArray, searchTerm, argumentTwo, argumentThree) {
      return function(dataArray, searchTerm) {
          // If no array is given, exit.
          if (!dataArray) {
              return;
          }
          // If no search term exists, return the array unfiltered.
          else if (!searchTerm) {
              return dataArray;
          }
          // Otherwise, continue.
          else {
               // Convert filter text to lower case.
               var term = searchTerm.toLowerCase();
               // Return the array and filter it by looking for any occurrences of the search term in each items id or name. 
               return dataArray.filter(function(item){
                  var termInId = item.id.toLowerCase().indexOf(term) > -1;
                  var termInName = item.name.toLowerCase().indexOf(term) > -1;
                  return termInId || termInName;
               });
          } 
      }    
    });
    

    Then in your HTML:

    <tr ng-repeat="item in data | myTableFilter:filterText">
    

    Or if you want to use multiple arguments:

    <tr ng-repeat="item in data | myTableFilter:filterText:argumentTwo:argumentThree">
    
    0 讨论(0)
  • 2020-11-30 12:49

    Here is my solution, it's very lazy, it will search on all strings in array on first level, you could update this to recusively go down the tree, but this should be good enough...

    app.filter('filterAll', function () {
    
        return function (dataArray, searchTerm, propertyNames) {
            if (!dataArray) return;    
    
            if (!searchTerm) {
                return dataArray;
            } else {
    
    
    
                if (propertyNames == undefined) {
                    propertyNames = [];
    
                    for (var property in dataArray[0]) {
                        if(typeof dataArray[0][property] == "string" && 
                            property != "$$hashKey" && 
                            property != "UnitName" )
                            propertyNames.push(property);
                    }
                }
    
                console.log("propertyNames", propertyNames);
    
                var term = searchTerm.toLowerCase();
                return dataArray.filter(function (item) {
                    var found = false;
                    propertyNames.forEach(function(val) {
                        if (!found) {
                            if (item[val] != null && item[val].toLowerCase().indexOf(term) > -1)
                                found = true;
                        } 
                    });
                    return found;
                });
            }
        }
    });
    
    0 讨论(0)
  • 2020-11-30 12:52

    I created this filter to perform search in several fields:

    var find = function () {
        return function (items,array) {
            var model  = array.model;
            var fields = array.fields;
            var clearOnEmpty = array.clearOnEmpty || false;
            var filtered = [];
    
            var inFields = function(row,query) {
                var finded = false;
                for ( var i in fields ) {
                    var field = row[fields[i]];
                    if ( field != undefined ) {
                        finded = angular.lowercase(row[fields[i]]).indexOf(query || '') !== -1;
                    }
                    if ( finded ) break;
                }
                return finded;
            };
    
            if ( clearOnEmpty && model == "" ) return filtered;
    
            for (var i in items) {
                var row = items[i];                
                var query = angular.lowercase(model);
    
                if (query.indexOf(" ") > 0) {
                    var query_array = query.split(" ");
                    var x;
                    for (x in query_array) {
                        query = query_array[x];
                        var search_result = true;
                        if ( !inFields(row,query) ) {
                            search_result = false;
                            break;
                        }
                    }
                } else {
                    search_result = inFields(row,query);
                }                
                if ( search_result ) {
                    filtered.push(row);
                }
            }
            return filtered;
        };
    };   
    

    How to use:

    <tr repeat="item in colletion
                        | find: {
                            model : model, // Input model
                            fields : [     // Array of fields to filter
                                'FIELD1',
                                'FIELD2',
                                'FIELD3'
                            ],
                            clearOnEmpty: true // Clear rows on empty model (not obligatory)
                        } "></tr>
    
    0 讨论(0)
  • 2020-11-30 12:53

    To expand on the excellent answer by @charlietfl, here's a custom filter that filters by one column(property) which is passed to the function dynamically instead of being hard-coded. This would allow you to use the filter in different tables.

    var app=angular.module('myApp',[]);        
    app.filter('filterByProperty', function () {
            /* array is first argument, each addiitonal argument is prefixed by a ":" in filter markup*/
            return function (dataArray, searchTerm, propertyName) {
                if (!dataArray) return;
                /* when term is cleared, return full array*/
                if (!searchTerm) {
                    return dataArray
                } else {
                    /* otherwise filter the array */
                    var term = searchTerm.toLowerCase();
                    return dataArray.filter(function (item) {
                        return item[propertyName].toLowerCase().indexOf(term) > -1;
                    });
                }
            }
        });
    

    Now on the mark-up side

    <input type="text" ng-model="filterText" />
    
    <table>
      <tr ng-repeat="item in data |filterByProperty:filterText:'name'"><td>{{ item.id }}</td><td>{{ item.name }}</td>...</tr>
    </table>
    
    0 讨论(0)
  • 2020-11-30 13:03

    see this link Filter multiple object properties together in AngularJS

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