Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open all links using system browser inside an ionic app

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

like image 967
Sebastian Hernandez Avatar asked Jan 27 '16 23:01

Sebastian Hernandez


People also ask

How do I open URL in Webview in Ionic 4?

If you want to open an URL in a so called in-app browser you can use the Browser API ( @capacitor/browser plugin): Capacitor 2: https://capacitorjs.com/docs/apis/browser. Capacitor 3 (soon to be released): https://capacitorjs.com/docs/v3/apis/browser.

Does Ionic support Webview?

Ionic Portals offers a supercharged native Web View component for iOS and Android that enables teams to add web-based experiences to native mobile apps.

What is ionic4?

Ionic 4 represents the culmination of more than two years of research and hard work transforming Ionic from “mobile for Angular” into a powerful UI Design System and app framework for every web developer in the world.


4 Answers

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.

like image 54
caiocpricci2 Avatar answered Sep 24 '22 22:09

caiocpricci2


Because the HTML is already rendered when it comes to Angular, and the inAppBrowser plugin only works if called by explicit Javascript, there is nothing you can do that doesn't involve manually changing the HTML or using plain javascript.

Changing the HTML is just a Bad Idea®, especially if you try to do it by using regex matching.

That leaves javascript:

Restangular.all('stories').getList().then(function(stories){
  $scope.stories = stories;
  updateLinks();
});

function updateLinks(){
  //use $timeout wait for items to be rendered before looking for links
  $timeout(function(){
      var $links = document.querySelectorAll(".stories .story a");
      for(var i =0; i < $links.length; i++) {
        var $link = $links[i];
        var href = $link.href;
        console.log("Hijacking link to ", href);
        $link.onclick = function(e){
          e.preventDefault();
          var url = e.currentTarget.getAttribute("href");
          window.cordova.inAppBrowser.open(url, "_system");
        }
      }
    });
}
like image 28
you786 Avatar answered Sep 21 '22 22:09

you786


Install next plugin:

cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git

Now, you can use _system, _blank or _self for destination:

window.open(url, '_blank');

More info: https://www.thepolyglotdeveloper.com/2014/07/launch-external-urls-ionicframework/

like image 32
Eduardo Cuomo Avatar answered Sep 25 '22 22:09

Eduardo Cuomo


You can override the default link tag functionality as seen here:

https://www.thepolyglotdeveloper.com/2014/12/open-dynamic-links-using-cordova-inappbrowser/

Best,

like image 20
Nic Raboy Avatar answered Sep 25 '22 22:09

Nic Raboy