Search code examples
angularinnerhtml

How to make hashtags in a string clickable and access the value of clicked word in Angular?


I am trying to make the hashtags present inside a string clickable and get their value so that I know which hashtag has been clicked. I have tried to use innerHTML for this purpose by passing it a custom component but it's not working.

In my parent component, I replace hashtags with the markup for my child component:

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  tweet = 'This is a test tweet with a couple of #Hashtags in #Angular';
  ngOnInit() {
    this.tweet = this.tweet.replace(
      /#(\S+)/g,
      `<hello hashtag=\"$1\"></hello>`
    );
  }
}

And in the child component, hello, I display the hashtag and bind click method to it:

@Component({
  selector: 'hello',
  template: `<span *ngIf="hashtag" (click)="clickHashtag()">{{hashtag}}</span>`,
  styles: [],
})
export class HelloComponent {
  @Input() hashtag: string;
  clickHashtag() {
    alert(this.hashtag);
  }
}

But the child component hello is not rendered at all. How could I resolve this?

StackBlitz link


Solution

  • There a better approach that addEventListener to "each" element: this SO

    but first you need inject in constructor DomSanitizer

      constructor(private sanitizer:DomSanitizer){}
      ngOnInit() {
        this.tweet = this.sanitizer.bypassSecurityTrustHtml(this.tweet.replace(
          /#(\S+)/g,
          `<hello hashtag=\"$1\">$1</hello>`
        ));
      }
    

    you "check" the click in the div

    <div (click)="click($event.target)" [innerHTML]="tweet"></div>
    

    In the click you check about the "tagName"

      click(el:any)
      {
        if (el.tagName.toUpperCase()=="HELLO")
          alert(el.getAttribute('hashtag'))
      }
    

    You can also add a .css in styles.css to show that it's "clickable"

    hello{
      color:red;
      cursor:pointer
    }
    hello:hover{
      text-decoration: underline overline;
    }
    

    See stackblitz

    NOTE: hello it's not a component, you use hello or you can use <strong> or any html tag inline