0

I have an input field to which I use a custom pipe to filter and it works really well. This is the main code:

private personContainsFilterTerm(person: PersonModel, filterTerm: string) {
  return person.firstName.toLocaleLowerCase().includes(filterTerm)
  || person.lastName.toLocaleLowerCase().includes(filterTerm)
  || formatDate(person.dateOfBirth,'dd.MM.yyyy', 'de- 
  DE').toLocaleLowerCase().includes(filterTerm);
}

So if I put in 'john' or 'John' it will return any item that has john in first name and last name. The data I am working with can return only the first 100 items (it is the way the DB works, I have no control over it) so if you just want people with first name as 'John' you need to filter futher. This is why I am using checkboxes and this code that I found here: Angular 6 Checkbox Filter (with adjustments)

 filterChange() {
  if(this.filterChoices.lastName || this.filterChoices.firstName || 
  this.filterChoices.dateOfBirth){
     this.filteredPeople = this.people.filter(person => 
      (person.lastName === this.searchText && this.filterChoices.lastName)
      || (person.firstName === this.searchText && this.filterChoices.firstName)
      || (person.dateOfBirth.toLocaleString() === this.searchText && 
      this.filterChoices.dateOfBirth)
    );
  }
  else {
   this.filteredPeople = this.people;
  }
}

Here is my problem: When I input 'John' and click the checkbox for first name, I do get only the list of people with 1st name John However, if I put in 'john' (lowercase) then I get no results. So if someone spells Jonathon as Johnaton, I won't get any results for this. searchText in the case of checkboxes needs an exact match. How can I solve this? I tried to use includes, and substrings but none of them work.

MyHTMLCode

    <mat-form-field>
    <mat-label>People (max 100)</mat-label>
    <input matInput type="text" placeholder="Enter a search term" [(ngModel)]="searchText">
            <mat-icon matPrefix svgIcon="tb-search"></mat-icon>
            <button mat-icon-button color="primary" matSuffix *ngIf="searchText" 
            (click)="searchText=''">
              <mat-icon svgIcon="close-small"></mat-icon>
            </button> 
    </mat-form-field>
                        
    <input type="checkbox" [(ngModel)]="filterChoices.lastName" (change)="filterChange()" 
    (click)="$event.stopPropagation();"/> Last Name 
    <input type="checkbox" [(ngModel)]="filterChoices.firstName" (change)="filterChange()" 
    (click)="$event.stopPropagation();"/> First Name 
    <input type="checkbox" [(ngModel)]="filterChoices.dateOfBirth" (change)="filterChange()" 
    (click)="$event.stopPropagation();"/> Date of Birth
                        
                        
    <container *ngFor="let person of filteredPeople | peopleFilter: searchText;" >
        <title>
            <div>
              <p>{{person.lastName}}, {{person.firstName}}</p>
              <p class="textWrapBy95PercLength subText">* {{person.dateOfBirth | 
              date:'dd.MM.yyyy'}}</p>
            </div>
        </title>                
    </container>

Stackblitz examples and questions I have looked at (stackblitz created as answers to questions) : https://stackblitz.com/edit/angular-rxjs-multi-option-filter-7t7aw9?embed=1&file=app/app.component.ts https://stackblitz.com/edit/angular-ivy-zsfhuf?file=src%2Fapp%2Fapp.component.ts https://stackblitz.com/edit/angular-form-filtering?file=src%2Fapp%2Fapp.component.html Angular 10+ checkbox filtering

Siobhan Holubicka
  • 147
  • 1
  • 4
  • 17
  • Do you know the Levenshtein distance ? https://en.wikipedia.org/wiki/Levenshtein_distance (he probably invented it because of matching problems with his last name imo). Here is an implementation : https://stackoverflow.com/questions/18516942/fastest-general-purpose-levenshtein-javascript-implementation – Julien Sep 08 '22 at 08:53

0 Answers0