Reputation: 2116
I am trying to add a search filter on top of my Angular data table(I'm not too fussed with it's positioning right now). I am using Angular-6-datatable (https://www.npmjs.com/package/angular-6-datatable) and bootstrap. I have created a stackblitz project here.
https://stackblitz.com/edit/angular-utd8cc
I just want to be able to search the 'Name' column. Please assist.
Upvotes: 2
Views: 26819
Reputation: 1
Just assume this is the data fetch from server: data.service.ts
let posts = [
{
"userId": 1,
"id": 1,
"title": "sunt aut",
"body": "quia et"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum"
},
{
"userId": 1,
"id": 3,
"title": "ea molestias quasi"
},
{
"userId": 1,
"id": 4,
"title": "eum et est occaecati",
"body": "ullam et saepe"
},
{
"userId": 1,
"id": 5,
"title": "nesciunt quas odio",
"body": "repudiandae veniam"
},
{
"userId": 1,
"id": 6,
"title": "dolorem eum magni eos aperiam quia",
"body": "ut aspernatur"
}
]
getPost() {
return this.posts;
}
*In HTML displaying this data in tabular format using ngFor directive: Syntax:
<input type="text" value="" (input)="searchData($event.target.value)">
<tr *ngFor="let post of filteredPost">
<td>Data display here..</td>
</tr>
In TS:
let post:any[] = [];
let filteredPost: any[] = [];
constructor(private dataService: DataService) {}
ngOnInit() {
this.post = this.dataService.getPost();
this.filteredPost = this.post;
}
searchData(searchText: string) {
if(!searchText) {
this.filteredPost = this.post;
} else {
this.filteredPost = this.post?.filter(post =>
post.title.toLowerCase().includes(searchText.toLowerCase()))
}
}
Upvotes: 0
Reputation: 21
Create 3 array lists i.e: rows =[]; permanentRows = []; temp = [];
While getting the data from API, initialize both the arrays i.e:
get_data_from_api(data=>{
this.rows = data,
this.permanentRows = data
}
)
updateFilter(event) {
const val = event.target.value.toLowerCase();
if(val) {
this.temp = this.rows;
// filter our data
const temp = this.temp.filter(function (d) {
return ( d.name.toLowerCase().indexOf(val) !== -1 || d.email.toLowerCase().indexOf(val) !== -1 || !val);
});
// update the rows
this.rows = temp;
}
else
{
this.rows = this.permanentRows;
}
}
Upvotes: 0
Reputation: 4696
i Think Your Requirement is Custom Filters in Data table.
Component.html
<form (ngSubmit)="filterById($event)">
<label>
First Name
<input type="text" name="first_name" id="first_name" />
</label>
<label>
Last Name
<input type="text" name="last_name" id="last_name"/>
<button class="btn btn-primary" type="submit">Search</button>
</form>
<br />
<table datatable [dtOptions]="dtOptions" class="row-border hover"></table>
Component.ts
export class DatatableComponent implements OnInit {
@ViewChild(DataTableDirective)
datatableElement: DataTableDirective;
private new_url = 'service_url';
Search$: Observable<Person>;
constructor(private personservice: PersonService, private httpClient: HttpClient) { }
send_data_service: any = {};
dtOptions: DataTables.Settings = {};
ngOnInit(): void {
this.dtOptions = {
ajax: this.new_url,
columns: [{
title: 'id',
data: 'id'
}, {
title: 'first_name',
data: 'first_name'
}, {
title: 'last_name',
data: 'last_name',
},
]
};
}
filterById(event: any) {
const first_name = event.target.first_name.value;
const last_name = event.target.last_name.value;
this.send_data_service = { 'first_name': first_name, 'last_name': last_name };
this.datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
this.personservice.searchData(this.send_data_service)
.subscribe(data =>
this.send_data_service = data);
dtInstance.search(first_name).draw();
}
}
You can implement custom filters in datatable.
Upvotes: 3
Reputation: 1392
Just add a separate array for your filtered data and bind your table to it:
ts file
search(term: string) {
if(!term) {
this.filterData = this.data;
} else {
this.filterData = this.data.filter(x =>
x.name.trim().toLowerCase().includes(term.trim().toLowerCase())
);
}
}
html
<input type="text" (keyup)='search($event.target.value)'>
Upvotes: 6
Reputation: 7733
You could filter using a Subject and the Array filter function.
In the component code :
data$ = new Subject<any>();
filter(search) {
this.data$.next(this.data.filter(_ => _.name.includes(search)));
}
And in the template just replace the data
with data$ | async
.
Here is a running edit of your code.
Upvotes: 1