简体   繁体   中英

angular custom pipe & input search autocomplete

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM