Angular 2 searchtext

Issue

I have a dropdown menu with a search function and a list with projects (and checkboxes) I would like to make the searchterm update the projects in that list.

example:

I have 5 projects:
– project1
– potato
– listItem1
– listItem2
– whatever

The idea is when you didn’t type anything you see all 5 items, and if you type “p” you would only see project1 and potato. This is my code so far:

<div id="dropdown-menu">
    <button id="show-users" (click)="showMenu = !showMenu">Project toevoegen</button> 
    <div id="drp-project-select">
        <div class="scroller" [hidden]="!showMenu">
            <div id="search-wrapper">
                <i class="fa fa-search"></i>
                <input [(ngModel)]="searchTerm" type="text" placeholder="Zoek op naam..." >
            </div>   
            <ul>
                <li *ngFor="#project of projectdata.LoginResponse?.ProjectVM, #i = index">
                    <label class="checkbox-label" >
                        <input type="checkbox" class="dropdown-checkbox" [(ngModel)]="project.isChecked" >
                        <span>{{project.Project}}</span>
                    </label>
                </li>
            </ul>
        </div>
    </div>
</div>

Solution

Use a filter pipe.
For a full example see https://plnkr.co/edit/4Il8QMlh9UYQ4hyrnU3W?p=preview

<input [(ngModel)]="searchTerm" type="text" placeholder="Zoek op naam..." #search>
...
<li *ngFor="#project of projectdata.LoginResponse?.ProjectVM | filter:'Project':search.value, #i = index">

Supports only to filter by one column, but shouldn’t be to hard to extend.
It returns the same result if there were no changes to prevent

EXCEPTION: Expression has changed after it was checked.

import {Pipe, PipeTransform} from 'angular2/core'

@Pipe({name: 'filter'})
export class FilterPipe implements PipeTransform {
  previousResult:any[];

  transform(value:any[], args:string[]) : any {
    if(!value || !args || args.length < 2 || !args[0] || !args[1]) {
      return value;
    }
    console.log('value: ' + value);
    console.log('args: ' + args);

    var result = value.filter((val) => {
      console.log('item: ' + val[args[0]])
      var contains = val[args[0]].indexOf(args[1]) > -1;
      console.log('found: ' + contains);
      return contains;
    });

    console.log(result);
    if(this.previousResult && this.previousResult.length == result.length) {
      for(var i = 0; i < result.length; i++) {
        if(this.previousResult[i] != result[i]) {
          console.log(i);
          this.previousResult = result;
          return this.previousResult;
        }
      }
    }
    this.previousResult = result;
    return this.previousResult;
  }
}

Answered By – Günter Zöchbauer

Answer Checked By – Senaida (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.