Filter by multiple columns with ng-repeat
Solution 1:
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">
Solution 2:
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">
...
Solution 3:
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>