Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular highlight & dehighlight dynamic html using filters

I'm trying to write a set of filters to highlight and then dehighlight dynamically generated html:

Highlight filter:

app.filter('highlight', function ($sce) {
    return function (str, termsToHighlight) {
        // Sort terms by length
        termsToHighlight.sort(function (a, b) {
            return b.length - a.length;
        });
        var regex = new RegExp('(' + termsToHighlight.join('|') + ')', 'g');
        return $sce.trustAsHtml(str.toString().replace(regex, '<span class="highlightedSpan" style="background-color: yellow; ' +
            'font-weight: bold;">$&</span>'));
    };
});

Dehighlight:

app.filter('dehighlight', function ($sce) {
    return function (str) {

        var obj = $($.parseHTML(str));

        obj = obj.find('.highlightedSpan').replaceWith(function () { return this.innerHTML; });

        return $sce.trustAsHtml(obj.html());
    };
});

I'm trying to strip away the span tag and leave the original text, but I'm not sure if it's working or what to return. Str is the html string. Any help would be greatly appreciated!

like image 424
RandomUs1r Avatar asked Nov 17 '17 16:11

RandomUs1r


People also ask

What is attribute in Angular?

Attribute binding in Angular helps you set values for attributes directly. With attribute binding, you can improve accessibility, style your application dynamically, and manage multiple CSS classes or styles simultaneously.

What are types of directives in Angular?

The three types of directives in Angular are attribute directives, structural directives, and components.

What is attribute directive in Angular?

The attribute directive changes the appearance or behavior of a DOM element. These directives look like regular HTML attributes in templates. The ngModel directive which is used for two-way is an example of an attribute directive.


2 Answers

We found marking terms with Angular to be a non-trivial task and ended up using an outside library (Mark.js). Manipulating the html directly like that can break angular's scoping and create other issues. If each possible term is in it's own little html tag, then you can use a filter on each one to test against a shared list of terms (either passed in or as part of a service), just remember that the "filter" is finicky about what changing inputs will fire a dirty-check and re-evaluate.

like image 130
nclu Avatar answered Oct 22 '22 15:10

nclu


Just for completeness sake, I got it in the end, the find function was misbehaving from my POV.

Final solution for dehighlighting:

app.filter('dehighlight', function () {
    return function (str) {
        var obj = $('<div/>').append(str);

        obj.find('span.highlightedSpan').replaceWith(function () { return this.innerHTML; });

        return obj.html().toString();
    };
});
like image 43
RandomUs1r Avatar answered Oct 22 '22 15:10

RandomUs1r