it-swarm.com.de

Angular ui-select filtert nur ein Feld

DIE SITUATION:

Ich habe eine Winkel-App mit angle ui-select zum Suchen und Auswählen von Personen aus einer Datenbank.

Es funktioniert gut, bis auf eine Sache .. Der Benutzer sollte in der Lage sein, unter den Personen anhand zweier Kriterien zu filtern: Name und E-Mail.

Mit dem normalen Winkelfilter kann ich nur eines davon filtern .. Wenn ich versuche, beide Felder zu filtern, funktioniert es nicht mehr.

ARBEITSBEISPIEL MIT EINEM FELD:

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


NICHT BEARBEITUNGSBEISPIEL MIT ZWEI FELDERN IM FILTER:

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

Das Merkwürdige ist, dass es tatsächlich funktioniert, ABER nur für das erste Zeichen. Wenn ich das erste Zeichen eingebe, wird es in den beiden Feldern Name und E-Mail hervorgehoben. Wenn ich jedoch das zweite Zeichen eingebe, funktioniert es nicht mehr (Ich habe keine Fehlermeldung in der Konsole erhalten).


ATTEMP MIT PROPSFILTER VON ANGULAR PROBEN :

 <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 diesem Fall ist es komplett kaputt, es gibt keine Daten mehr in select2 und ich bekomme einige Fehler in der Konsole:

Cannot read property 'toString' of null

Cannot read property 'length' of undefined


DIE FRAGEN):

Wie kann ich zwischen mehreren Feldern filtern? Kann ich das mit normalen Filtern tun? Oder muss ich einen benutzerdefinierten Filter verwenden? Aber warum funktioniert das nicht richtig?

Vielen Dank!

16
FrancescoMussi

Vielleicht liegt es daran, dass derselbe Wert ($ select.search) für beide Filter-E-Mails und -Namen verwendet wird.

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

Dies erklärt auch, warum es nur mit dem ersten Zeichen funktioniert.

Verwenden Sie für jeden Filter separate Werte, um dies zu beheben:

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

Sie können den Eigenschaftenfilter wie folgt verwenden

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

Sie müssen das propertyFilter wie folgt ändern:

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

Die Suche kann nach dem Optionswert als Ganzes durchgeführt werden. Wenn Sie zum Beispiel in Optionen "Peter Parker" haben, können Sie mit "Peter", "Parker", "Peter Parker", "Peterparker" und sogar mit mehreren Leerzeichen dazwischen einen beliebigen Charakter von Peter Parker suchen.

8
kunsingh

Ich habe einige gesehen, die wie die Antwort von kunsingh herumschwammen, was mich dazu brachte, mein ähnliches Problem zu lösen. In meinem Fall wurde mehrfach und in Objekten gesucht, aber ich sende auch logisch gelöschte Datensätze an den Client und filtere sie optional in Listen. Für Dropdowns wollte ich, dass das immer entfernt wurde, ohne die API ändern zu müssen. 

Hier ist meine veränderte Version, die auch die Suche nach Objekten beinhaltet. Offensichtlich funktioniert das nur, wenn alle Ihre Tabellen über eine int-Spalte mit dem Namen "Delete" verfügen (Für mich ist es Teil des eindeutigen Schlüssels und wird beim Löschen auf den Identitätswert gesetzt), und Sie übergeben ihn an den Client.

Zu einem späteren Zeitpunkt plane ich weitere Änderungen, um die rekursive Suche nach Objekten zu ermöglichen.

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

und ein Beispiel davon (unter Verwendung von select2 für Winkel). Dies ist ein Dropdown von Staat/Land mit Land als Unterobjekt des Staates.

<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>
1
dbmuller

Ich habe dieses Problem mit diesem Code gelöst:

<ui-select-choices repeat="person2 in list_people | filter: $select.search" >

In ui-select-match verwende ich zwei Felder:

<ui-select-match placeholder="select One...">
   {{$item.field1}} - {{$item.field2}}
</ui-select-match>
0
Pasha Gharibi