2013-10-16 8 views
14

Sto provando a scrivere un filtro personalizzato angularjs che controlla se un array di paesi contiene una stringa di ricerca immessa dall'utente.Come posso scrivere un filtro angularjs per cercare frammenti/sequenze di stringhe

La stringa può essere costituita da una lettera (ad esempio "E"), o un frammento di n lettere (ad esempio "lan") o un'intera parola (ad esempio "Inghilterra").

In ogni caso, tutti i paesi contenenti quella lettera o quel frammento devono essere restituiti, quindi "E" restituirebbe "Inghilterra", "Estonia" ecc. Mentre "lan" restituire "Inghilterra", "Irlanda", ecc

Finora il mio filtro restituisce l'intero paese o singole lettere ma sto avendo difficoltà con frammenti di stringa:

  1. HTML Template:

    <input ng-model="filter.text" type="search" placeholder="Filter..."/> 
    
    <ul> 
        <li ng-repeat="item in data | listfilter:filter.text"> 
    </ul> 
    
  2. angularJS

    angular.module('sgComponents').filter('listfilter',[ function() { 
    return function(items, searchText) { 
        var filtered = [];    
    
        angular.forEach(items, function(item) { 
         if(item.label === searchText) { // matches whole word, e.g. 'England' 
          filtered.push(item); 
         } 
         var letters = item.label.split(''); 
         _.each(letters, function(letter) { 
          if (letter === searchText) { // matches single letter, e.g. 'E' 
           console.log('pushing'); 
           filtered.push(item); 
          } 
         }); 
         // code to match letter fragments, e.g. 'lan' 
        }); 
        return filtered; 
    }; 
    }]); 
    

risposta

24

è molto più semplice di quello, utilizzare il String.indexOf() funzione:

angular.forEach(items, function(item) { 
    if(item.label.indexOf(searchText) >= 0) filtered.push(item); 
}); 

Si consiglia di attivare entrambe le stringhe .toLowerCase() per fare case-insensitive matching:

searchText = searchText.toLowerCase(); 
angular.forEach(items, function(item) { 
    if(item.label.toLowerCase().indexOf(searchText) >= 0) filtered.push(item); 
}); 
+0

perfetto! molte grazie. Avevo bisogno di farlo come suggerito: if (item.label.toLowerCase(). IndexOf (searchText.toLowerCase())> = 0) filtered.push (item); – Tone

0

Date un'occhiata alla Angular-UI-Bootstrap direttiva per typeahead fa esattamente ciò che si vuole: http://angular-ui.github.io/bootstrap/#/typeahead

+0

Grazie per la risposta, ma purtroppo non sto usando angolare-ui – Tone

+3

FWIW, angolare-ui non è un framework di sviluppo come jQuery-ui che bisogna essere ' utilizzando'. È un kit di parti che puoi distribuire al bisogno, senza la necessità di modificare la tua app in altro modo. – XML

7
angular.module('sgComponents').filter('listfilter',[ function() { 
    return function(items, searchText) { 
     var filtered = []; 
     var regex = new RegExp(".*" + searchItem + ".*", "ig"); 
     angular.forEach(items, function(item) { 
      if(regex.test(item)){ 
       filtered.push(item); 
      } 
     }); 
     return filtered; 
    } 
}]); 
+1

Non farlo: è molto lento. Per favore sposta almeno 'var regex = new RegExp (". * "+ SearchItem +". * "," Ig ")' prima del ciclo. Comunque un approccio migliore è usare 'indexOf' invece RegExp. – kseb

+0

grazie per la risposta. La soluzione indexOf() di Nikos si è dimostrata la più semplice da implementare. – Tone

Problemi correlati