Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to highlight a word in a paragraph in angular 2?

I have done this in angular 1.x but i want to know how to highlight a dynamic word in angular 2..in angular 1.x iam using a keyword

        <td><div highlight="var" keywords="somename">      {{paragraph}}</div></td>

I have done the above html by using the below angular-highlight.js .

     angular.module('angular-highlight', [])
      .directive('highlight', function()
    {

    var component = function(scope, element, attrs) {

    if (!attrs.highlightClass) {
        attrs.highlightClass = 'angular-highlight';
    }

    var replacer = function(match, item) {
        return '<span class="'+attrs.highlightClass+'">'+match+'</span>';
    }
    var tokenize = function(keywords) {
        keywords = keywords.replace(new RegExp(',$','g'), '').split(',');
        var i;
        var l = keywords.length;
        for (i=0;i<l;i++) {
            keywords[i] = '\\b'+keywords[i].replace(new RegExp('^ | $','g'), '')+'\\b';
        }
        return keywords;
    }

    scope.$watch('keywords', function() {
        //console.log("scope.keywords",scope.keywords);
        if (!scope.keywords || scope.keywords == '') {
            element.html(scope.highlight);
            return false;
        }


        var tokenized   = tokenize(scope.keywords);
        var regex       = new RegExp(tokenized.join('|'), 'gmi');

        //console.log("regex",regex);

        // Find the words
        var html = scope.highlight.replace(regex, replacer);

        element.html(html);
    });
}
return {
    link:           component,
    replace:        false,
    scope:          {
        highlight:  '=',
        keywords:   '='
    }
};
});
like image 395
Arron Avatar asked Apr 29 '16 11:04

Arron


People also ask

Is it possible to highlight text within HTML in AngularJS?

Things have changed between AngularJS and Angular, but the topic is still very valuable. Being able to manipulate HTML on the fly can solve many problems in Angular. We're going to see how to highlight text within HTML using a query string and simple replace logic.

How to highlight a specific search term in angular?

A very simple and straightforward highlight directive in Angular. We see something similar in chrome dev tools. The idea is pretty simple. We just have to match the searched term and somehow wrap the matched text in a span or mark ( ref) tag so that we can style them later according to our needs.

How do I highlight text in HTML?

First it makes sense to come up with some basic CSS for highlighting text. With the very simple CSS out of the way, we can have a look at the logic involved for manipulating the HTML. Open the project's src/app/app.component.ts file and include the following TypeScript code:

How to render HTML from a variable in angular?

The content displayed on the screen is powered by the p tag with the [innerHTML] attribute. The [innerHTML] attribute is very important as it allows us to render HTML from a variable. The data rendered comes from our highlight method. You just saw how to do a few things with Angular.


2 Answers

I would create a custom directive for this:

@Directive({
  selector: '[highlight]'
})
export class HighlightDirective {
  @Input()
  keywords:string;

  highlightClass: string = 'highlight';

  constructor(private elementRef:ElementRef,private renderer:Renderer) {

  }

  replacer(match, item) {
    return `<span class="${this.highlightClass}">${match}</span>`;
  }

  tokenize(keywords) {
    keywords = keywords.replace(new RegExp(',$','g'), '').split(',');
    return keywords.map((keyword) => {
      return '\\b'+keyword.replace(new RegExp('^ | $','g'), '')+'\\b';
    });
  }  

  ngOnChanges() {
    if (this.keywords) {
      var tokenized = this.tokenize(this.keywords);
      var regex = new RegExp(tokenized.join('|'), 'gmi');

      var html = this.elementRef.nativeElement.innerHTML.replace(regex, (match, item) => {
        return this.replacer(match, item);
      });

      this.renderer.setElementProperty(this.elementRef.nativeElement, 'innerHTML', html);
    }
  }
}

And use it like this:

@Component({
  selector: 'app'
  template: `
    <p highlight keywords="test,angular2">
    this is a test to highlight words with angular2
    </p>
  `,
  styles: [`
    .highlight {
      background-color: yellow;
    }
  `]
  directives: [ HighlightDirective ]
})
export class App {
}

According to the ViewEncapsulation used, you could need an hack (in the emulated one - default on) to add an attribute to be able to see styles applied:

replacer(match, item) {
  return `<span ${encapsulationAttribute} class="${this.highlightClass}">${match}</span>`;
}

ngOnChanges() {
  this.initializeEncapsulationAttribute();
  (...)
}

initializeEncapsulationAttribute() {
  if (!this.encapsulationAttribute) {
    var attributes = this.elementRef.nativeElement.attributes;
    for (var i = 0; i<attributes.length; i++) {
      let attr = attributes[i];
      if (attr.name.indexOf('_ngcontent') != -1) {
        this.encapsulationAttribute = attr.name;
        break;
      }
    }
  }
}

See this plunkr: https://plnkr.co/edit/XxB1pFEyUHlZetxtKMUO?p=preview.

like image 140
Thierry Templier Avatar answered Oct 17 '22 18:10

Thierry Templier


In case someone is interested in a simple (generic) solution, I came up with a directive (based on Thierry Templier work !).

This directive allows you to pass the text to work with, the search text and a class to apply :

import { Directive, ElementRef, Renderer, Input, OnInit } from '@angular/core';
import { escapeStringRegexp } from '../helpers/helper';

@Directive({
  selector: '[appColorSearchedLetters]'
})
export class ColorSearchedLettersDirective implements OnInit {
  @Input() search: string;
  @Input() text: string;
  @Input() classToApply: string;

  constructor(private el: ElementRef, private renderer: Renderer) { }

  ngOnInit() {
    if (typeof this.classToApply === 'undefined') {
      this.classToApply = '';
    }

    if (typeof this.search === 'undefined') {
      this.renderer.setElementProperty(this.el.nativeElement, 'innerHTML', this.text);
      return;
    }

    let search = escapeStringRegexp(this.search.toString());
    this.renderer.setElementProperty(this.el.nativeElement, 'innerHTML', this.replace(this.text, search));
  }

  replace(txt: string, search: string) {
    let searchRgx = new RegExp('('+search+')', 'gi');

    return txt.replace(searchRgx, `<span class="${this.classToApply}">$1</span>`);
  }
}

And the helper

import { escapeStringRegexp } from '../helpers/helper';

contains :

let matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;

export function escapeStringRegexp (str) {
  if (typeof str !== 'string') {
    throw new TypeError('Expected a string');
  }

  return str.replace(matchOperatorsRe, '\\$&');
};

This function is from https://www.npmjs.com/package/escape-string-regexp and credit goes to Sindresorhus.

Here's how I use it :

<span appColorSearchedLetters [search]="search" [text]="user.name" classToApply="searched"></span>
like image 6
maxime1992 Avatar answered Oct 17 '22 18:10

maxime1992