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>
2
  • Greg, reorder the sanitize function after filter(this.targetData, $event) and your map functions require modifications. Have a look here Commented Oct 7, 2019 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. Commented Oct 7, 2019 at 11:53

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

3 Comments

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
using this SO post you can update accordingly demo
it's ok for you demo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.