2016-07-20 12 views
0

Ich habe eine dynamische Tabelle aus einem Array von Objekten erstellt und die Zeilen mit angular-ui-bootstrap paginiert. Ich muss auch die Zeilenfilterfunktionalität in der Tabelle basierend auf der Benutzerauswahl implementieren. Zum Beispiel würde ich eine oder mehrere Städte aus den Kontrollkästchen auswählen und nur die Zeilen mit übereinstimmenden Städten anzeigen, oder der Benutzer wählt bestimmte Namen oder eine Kombination aus beiden aus. Im Folgenden Beispieldaten ist:Filter ng-repeat Tabelle mit mehreren Filterwerten für eine Spalte

ctrl.data = [{ 
    id: 1, 
    name: 'Ram Kumar', 
    city: 'Delhi', 
    date: new Date("October 13, 2014 11:13:00") 
}, { 
    id: 2, 
    name: 'Raman Kumar', 
    city: 'Mumbai', 
    date: new Date("November 13, 2014 11:13:00") 
}, { 
    id: 3, 
    name: 'Raghav Kumar', 
    city: 'Chennai', 
    date: new Date("December 13, 2014 11:13:00") 
}]; 

Ich habe auch eine Metadaten erstellt, die Informationen über alle Eigenschaften von Daten wie Eigenschaftsnamen enthalten wird, dann ist es eindeutige Werte, die Art Filter, die diese Eigenschaft also beim Check-Box benötigen würde oder ein Schieberegler. Im Folgenden finden Sie die Metadaten:

ctrl.metadata = [{ 
    name: "ID", 
    values: [1, 2, 3], 
    type: "checkbox", 
    showFilter: false 
}, { 
    name: "Name", 
    type: "checkbox", 
    values: ["Ram Kumar", "Raman Kumar", "Raghav Kumar"], 
    showFilter: false 
}, { 
    name: "City", 
    type: "checkbox", 
    values: ["Delhi", "Mumbai", "Chennai"], 
    showFilter: true 
}, { 
    name: "Birth Date", 
    type: "date", 
    showFilter: false 
}, { 
    name: "Age", 
    type: "slider", 
    values: [18,26], 
    showFilter: false 
}]; 

ich derzeit eine Ein-Wert statische Filterabfragevariable für einige Attribute wie ID, Name und Stadt gemacht habe.

<div ng-repeat="attr in metadata"> 
    <div ng-if="attr.name === 'ID'"> 
     Enter Filter: 
     <input type="textbox" ng-model="search.id" /> 
    </div> 

    <div ng-if="attr.name === 'City'"> 
     Enter Filter: 
     <input type="textbox" ng-model="search.city" /> 
    </div> 
<div> 

Und ich bin der Anwendung dieser Filter auf Tabellenzeilen auf diese Weise:

<tr ng-repeat="row in data | filter: search | pages: currentPage : itemsPerPage"> 
    <td ng-repeat="item in row">{{ item }}</td> 
    </tr> 

Aber zunächst möchte ich die Filterabfragevariable (Suche) dynamisch generiert werden, da die Daten und Metadaten könnten Veränderung. So etwas wie unten, wenn möglich:

<div ng-repeat="attr in metadata"> 
    <div ng-if="attr.name === 'ID'"> 
     Enter Filter: 
     <input type="textbox" ng-model="attr.searchQuery" /> 
    </div> 
</div> 

Ich legte die Suchabfrage zu Metadatenobjekt Eigenschaft namens Search. Aber wenn ich versuche, es in Filter zu verwenden, sehe ich kein Ergebnis:

<tr ng-repeat="row in data | filter: metadata[$index].searchQuery | pages: vm.currentPage : vm.itemsPerPage"> 
    <td ng-repeat="item in row">{{ item }}</td> 
    </tr> 

Zweitens kann die Suchanfrage nur eine Saite nehmen, aber als ich die Filter will auf mehr als einen Wert zu basieren, wie kann ich es erreichen? Ich habe über benutzerdefinierte Filter recherchiert, aber das Problem ist, wie kann ich die ausgewählten Werte "aufzeichnen" und dann an den Filter senden (zum Beispiel, um alle ausgewählten Städte aus den Kontrollkästchen zu holen)? Ich muss jede Variable dynamisch oder Teil von Metadaten machen, so dass sie nicht bricht, wenn entweder die Anzahl der Eigenschaften oder der Name der Eigenschaften oder Werte geändert werden. Es gibt möglicherweise keine Städte außer Staaten, wenn Daten geändert werden, also kann nichts statisches machen.

Bitte schlagen Sie einige Ideen für die Umsetzung vor. Here is a working plunker.

Antwort

1

Zuerst sollten Sie Ihre <input> ändern:

<input type="checkbox" ng-model="vm.selected[$index]" ng-true-value="'{{value}}'" ng-false-value="" /> {{value}} 

Dann wird Ihr ng-repeat:

<tr ng-repeat="row in vm.data | filter: vm.search | customFilter: vm.selected | pages: vm.currentPage : vm.itemsPerPage"> 

Und schließlich können Sie eine custom filter implementieren zu erreichen, was Sie wollen, wie folgt aus:

.filter('customFilter', function() { 
    return function(items, search) { 
    if (!search || (Object.keys(JSON.parse(JSON.stringify(search))).length === 0 && search.constructor === Object)) { 
     return items; 
    } 
    var selected = Object.keys(search).map(function(key) { 
     return search[key] 
    }); 
    items = items.filter(function(value) { 
     return selected.indexOf(value.city) != -1; 
    }); 
    return items; 
    } 
}); 

Überprüfen Sie die komplette code

Ich hoffe, es hilft.

Tipp: Ich weiß nicht, wenn Sie diese Dinge von ui-bootstrap in Ihrem realen Projekt verwenden, aber sie sind veraltet, wie Sie in der Konsole sehen:

PaginationController jetzt veraltet . Verwenden Sie stattdessen UibPaginationController . Die Seitennummerierung ist jetzt veraltet. Verwenden Sie stattdessen uib-pagination.

+0

Großartige Arbeit, aber der Filter funktioniert nur auf Stadt. Ich kann nicht basierend auf ID oder Name filtern (versuche herauszufinden, aber noch keine Lösung). Wenn ich versuche, die Kontrollkästchen "ID" oder "Name" zu aktivieren, werden die Markierungsfelder "Stadt" ausgeblendet (Kontrollkästchen für nur einen Filterabschnitt können gleichzeitig ausgewählt werden). Wenn ich beispielsweise alle Kontrollkästchen von "Stadt" auswähle und dann das erste Kontrollkästchen der ID wähle, wird das erste Kontrollkästchen von "Stadt" ausgeblendet (wegen des gleichen Filtermodells). Kann ich die Filtervariable "Ausgewählter [$ index]" nicht an meine Metadaten anhängen? Ich möchte, dass alle Filter gleichzeitig bestehen bleiben. – Rishabh

+0

Ich habe versucht, "ausgewählten [$ index]" an attr anstelle von Controller (vm) anzuhängen, aber selbst wenn ich die gespeicherten Auswahlen sehen kann, kann ich den Filter nicht mit "customFilter: attr.selected" auf Tabelle anwenden – Rishabh

+0

Hmm .. du sprichst nur über Städte .. Willst du, dass alle Filter funktionieren ** simplesonely **? Wie wenn Sie nur einen Tab öffnen lassen können (zB ** oder **)? – developer033

Verwandte Themen