Filtrar por varias columnas con ng-repeat

Me pregunto si hay una manera fácil en Angular para filtrar una tabla usando ng-repeat en columnas específicas usando or lógica, en lugar de and . En este momento, mi filtro está buscando todo en la tabla (más de 10 columnas de datos), cuando realmente solo necesita filtrar en 2 columnas de datos (ID y Nombre).

Me las arreglé para bajar solo para mirar esas 2 columnas al filtrar ( usando un objeto en la expresión del filtro según los documentos y mirando esta respuesta SO ), pero está usando and lógica, que es demasiado específica. Me gustaría que sea de uso or lógica, pero estoy teniendo problemas.

Mi HTML

  ...
{{ item.id }}{{ item.name }}

Mi lógica de filtro:

$filter('filter')(data, {id:$scope.filterText, name:$scope.filterText})

El filtrado funciona, pero una vez más, está tomando la intersección de las columnas correspondientes en lugar de la unión. ¡Gracias!

No es difícil crear un filtro personalizado que le permita tener tantos argumentos como desee. A continuación se muestra un ejemplo de un filtro con uno y dos argumentos, pero puede agregar tantos como necesite.

Ejemplo 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; }); } } }); 

Luego en tu HTML:

  

O si quieres usar múltiples argumentos:

  

Úselo para buscar en Todas las Columnas (puede ser lento): buscar. $ AngularJS API: filtrar

 Any Column Search:   ...

Para ampliar la excelente respuesta de @charlietfl , aquí hay un filtro personalizado que filtra por una columna (propiedad) que se pasa a la función de forma dinámica en lugar de estar codificada. Esto le permitiría usar el filtro en diferentes tablas.

 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; }); } } }); 

Ahora en el lado del margen

  ...
{{ item.id }}{{ item.name }}

Lo descubrí; tuve que escribir mi propio filtro personalizado. Aquí está mi solución:

 var filteredData; filteredData = $filter('filter')(data, function(data) { if ($scope.filter) { return data.id.toString().indexOf($scope.filter) > -1 || data.name.toString().indexOf($scope.filter) > -1; } else { return true; } }); 

Creé este filtro para realizar búsquedas en varios campos:

 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; }; }; 

Cómo utilizar:

  

Fácilmente podemos hacer este tipo Siguiendo el código escrito de acuerdo creará fácilmente otro filtro de campo ….

 var myApp = angular.module('myApp',[]); myApp.filter('myfilter',myfilter); function myfilter(){ return function (items, filters) { if (filters == null) { return items; } var filtered = []; //Apply filter angular.forEach(items, function (item) { if ((filters.Name == '' || angular.lowercase(item.Name).indexOf(angular.lowercase(filters.Name)) >= 0) ) { filtered.push(item); } }); return filtered; }; } myApp.controller('mycontroller',['$scope',function($scope){ $scope.filters={Name:'',MathsMarks:''}; $scope.students=[]; var i=0; for(i=0;i<5;i++){ var item={Name:'',Marks:[]}; item.Name='student' + i; item.Marks.push({Maths:50-i,Science:50 +i}); $scope.students.push(item); } }]); 
       
Name : {{student.Name}} Marks == > Maths:{{m.Maths}} Science:{{m.Science}}

Aquí está mi solución, es muy vago, buscará todas las cadenas en el primer nivel, podrías actualizar esto para bajar recíprocamente, pero esto debería ser lo suficientemente bueno …

 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; }); } } }); 

ver este enlace Filtrar múltiples propiedades de objetos juntas en AngularJS