Conditionally add target=“_blank” to links with Angular JS

I am building a navigation tree in Angular JS. Most links in the tree will point to pages within my website, but some may point to external sites.

If the href of a link begins with http:// or https:// then I am assuming the link is for an external site (a regex like /^https?:\/\// does the trick).

I would like to apply the target="_blank" attribute to these links. I was hoping to do this with angular when I am creating my links:

<ul>
    <li ng-repeat="link in navigation">
        <a ng-href="{{link.href}}" [add target="_blank" if link.href matches /^https?:\/\//]>{{link.title}}</a>
    </li>
</ul>

Can anyone help me out?

Thanks

Answers:

Answer

I was just about to create a directive as suggested and then realised that all you actually need to do is this:

<a ng-attr-target="{{(condition) ? '_blank' : undefined}}">
  ...
</a>

ng-attr-xyz lets you dynamically create @xyz, and if the value is undefined no attribute is created -- just what we want.

Answer

Update

Or use a directive:

module.directive('myTarget', function () {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          var href = element.href;
          if(true) {  // replace with your condition
            element.attr("target", "_blank");
          }
        }
    };
});

Usage:

<a href="http://www.google.com" my-target>Link</a>

When you don't need to use this with Angular routing you can simply use this:

<a href="http://www.google.com" target="{{condition ? '_blank' : '_self'}}">Link</a>
Answer

The proposed solutions will only work with hard-coded hrefs. They will fail if they are interpolated because angular will not have done any interpolation when the directive is run. The following solution will work on interpolated hrefs, and is based on Javarome's solution:

yourModule.directive('a', function() {
  return {
    restrict: 'E',
    link: function(scope, elem, attrs) {
      attrs.$observe('href', function(){
        var a = elem[0];
        if (location.host.indexOf(a.hostname) !== 0)
          a.target = '_blank';
      }
    }
  }
}
Answer

A more simple directive does not require changes in your HTML by handling all <a href="someUrl"> tags, and adding target="_blank" if someURL does not target the current host:

yourModule.directive('a', function() {
  return {
    restrict: 'E',
    link: function(scope, elem, attrs) {
      var a = elem[0];
      if (a.hostname != location.host)
         a.target = '_blank';
    }
  }
}

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.