问题
I've been trying to get this working with no luck. I've been referencing these resources for help:
http://swimlane.github.io/ngx-datatable/#filter
https://github.com/swimlane/ngx-datatable/blob/master/demo/basic/filter.component.ts
Basically i just want to allow my filter to apply to more than a single column, without implementing code to handle every column. (Some datatables have 20+ columns!)
Example Code:
//HTML
<input type='text' placeholder='Filter' (keyup)='updateFilter($event.target.value)' />
<ngx-datatable
class="material"
columnMode="force"
[columns]="gridProperties.FilteredColumns"
[footerHeight]="50"
[loadingIndicator]="gridLoadingIndicator"
[rows]="filteredList"
[scrollbarH]="false"
[scrollbarV]="true"
[selected]="selectedItem"
[selectionType]="'single'"
style="min-height:400px;">
</ngx-datatable>
//TYPESCRIPT
public items: Item[];
updateFilter(filterValue) {
const lowerValue = filterValue.toLowerCase();
this.filteredList = this.items.filter(item => item.name.toLowerCase().indexOf(lowerValue) !== -1 || !lowerValue);
}
Here I am obviously just handling filtering for the 'name' property of my items array. This works great as is, but like I had mentioned, if the grid contains many columns I'd like one method to handle all of them. Any help or tips are appreciated.
回答1:
Using the example TS file for filtering (https://github.com/swimlane/ngx-datatable/blob/master/demo/basic/filter.component.ts) as a foundation, I was able to successfully make it filter all columns dynamically (it will filter all columns without the need to specify them). I've included what I believe to be all the necessary parts for this to work but also trimmed the code down as much as I could to make it easier to understand.
HTML
<ngx-datatable
#table
class="material striped scroll-vertical"
[rows]="data"
[columns]="cols"
[columnMode]="'force'"
[headerHeight]="35"
[footerHeight]="35"
[rowHeight]="'auto'"
[limit]="pageSize"
[selectionType]="'single'">
<input type="text" (keyup)='filterDatatable($event)'>
TYPESCRIPT
cols = [{name:'First Name'},{name:'Last Name'},{name:'Address'}];
data = [];
filteredData = [];
// dummy data for datatable rows
dummyData = [
{firstName:'Daenarys',lastName:'Targaryen',address:'Dragonstone'},
{firstName:'Sansa',lastName:'Stark',address:'Winterfell'},
{firstName:'Cersei',lastName:'Lannister',address:'Kings Landing'},
{firstName:'Brienne',lastName:'Tarth',address:'Sapphire Island'},
{firstName:'Lyanna',lastName:'Mormont',address:'Bear Island'},
{firstName:'Margaery',lastName:'Tyrell',address:'Highgarden'}
]
ngOnInit(){
// populate datatable rows
this.data = this.dummyData;
// copy over dataset to empty object
this.filteredData = this.dummyData;
}
// filters results
filterDatatable(event){
// get the value of the key pressed and make it lowercase
let val = event.target.value.toLowerCase();
// get the amount of columns in the table
let colsAmt = this.cols.length;
// get the key names of each column in the dataset
let keys = Object.keys(this.dummyData[0]);
// assign filtered matches to the active datatable
this.data = this.filteredData.filter(function(item){
// iterate through each row's column data
for (let i=0; i<colsAmt; i++){
// check for a match
if (item[keys[i]].toString().toLowerCase().indexOf(val) !== -1 || !val){
// found match, return true to add to result set
return true;
}
}
});
// whenever the filter changes, always go back to the first page
this.table.offset = 0;
}
回答2:
here is an example of your code with multiple columns filtering:
updateFilter(filter: string): void {
const val = filter.trim().toLowerCase();
this.filteredList = this.items.slice().filter((item: any) => {
let searchStr = '';
for (let i = 0; i < this.gridProperties.FilteredColumns.length; i++) {
searchStr += (item[this.gridProperties.FilteredColumns[i]]).toString().toLowerCase();
}
return searchStr.indexOf(val) !== -1 || !val;
});
}
If I did not made any errors, it should work correctly.
回答3:
updateFilter(event) {
const val = event.target.value.toLowerCase();
const temp = this.temp.filter(index => {
return (index.name.toLowerCase().indexOf(val) !== -1 ||
index.company.toLowerCase().indexOf(val) !== -1 ||
index.gender.toLowerCase().indexOf(val) !== -1 ||
!val);
});
this.company = temp;
this.table.offset = 0;
}
回答4:
import { DatatableComponent } from '@swimlane/ngx-datatable';
ViewChild(DatatableComponent) table: DatatableComponent;
updateFilter(event) {
const val = event.target.value.toLowerCase();
var returnData: any;
// filter our data
const temp = this.temp.filter(function (d) {
if (d.yourFirstColumnName.toLowerCase().indexOf(val) !== -1 || !val) {
returnData = d.user_name.toLowerCase().indexOf(val) !== -1 || !val;
} else if (d.yourSecondColumnName.toLowerCase().indexOf(val) !== -1 || !val) {
returnData = d.notes_title.toLowerCase().indexOf(val) !== -1 || !val;
}
return returnData;
});
<input placeholder="Search Order" (keyup)='updateFilter($event)'>
回答5:
This answer improves an existing answer by Cole Paciano :
- Column names to be searched are only created once and not whenever a key is pressed
- Cell with
null
values are correctly handled (no console errors) - Full rows are shown (because filter is apply to row array)
- Column names to be searched can also be specified by hand to only include some of them (exclude guids, ids, etc)
In the template (html) file add an input with a keyup
handler
Search:
<input type="text" (keyup)='filterDatatable($event)'>
<ngx-datatable
class="material"
[rows]="rows"
[columns]="columns"
headerHeight="35"
rowHeight ="35">
</ngx-datatable>
In the component add the following filteredData
and columnsWithSearch
export class ListParkingsComponent implements OnInit {
columns = [];
rows = [];
filteredData = [];
columnsWithSearch : string[] = [];
ngOnInit() {
this.rows = getData() ; //recover data from API/database/datasource
this.filteredData = this.rows;
// for specific columns to be search instead of all you can list them by name
this.columnsWithSearch = Object.keys(this.rows[0]);
}
getData() {
//your current logic to fill the rows of the table
}
// filters results
filterDatatable(event){
// get the value of the key pressed and make it lowercase
let filter = event.target.value.toLowerCase();
// assign filtered matches to the active datatable
this.rows = this.filteredData.filter(item => {
// iterate through each row's column data
for (let i = 0; i < this.columnsWithSearch.length; i++){
var colValue = item[this.columnsWithSearch[i]] ;
// if no filter OR colvalue is NOT null AND contains the given filter
if (!filter || (!!colValue && colValue.toString().toLowerCase().indexOf(filter) !== -1)) {
// found match, return true to add to result set
return true;
}
}
});
// TODO - whenever the filter changes, always go back to the first page
//this.table.offset = 0;
}
来源:https://stackoverflow.com/questions/45106241/implementing-ngx-datatable-filtering-on-all-columns