AngularJS create html/link/anchor from text (escape/unescape html in view)

18,458

Solution 1

I think you can use Angular's linky filter for this: https://docs.angularjs.org/api/ngSanitize/filter/linky

You can use it like so:

<p ng-bind-html="post | linky"></p>

You'll have to include Angular's sanitize module for linky to work:

angular.module('myApp', [
    'ngRoute',
    'ngSanitize',
    'myApp.filters', 
    ...

Solution 2

You can use this replace for the string:

'please visit http://stackoverflow.com quickly'.replace(/(http[^\s]+)/, '<a href="$1">$1</a>')

then you'll need to use the $sce service, and ngBindHtml directive.

$sce is a service that provides Strict Contextual Escaping services to AngularJS.

So in your filter you need to wrap links with a tags then return a trusted html using $sce.trustAsHtml:

filter('createAnchors', function ($sce) {
    return function (str) {
        return $sce.trustAsHtml(str.
                                replace(/</g, '&lt;').
                                replace(/>/g, '&gt;').
                                replace(/(http[^\s]+)/g, '<a href="$1">$1</a>')
                               );
    }
})

Working examples: http://jsfiddle.net/T3fFt/11/

Share:
18,458

Related videos on Youtube

Daan
Author by

Daan

Updated on June 04, 2022

Comments

  • Daan
    Daan almost 2 years

    I have a controller that has an assigned value:

    $scope.post = 'please visit http://stackoverflow.com quickly';
    

    I have some text in my html:

    <p>{{post}}</p>
    

    I would like to make a clickable link of the url (surround it with anchor tags).

    I tried to change my html to:

    <p ng-bind-html="post | createAnchors"></p>
    

    Here is a simplified example of the problem:

    http://jsfiddle.net/T3fFt/4/

    The question is, how can I escape the whole post text, except for the link, which will be surrounded by anchor tags? ?

    • Kato
      Kato almost 10 years
      Why is there no accepted answer for this question. At least one of these are Kato approved. Make it so.
  • Daan
    Daan over 10 years
    Can you please tell me what functions exactely? I tried a few of them but didn't get it to work.
  • CD..
    CD.. over 10 years
    did you try trustAsHtml?
  • Daan
    Daan over 10 years
    Do I get it right: When you set ng-bind-html, Angular will not escape html. When you then manually set $sce.trustAsHtml, this is the same right? So in that case that won't help me
  • Daan
    Daan over 10 years
    The problem with this solution is that the rest of the text is not getting escaped. Check jsfiddle.net/T3fFt/5 where another anchor is not escaped. I updated my question with a jsfiddle.
  • CD..
    CD.. over 10 years
    I've lost you, you do not want to escape the string?
  • Daan
    Daan over 10 years
    When someone enters a url in the post, I want them to get anchor tags around them and THAT anchor tag should not be escaped but rendered as HTML. The REST of the post should be escaped, so a user cannot insert <script> tags or something.
  • Daan
    Daan over 10 years
    Yes like that, but than I don't want to escape every character myself (what you do now with the replace(/</g, '&lt;')) but want to use some function from Angular
  • CD..
    CD.. over 10 years
    No such function AFAIK.
  • exclsr
    exclsr almost 10 years
    I think the linky filter has been available since AngularJS 1.0: code.angularjs.org/1.0.2/docs/api/ngSanitize.filter:linky
  • GFoley83
    GFoley83 over 9 years
    @Daan I'm on Angular v1.2.21 and it works fine. <div ng-bind-html="post.Text | linky:'_blank'"></div>
  • Dylanthepiguy
    Dylanthepiguy almost 8 years
    A word of warning to anyone wanting to use linkyFilter: It escapes HTML characters so your raw HTML code (but with links) will show up in the html-bound element
  • exclsr
    exclsr almost 8 years
    Yes, @Dylanthepiguy, that is the desired behavior for this question.