Open all links using system browser inside an ionic app

Sebastian Hernandez picture Sebastian Hernandez · Jan 28, 2016 · Viewed 14.8k times · Source

I need that all links inside a certain section of my app open in the system browser. The trick is that those links come from an external source (an API) so I can't add the ng-click function that helps me to open the links externally.

I'm using in-app-browser plugin (ng-cordova). In fact I have other links that open externally but in this case the links can be in any part of the content so my question would be how could I add the ng-click directive to all links after they are loaded? or if it's possible, how to config in-app-browser plugin to open ALL links in system browser?

By the way, the simple links don't open even in the inappbrowser: I tap on them and nothing happens.

Thanks for the help

Answer

caiocpricci2 picture caiocpricci2 · Feb 20, 2016

AFAIK there isn't a way of doing that automatically, you must use the in app browser js code to open links externally consistently in every platform.

Your question doesn't give a clear example of what the server returns so I'm assuming you are getting a full block of html and are just rendering it on the screen. Assuming a request return something basic like :

<div id="my-links">
   <a href='http://externallink.com'> External Link 1 </a>
   <a href='http://externallink.com'> External Link 2 </a>
   <a href='http://externallink.com'> External Link 3 </a>
</div>

And your request looks like:

$http.get('givemelinks').success(function(htmlData){
   $scope.myContent = htmlData;
})

If you have access to the server side and can make changes:

Add a "inappbrowser" parameter to your request to detect if it should return inappbrowser compatible links and change the response from your server to be something like:

if (inappbrowser) {
<div id="my-links">
   <div ng-click='openExternal($event)' data-external='http://externallink.com'> External Link 1 </div>
   <div ng-click='openExternal($event)' data-external='http://externallink.com'> External Link 2 </div>
   <div ng-click='openExternal($event)' data-external='http://externallink.com'> External Link 3 </div>
</div>
} else {
 <div id="my-links">
   <a href='http://externallink.com'> External Link 1 </a>
   <a href='http://externallink.com'> External Link 2 </a>
   <a href='http://externallink.com'> External Link 3 </a>
</div>
}

And have a generic openExternal method:

$scope.openExternal = function($event){
  if ($event.currentTarget && $event.currentTarget.attributes['data-external'])
  window.open($event.currentTarget.attributes['data-external'], '_blank', 'location=yes');
}

If you can't change the server side

Parse the response and replace the links with ng-clicks:

$http.get('givemelinks').success(function(htmlData){
   htmlData = htmlData.replace(/href='(.*)'/,'ng-click="openExternal($event)" data-external="$1"').replace(/<a/,"<div").replace(/a>/,"div>")
   $scope.myContent = htmlData;
})

And use the same openExternal method as above.

I'm replacing the anchors with divs to prevent changing the app routes. That might not be necessary in every app.

To make this even better you should bundle it in a open-external directive so you can use it in multiple controllers and keep them cleaner.