0
votes

I would like to take the following user.component template and make it so that the string entered in the text input field filters the items in the users array. In other words, I only want those users in the array matching the string inputted to be displayed. How do I bind the input value to the view without creating a custom pipe? Since I am using Angular 6, I cannot use the 'filter' pipe anymore.

If I use an [(ngModel)] two-way binding directive, how do I filter the string passed into it inside my component without creating a custom pipe?

Here is the users.component.html template:

<div class="wrapper">
  <span id = "search-box"><input class = "col-lg-7" id= "search-input" type="text"  name="users" placeholder = "Search by name"></span>
  <span id= "people">{{users.length}} <span *ngIf = "users.length == 1">Person</span><span *ngIf = "users.length > 1">People</span></span>
  <div class="accordion" id="accordionExample">
  <div class="card" *ngFor = "let user of users">
    <div class="card-header" id="headingOne">
      <h5 class="mb-0">
        <button class="btn btn-link" type="button" data-toggle="collapse" [attr.data-target]="'#' + user" aria-expanded="true" aria-controls="collapseOne">
          {{user}}
        </button>
      </h5>
    </div>
      <div [attr.id]= "user" class="collapse" aria-labelledby="headingOne" data-parent="#accordionExample">
       <div class="card-body">
        <img src="./assets/user.jpg" id= "user-pic">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div><!-- end of .card -->
 </div><!--end of .accordion-->
</div><!--end of .wrapper -->

And here is the users.component.ts file:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit { 

 users: any[] = [
    "Bob",
    "James",
    "Mary"
  ];

  constructor() { }

  ngOnInit() {
  }
}

If I need to use a custom pipe, please tell me how to set this up?

3

3 Answers

2
votes

You can do it with (input). when input changing you have to filter your array. so using prototype pattern you have to keep a copy of your array.I have done an example for you. StackBlitz link

1
votes

If you don't want to use pipe then you can do the same thing in ts file. Instead of using the array variable in html use the function which returns the filtered result.

Sample demo is here - https://stackblitz.com/edit/angular-shghzh

0
votes

I dunno why you talking about custom pipe or anything else. I think best solution would be 1. Create another array, that will be used in your view filteredUsers: any[]. 2. Secondly add this code to your teamplate

   <input class = "col-lg-7"
    id="search-input"
    type="text"  name="users" 
    placeholder = "Search by name" 
    (onModelChange)='filterArray($event)'>

and change array in your ngFor.

 <div class="card" *ngFor = "let user of filteredUsers">
  1. Create function in your template.

filterArray(event){ this.filteredUsers = this.users.filter(user => user === event); }

In html

<div class="card" *ngFor = "let user of filteredUsers">

And it will work just nice.