2014-11-24 13 views
15

LA SITUAZIONE:angolare ui-seleziona il filtro in un solo campo

Ho un app angolare utilizzando angular ui-select per cercare e selezionare le persone da un database.

Sta funzionando bene, tranne una cosa. L'utente dovrebbe essere in grado di filtrare tra le persone utilizzando due criteri: nome ed e-mail.

Utilizzando il normale filtro angolare sono in grado di filtrarne solo uno. Se provo a filtrare entrambi i campi, non funziona più.

LAVORARE ESEMPIO CON UN CAMPO:

<ui-select multiple ng-model="database_people.selectedPeople" theme="select2" ng-disabled="disabled" style="width:100%"> 

    <ui-select-match placeholder="Select person...">{{$item.name}} &lt; {{$item.email}} &gt;</ui-select-match> 

    <ui-select-choices repeat="person2 in list_people | filter: {name: $select.search, db_data_type_id: 5}"> 

      <div ng-bind-html="person2.name | highlight: $select.search"></div> 

       <small> 
        email: <span ng-bind-html="''+person2.email | highlight: $select.search"></span> 
       </small> 

    </ui-select-choices> 

</ui-select> 


Non funziona ESEMPIO CON DUE CAMPI NEL FILTRO:

<ui-select multiple ng-model="database_people.selectedPeople" theme="select2" ng-disabled="disabled" style="width:100%"> 

    <ui-select-match placeholder="Select person...">{{$item.name}} &lt; {{$item.email}} &gt;</ui-select-match> 

    <ui-select-choices repeat="person2 in list_people | filter: {name: $select.search, email: $select.search, db_data_type_id: 5}"> 

      <div ng-bind-html="person2.name | highlight: $select.search"></div> 

       <small> 
        email: <span ng-bind-html="''+person2.email | highlight: $select.search"></span> 
       </small> 

    </ui-select-choices> 

</ui-select> 

La cosa strana è che funziona in realtà MA solo per il primo personaggio. Quando digito il primo carattere lo evidenzia in entrambi i campi, nome e indirizzo email. Ma quando digito il secondo carattere non funziona più (Non ho ricevuto errori nella console).


attemp UTILIZZO PROPSFILTER DA ANGULAR SAMPLES:

<ui-select multiple ng-model="database_people.selectedPeople" theme="select2" ng-disabled="disabled" style="width:100%"> 

    <ui-select-match placeholder="Select person...">{{$item.name}} &lt; {{$item.email}} &gt;</ui-select-match> 

    <ui-select-choices repeat="person2 in list_people | propsFilter: {name: $select.search, email: $select.search, db_data_type_id: 5}"> 

      <div ng-bind-html="person2.name | highlight: $select.search"></div> 

       <small> 
        email: <span ng-bind-html="''+person2.email | highlight: $select.search"></span> 
       </small> 

    </ui-select-choices> 

</ui-select> 

In questo caso si è rotto completamente, non ci sono dati più nel select2 ed ottengo alcuni errori nella console:

Cannot read property 'toString' of null 

Cannot read property 'length' of undefined 


LA QUESTIONE (S):

Come faccio a filtrare tra i campi mulitple? Posso farlo usando il filtro normale? Oppure devo usare un filtro personalizzato? Ma in questo caso, perché non funziona correttamente?

Grazie mille!

+0

@hanu Solo chiedendosi, hai implementato la funzione javascript personalizzata per propsFilter? Non funzionerà da solo ([vedi riga 83] (http://plnkr.co/edit/5pWPKGSQfGejuEflDNuF?p=preview)). Non ho ancora provato a utilizzarlo, ma sembra che molte persone non sappiano che devono includere il codice javascript. – DaaaahWhoosh

+0

Sì, deve essere inclusa la direttiva. Grazie per segnalarlo. – johnnyfittizio

risposta

5

Forse perché lo stesso valore ($ select.search) viene utilizzato per entrambi i filtri email e nome.

<ui-select-choices repeat="person2 in list_people | filter: {name: $select.search, email: $select.search, db_data_type_id: 5}"> 
... 

Questo spiega anche perché funziona solo con il primo carattere.

Usa i valori separati per ogni filtro per risolvere questo problema:

<ui-select-choices repeat="person2 in list_people | filter: {name: $select.search.name, email: $select.search.email, db_data_type_id: 5}"> 
... 
+0

Dio ti benedica !! – johnnyfittizio

+1

Siamo spiacenti, ma come dovrebbe funzionare? '$ select.search' è una proprietà con un solo valore di testo. –

+0

Anche per me non funziona – Icet

8

È possibile utilizzare il filtro proprietà come di seguito

<ui-select ng-model="emplyee" theme="bootstrap"> 
<ui-select-match placeholder="Select ...">{{$select.selected.firstName+" "+$select.selected.lastName}}</ui-select-match> 
<ui-select-choices repeat="emp in employees | propertyFilter: {firstName:$select.search, lastName:$select.search}"> 
<span ng-bind-html="emp.firstName+' '+emp.lastName | highlight: $select.search"></span> 
</ui-select-choices> 

si dovrà modificare il propertyFilter come qui di seguito:

.filter('propertyFilter', function($log) { 
return function(items, props) { 
    var out = []; 
    if (angular.isArray(items)) { 
    items.forEach(function(item) { 
     var itemMatches = false; 
     var keys = Object.keys(props); 
     var optionValue = ''; 
     for (var i = 0; i < keys.length; i++) { 
      optionValue = item[keys[i]] ? optionValue + item[keys[i]].toString().toLowerCase().replace(/ /g, '') : ''; 
     } 
     for (var j = 0; j < keys.length; j++) { 
      var text = props[keys[j]].toLowerCase().replace(/ /g, ''); 
      if (optionValue.indexOf(text) !== -1) { 
       itemMatches = true; 
       break; 
      } 
     } 
     if (itemMatches) { 
      out.push(item); 
     } 
     }); 
     } else { 
      // Let the output be the input untouched 
      out = items; 
     } 

     return out; 
    }; 
}) 

La ricerca può essere effettuata sul valore di tutte le opzioni. Ad esempio se nelle opzioni hai 'peter parker', puoi cercare con 'peter', 'parker', 'peter parker', 'peterparker' e anche cercare con più spazi tra qualsiasi carattere di peter parker.

1

Ho visto alcuni fluttuare in giro come la risposta di Kunsingh, che mi ha fatto iniziare a risolvere il mio problema simile. Nel mio caso cercava più oggetti e in oggetti, ma invio anche record logicamente cancellati al client e facoltativamente li filtro in elenchi. Per i dropdown volevo che rimuovessi sempre senza dover modificare l'API.

Ecco la mia versione modificata, che include la ricerca sugli oggetti. Ovviamente questo funzionerà solo se tutte le tue tabelle hanno una colonna int chiamata Deleted (For me fa parte della chiave univoca e imposta il valore dell'identità quando viene cancellata) e la passi al client.

In un secondo momento ho intenzione di modificare ulteriormente per consentire la ricerca ricorsiva di oggetti.

App.filter('dropdownFilter', function() { 
    return function (items, props: Object, keyvalue?) { 
    var out = []; 

     if (angular.isArray(items)) { 
      items.forEach(function (item) { 
       var itemMatches = false; 
       var canbreak = false; 

       // Filter out logically deleted records 
       if (item.Deleted != 0) 
        itemMatches = false; 
       else { 
        var keys = Object.keys(props); 

        for (var i = 0; i < keys.length; i++) { 
         var prop: string = keys[i]; 
         var text = ""; 
         // If an object, e.g. searching deep, such as Project: {ProjectName: $select.search} 
         // Then iterate through the object to find values. 
         // NOTE: This one searches one deep from each object, 
         // e.g. Project.ProjectName 
         //  Project.User.LastName WILL NOT WORK. 
         if (angular.isObject(props[prop])) { 
          angular.forEach(props[prop], function (value, key) { 
           text = value.toLowerCase(); 
           if (item[prop][key].toLowerCase().indexOf(text) !== -1) { 
            itemMatches = true; 
            canbreak = true; 
           } 
          }); 
          if (canbreak) 
           break; 
         } 
         // If it's a simple array, then woo! 
         else { 
          text = props[prop].toLowerCase(); 
          if (item[prop] != undefined && item[prop].toString().toLowerCase().indexOf(text) !== -1) { 
           itemMatches = true; 
           break; 
          } 
         } 
        } 
       } 

       if (itemMatches) { 
        out.push(item); 
       } 
      }); 
     } 
     else { 
      // Let the output be the input untouched 
      out = items; 
     } 

    return out; 
    } 
}); 

e un campione di esso in uso (utilizzando select2 per angolare). Questo è un elenco a discesa di stato/paese con paese come sotto-oggetto di stato.

<ui-select ng-model="personneladdress.StateID" theme="select2" class="select2"> 
    <ui-select-match placeholder="{{language.State}}">{{$select.selected.StateName}}</ui-select-match> 
    <ui-select-choices repeat="item.StateID as item in State | dropdownFilter: {StateName: $select.search, Country: {CountryName: $select.search}}"> 
     <span ng-bind-html="item.StateName | highlight: $select.search"></span><br /> 
     <small> 
      <span ng-bind-html="''+item.Country.CountryName | highlight: $select.search"></span> 
     </small> 
    </ui-select-choices> 
</ui-select> 
+0

hai fatto il ricorsivo? –

+0

Non l'ho ancora fatto, mi dispiace! Sono riuscito a mantenere tutti i miei elenchi subobjects in misura minore. – dbmuller

Problemi correlati