问题
I'm following the material table example from Angular Material and currently, they have a filtering the table example with typed in results.
I added two dropdowns to the material table example and I want to be able to select a value from both dropdowns and perform a search based on both values from the two dropdowns. E.g. in this case, if I select 8 and Hydrogen, I should not get any results because 8 and hydrogen are not part of the same record/item. If I select however 1 and hydrogen, I should get back hydrogen because 1 and hydrogen values are part of the same item/record.
Here's the stackbiltz: https://stackblitz.com/edit/angular-t67ae3-huzvd6?file=app%2Ftable-filtering-example.ts
Here's the code snippets:
component:
import {Component} from '@angular/core';
import {MatTableDataSource} from '@angular/material';
/**
* @title Table with filtering
*/
@Component({
selector: 'table-filtering-example',
styleUrls: ['table-filtering-example.css'],
templateUrl: 'table-filtering-example.html',
})
export class TableFilteringExample {
displayedColumns = ['position', 'name', 'weight', 'symbol'];
dataSource = new MatTableDataSource(ELEMENT_DATA);
//How do I filter based on selected value?
search(selectedValue: string, selectedValueEle: string) {
selectedValue = selectedValue.trim(); // Remove whitespace
selectedValue = selectedValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
this.dataSource.filter = selectedValue && selectedValueEle;
debugger
}
}
export interface Element {
name: string;
position: number;
weight: number;
symbol: string;
}
const ELEMENT_DATA: Element[] = [
{position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
{position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
{position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
{position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
{position: 5, name: 'Boron', weight: 10.811, symbol: 'B'},
{position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'},
{position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N'},
{position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O'},
{position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F'},
{position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne'},
{position: 11, name: 'Sodium', weight: 22.9897, symbol: 'Na'},
{position: 12, name: 'Magnesium', weight: 24.305, symbol: 'Mg'},
{position: 13, name: 'Aluminum', weight: 26.9815, symbol: 'Al'},
{position: 14, name: 'Silicon', weight: 28.0855, symbol: 'Si'},
{position: 15, name: 'Phosphorus', weight: 30.9738, symbol: 'P'},
{position: 16, name: 'Sulfur', weight: 32.065, symbol: 'S'},
{position: 17, name: 'Chlorine', weight: 35.453, symbol: 'Cl'},
{position: 18, name: 'Argon', weight: 39.948, symbol: 'Ar'},
{position: 19, name: 'Potassium', weight: 39.0983, symbol: 'K'},
{position: 20, name: 'Calcium', weight: 40.078, symbol: 'Ca'},
];
html:
<div class="example-container mat-elevation-z8">
<div class="example-header">
<select #selectedValueEle>
<option value="8">8</option>
<option value="9">9</option>
</select>
<select #selectedValue>
<option value="Hydrogen">Hydrogen</option>
<option value="Helium">Helium</option>
</select>
<button (click)="search(selectedValue.value, selectedValueEle.value)">Search</button>
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
</div>
<mat-table #table [dataSource]="dataSource">
<!-- Position Column -->
<ng-container matColumnDef="position">
<mat-header-cell *matHeaderCellDef> No. </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.position}} </mat-cell>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="weight">
<mat-header-cell *matHeaderCellDef> Weight </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.weight}} </mat-cell>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="symbol">
<mat-header-cell *matHeaderCellDef> Symbol </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.symbol}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</div>
回答1:
If you replace the line:
this.dataSource.filter = selectedValue && selectedValueEle;
with:
this.dataSource.filter = selectedValueEle + selectedValue;
that should do the trick!
This is because according to the Angular table documentation https://material.angular.io/components/table/overview#filtering:
For example, the data object {id: 123, name: 'Mr. Smith', favoriteColor: 'blue'} will be reduced to 123mr. smithblue. If your filter string was blue then it would be considered a match because it is contained in the reduced string, and the row would be displayed in the table.
From what I understand, they're doing a simple string search. So by concatenating the value and the element, it's doing a string search on "1Hydrogen" and finds it in the reduced data object, "1Hydrogen1.0079H."
But you must have it in the order of "1Hydrogen," so by having selectedValueEle
be first and selectedValue
next, you'll have it in the correct format. Hope this helped and good luck!
来源:https://stackoverflow.com/questions/49538398/how-can-i-filter-results-based-on-multiple-selections-from-dropdown