0

I built a search component to search for names in a list.

List that is grouped by date.

When I enter the search field I would like the items in the list to highlight if they match with the search.

I could do it in a pipe but when I postpone the code in a component the highlighting does not work anymore.

Pipe : https://stackblitz.com/edit/angular-searchpipe-bmzzez

Component: https://stackblitz.com/edit/highlihgt

I use DomSanitizer to display the text in the html, but it does not work.

I do not know if DomSanitizer is the best solution.

The function of the component that should display the highlight :

   handleChange($event: string) {
     function filter(messageArray, value) {
      function subFind( array, [key, ...keys]) {
         return keys.length
          ? array
        .map(o => {
          const temp = subFind(o[key], [keys]);
          return temp.length && Object.assign({}, o, { [key]: temp });
        })
        .filter(Boolean)
      : array.filter(o => o[key].toLowerCase().includes(value.toLowerCase()));
  }
  return subFind(messageArray, ['value', 'name']);
}
 this.filteredList = this.filteredList.map(item =>
  ({
    ...item,
    name: this._sanitizer.bypassSecurityTrustHtml(
      item.value.forEach(el => {
        el.name.replace($event, `<span style='font-weight:bolder'>${$event}</span>`);
      })
    )
  })
);
this.filteredList = filter(this.targetData, $event);
}

the html :

  <search-message (searchChanged)="handleChange($event)"></search-message>
  <ul>
    <div *ngFor="let player of filteredList"> Team : {{player.key}}
        <li *ngFor="let eachplayer of player.value">
          <span [innerHTML]="eachplayer.name"></span>
      </li>
   </div>
 </ul>
Greg-A
  • 772
  • 1
  • 19
  • 41
  • Greg, reorder the sanitize function after `filter(this.targetData, $event)` and your map functions require modifications. Have a look [here](https://i.stack.imgur.com/DwJKp.png) – Chenna Oct 07 '19 at 10:27
  • @Chenna I agree with you, there is indeed a problem for the "name" which is not in the right place. He should be a child of value. – Greg-A Oct 07 '19 at 11:53

1 Answers1

2

Try adding style after filter method call like

 this.filteredList = filter(this.targetData, $event);
     this.filteredList.forEach(i=>{
       i.value.forEach(v=>{
         v.name=this._sanitizer.bypassSecurityTrustHtml(`<span style='background:yellow'>${v.name}</span>`);
       })
     })

demo

jitender
  • 10,238
  • 1
  • 18
  • 44
  • This is not really the right solution because here the whole word is highlighted or it should highlight only the characters entered in the input field and match with the name, as in the pipe above – Greg-A Oct 09 '19 at 09:56
  • using [this SO post](https://stackoverflow.com/a/8644513/5621827) you can update accordingly [demo](https://stackblitz.com/edit/highlihgt-bcvmz4) – jitender Oct 09 '19 at 10:11
  • it's ok for you demo – Greg-A Oct 09 '19 at 14:34