Filtra per più colonne con ng-repeat

Mi chiedo se c’è un modo semplice in Angolare per filtrare una tabella usando ng-repeat su colonne specifiche usando or logica, piuttosto che and . In questo momento, il mio filtro sta cercando tutto nella tabella (oltre 10 colonne di dati), quando ha solo bisogno di filtrare su 2 colonne di dati (ID e Nome).

Sono riuscito ad abbassare lo sguardo solo a quelle 2 colonne durante il filtraggio ( utilizzando un object nell’espressione filtro come per i documenti e guardando questa risposta SO ), ma sta usando and logica, che è troppo specifica. Mi piacerebbe averlo per usare or logica, ma sto avendo problemi.

Il mio HTML

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

La mia logica di filtro:

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

Il filtro funziona, ma, di nuovo, sta prendendo l’intersezione delle colonne corrispondenti piuttosto che l’unione. Grazie!

Non è difficile creare un filtro personalizzato che ti permetta di avere tutti gli argomenti che vuoi. Di seguito è riportato un esempio di filtro con uno e due argomenti, ma è ansible aggiungerne il numero necessario.

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

Quindi nel tuo HTML:

  

O se vuoi usare più argomenti:

  

Utilizzare questo per cercare su Tutte le colonne (può essere lento): ricerca. $ AngularJS API: filter

 Any Column Search:   ...

Per espandere l’eccellente risposta di @charlietfl , ecco un filtro personalizzato che filtra per una colonna (proprietà) che viene passata dynamicmente alla funzione invece di essere codificata. Questo ti permetterebbe di usare il filtro in diverse tabelle.

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

Ora sul lato mark-up

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

L’ho capito – ho dovuto scrivere il mio filtro personalizzato. Ecco la mia soluzione:

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

Ho creato questo filtro per eseguire ricerche in diversi campi:

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

Come usare:

  

Facilmente possiamo fare questo tipo Seguendo il codice scritto in base a te, potrai facilmente creare un altro filtro di 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}}

Ecco la mia soluzione, è molto pigro, cercherà su tutte le stringhe in array al primo livello, potreste aggiornarlo per recusivamente scendere dall’albero, ma questo dovrebbe essere abbastanza buono …

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

vedi questo link Filtra più proprietà di oggetti insieme in AngularJS