I'm trying to make an input with an autocomplete with any field value, so I created a custom pipe.
My question is how can I do this because I have a component that displays my json data and another component that contains the autocomplete input?
should I use the @Input and @Output decorators?
I'm quite a beginner I don't know how to do it
thank you very much for your help
json.file
{
"boatType": "Semi-rigide",
"img": "/assets/img/boat-img/semi-rigide.jpg",
"longeur": 10,
"largeur": 20,
"tirantEau": 50,
"equipage": false,
"annexe": true
},
table.component.html
<div class="search">
<app-input #inputComponent></app-input>
</div>
<table>
<caption>Statement Summary</caption>
<thead>
<tr>
<th scope="col" class="toto">img</th>
<th scope="col">Type de bateau</th>
<th scope="col">longeur</th>
<th scope="col">largeur</th>
<th scope="col">tirant d'eau</th>
<th scope="col">equipage</th>
<th scope="col">annexe</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let boat of user | filter : inputComponent?.searchText">
<td data-label="img"><img [src]="boat.img" alt="boat" class="img"></td>
<td data-label="boat type">{{ boat.boatType }}</td>
<td data-label="longeur">{{boat.longeur}} cm</td>
<td data-label="largeur">{{boat.largeur}} cm</td>
<td data-label="tirant d'eau">{{boat.tirantEau}} cm</td>
<td data-label="equipage">{{boat.equipage ? "Oui" : "Non"}}</td>
<td data-label="annexe">{{boat.annexe ? "Oui" : "Non"}}</td>
</tr>
</tbody>
</table>
input.component.html
<input type="text" placeholder="Chercher un bateau.." [(ngModel)]="searchText">
filter.pipe
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filter'
})
export class FilterPipe implements PipeTransform {
transform(items: any[], searchText: string): any[] {
if (!items) return [];
if (!searchText) return items;
// TODO: need to improve this filter
// because at this moment, only filter by boatType
return items.filter(item => {
return item.boatType.toLowerCase().includes(searchText.toLowerCase());
});
}
}
The code needs some changes because you're using the tools in an incorrect way.
However, I refactored a little and I got the code to work.
A brief explanation and here the solution on stackblitz: https://stackblitz.com/edit/angular-ivy-ybubhx?file=src/app/filter.pipe.ts
I had to take the search input reference from app-input
component using #inputComponent
. (There are other ways to get this).
app.component.html
<div class="search">
<!-- I create a variable on template called inputComponent -->
<app-input #inputComponent></app-input>
</div>
<table>
<caption>Statement Summary</caption>
<thead>
<tr>
<th scope="col">type</th>
<!-- <th scope="col" class="toto">img</th> -->
<th scope="col">longeur</th>
<th scope="col">largeur</th>
<th scope="col">tirant d'eau</th>
<th scope="col">equipage</th>
<th scope="col">annexe</th>
</tr>
</thead>
<body>
<!-- I pass the searchText string taken from inputComponent to our filter pipe -->
<tr *ngFor="let boat of boats | filter : inputComponent?.searchText">
<!-- <td data-label="img"><img [src]="boat.img" alt="boat" class="img"></td> -->
<td data-label="boat type">{{ boat.boatType }}</td>
<td data-label="longeur">{{boat.longeur}} cm</td>
<td data-label="largeur">{{boat.largeur}} cm</td>
<td data-label="tirant d'eau">{{boat.tirantEau}} cm</td>
<td data-label="equipage">{{boat.equipage ? "Oui" : "Non"}}</td>
<td data-label="annexe">{{boat.annexe ? "Oui" : "Non"}}</td>
</tr>
</tbody>
</table>
app.component.ts
import { Component, VERSION } from "@angular/core";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
// I use boats as payload to demonstrate the filter pipe functionality
boats = [
{
boatType: "a1a12",
img: "/assets/img/boat-img/semi-rigide.jpg",
longeur: 10,
largeur: 20,
tirantEau: 50,
equipage: false,
annexe: true
},
{
boatType: "EAEA",
img: "/assets/img/boat-img/eaea.jpg",
longeur: 10,
largeur: 20,
tirantEau: 50,
equipage: false,
annexe: true
},
{
boatType: "bcbc",
img: "/assets/img/boat-img/bcbc.jpg",
longeur: 10,
largeur: 20,
tirantEau: 50,
equipage: false,
annexe: true
},
{
boatType: "bcbc 2",
img: "/assets/img/boat-img/bcbc.jpg",
longeur: 10,
largeur: 20,
tirantEau: 50,
equipage: false,
annexe: true
}
];
}
input.component.ts
import { Component, Input } from "@angular/core";
@Component({
selector: "app-input",
template: `
<input
type="text"
placeholder="Chercher un bateau.."
[(ngModel)]="searchText"
/>
`,
styles: [
`
h1 {
font-family: Lato;
}
`
]
})
export class InputComponent {
searchText: string;
}
filter.pipe.ts
import { Pipe, PipeTransform } from "@angular/core";
@Pipe({
name: "filter"
})
export class FilterPipe implements PipeTransform {
transform(items: any[], searchText: string): any[] {
if (!items) return [];
if (!searchText) return items;
// TODO: need to improve this filter
// because at this moment, only filter by boatType
return items.filter(item => {
return item.boatType.toLowerCase().includes(searchText.toLowerCase());
});
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.