How to allow external link in angularjs when using ng-bind-html - angularjs

Here is the rendered code
<div>dfdbfbdfbdfbdfbdfbfb gdfgfggtbrtb
<a href="www.github.com" target="_blank"> rtrtrt
</a>
<p></p>
</div>
I get this, when i click in the hyperlinked text
https://myapp.io/www.github.com

Remember to use HTTP protocol with external links, if you don't use HTTP before the link, it will be considered as local resource link. In your above mentioned code you should use
Github
Instead of
Github

Try <a href="https://www.github.com" target="_blank"> the link destination you pasted is relative to the domain you are in.

The easy way is to use $window in the controller and a ng-click in the view.
In the view:
<a ng-click="myFunctionToGoAwayFromAngularJS()">click me</a>
And in the controller:
$scope.myFunctionToGoAwayFromAngularJS = function () { $window.open("https://www.github.com"); };
Obviously you need to inject $window in your controller. This way you can assign ng-click in whatever tag you want, not only to anchor tags.

Related

How to make a button in ng-repeat open a full url link in ionic and angularfire?

Assuming i am using this in my controller
var messagesRef = firebase.database().ref().child("messages");
$scope.messages = $firebaseArray(messagesRef);
And in my html is
<li ng-repeat="message in messages">
<p>{{ message.user }}</p>
<p>{{ message.text }}</p>
<button href="{{ message.weblink }}">OPEN THIS LINK</button>
That {{website.weblink}} for example is www.google.com from my firebase database.
How can i make that button work to open www.google.com using that button because it is not working .
To summarize, <a ng-href=""> should be used instead of <button href="">.
Using Angular markup like {{hash}} in an href attribute will make the
link go to the wrong URL if the user clicks it before Angular has a
chance to replace the {{hash}} markup with its value. Until Angular
replaces the markup the link will be broken and will most likely
return a 404 error. The ngHref directive solves this problem. - ngHref

Links not working with ng-bind-html on mobile

I'm building a mobile app with Ionic using AngularJS.
In some of the views I would like to bind HTML code having multiple links, but somehow its not working on mobile.
In the browser it works just perfectly, but on mobile the link can not be clicked.
Text I would like to bind:
"Some text http://www.test.com"
My code in HTML:
<p ng-bind-html="testDetails"></p>
$sanitize is available, ngSanitize has been added as a dependency
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-sanitize.js"></script>
var appControllers = angular.module('starter.controllers', ['ngSanitize']); // Use for all controller of application.
Any idea?
Looks I've found a solution.
Somehow simple <a> tags with href attribute does not seem to be working on mobile with ng-bind-html.
Instead, I used:
<a href="" onClick="window.open('http://www.test.com', '_system', 'location=yes')"
target="_blank">http://www.test.com</a>
This just works perfectly, but it was necessary to bypass $sanitize in ng-bind-html by explicitly trusting the dangerous value (See AngularJS documentation).
https://docs.angularjs.org/api/ngSanitize/service/$sanitize
In Controller:
$scope.testDetails = '<a href="" onClick="window.open('http://www.test.com', '_system', 'location=yes')"
target="_blank">http://www.test.com</a>'
$scope.deliberatelyTrustDangerousSnippet = function(sniptext) {
return $sce.trustAsHtml(sniptext);
};
In HTML view:
<p ng-bind-html='deliberatelyTrustDangerousSnippet(testDetails)'></p>
Also I've found a good filter to do this work, if the data is received with simple <a href="">attributes:
https://gist.github.com/rewonc/e53ad3a9d6ca704d402e

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
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.
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");
}
}
});
}
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/
You can override the default link tag functionality as seen here:
https://www.thepolyglotdeveloper.com/2014/12/open-dynamic-links-using-cordova-inappbrowser/
Best,
<ul>
<li> <a href="#" ng-click='openlink($event)' data-link='https://www.link1.com'> Link 1 </a></li>
<li> <a href="#" ng-click='openlink($event)' data-link='https://www.link2.com'> Link2 </a></li>
<li> <a href="#" ng-click='openlink($event)' data-link='https://www.link3.com'> Link 3 </a></li>
</ul>
In controller -
angular.module('app', [])
.controller('LinkCtrl', function($scope) {
$scope.openlink = function($event)
{
if ($event.currentTarget && $event.currentTarget.attributes['data-link'])
{
window.open($event.currentTarget.attributes['data-link'], '_system', 'location=yes');
}
}
})

How to use angular.bootstrap twice?

I have a page where there are few tabs and I use angular+bootstrap.
I use angular.bootstrap initially.
Then I have another controller for showing different set of data in one of the tabs. when I try to use angular.bootstrap again, I get the error it cannot be bootstrapped twice. To make it simple, consider the following code.
<div id="mainpage" ng-controller="mainPageController">
<ul>
<li id="test1"> <a href="gototest1"> GoToTest1 </li>
<li id="test2"> <a href="gototest2"> GoToTest2 </li>
</ul>
</div>
<div id="gototest1">
this is some sample. I have another html page here which will be loaded as a tab
</div
The page for gototest1 looks like this
<div ng-controller="gototestcontroller>
Here comes the another widget from another controller and
I try to use angular.boostrap here again. And I get the error because it is already bootstrapped in mainPage
</div>
What is the best way to use angular.bootstrap here?
Angular bootstrap is used to manually initialize an Angular the document or an element.
https://docs.angularjs.org/guide/bootstrap
Angular cannot be initialized more than once on an element. Is there a reason you don't use automatic initialization, using ng-app?
It sounds like you could benefit from using the module ngRoute and applying the attirbute ng-view instead of trying to bootstrap twice.
https://docs.angularjs.org/api/ngRoute

AngularJS - (using Ionic framework) - data binding on header title not working

I'm using an AngularJS-based library called "Ionic" (http://ionicframework.com/).
This seems simple, but it isn't working for me.
In one of my views, I have the following
<view title="content.title">
<content has-header="true" padding="true">
<p>{{ content.description }}</p>
<p><a class="button button-small icon ion-arrow-left-b" href="#/tab/pets"> Back to home</a></p>
</content>
</view>
In the controller for the above view, I have
angular.module('App', []).controller('DetailCtrl', function($scope, $stateParams, MyService) {
MyService.get($stateParams.petId).then(function(content) {
$scope.content = content[0];
console.log($scope.content.title); // this works!
});
});
The data for this view is loaded via a simple HTTP GET service (called MyService).
The problem is that when I view this page,
<view title="content.title">
Doesn't display the title. It's just a blank. According to the Ionic documentation (http://ionicframework.com/docs/angularjs/controllers/view-state/), I think I'm doing the right thing.
It's strange that {{content.description}} part works, but content.title doesn't work?
Also, is it because I'm loading the content dynamically (via HTTP GET)?
By using the ion-nav-title directive (available since Ionic beta 14), the binding seems to work correctly.
Rather than
<ion-view title="{{content.title}}">
....
Do this
<ion-view>
<ion-nav-title>{{content.title}}</ion-nav-title>
...
Works a treat.
A solution for newer versions of Ionic is to use the <ion-nav-title> element rather than the view-title property. Just bind your dynamic title inside the content of the <ion-nav-title> using curly brace syntax. Example:
<ion-view>
<ion-nav-title>
{{myViewTitle}}
</ion-nav-title>
<ion-content>
<!-- content -->
</ion-content>
</ion-view>
Here's a working example of how to accomplish this in Ionic. Open the menu, then click "About". When the "About" page transitions, you will see the title that was resolved.
As Florian noted, you need to use a service and resolve to get the desired effect. You then inject the returned result into the controller. There are some down sides to this. The state provider will not change the route until the promise is resolved. This means there may be a noticeable lag in the time the user tries to change location and the time it actually occurs.
http://plnkr.co/edit/p9b6SWZmBKWYm0FIKsXY?p=preview
If you look at ionic view directive source on github, it's not watching on title attributes which means it won't update your view when you set a new value.
The directive is processed before you receive the answer from server and you fill $scope.content.title.
You should indeed use a promise in your service and call it in a resolver. That or submit a pull request to ionic.
I was encountering the same problem and was able to solve it by wrapping my title in double-curlies.
<ion-view title="{{ page.title }}">
I should note that my page.title is being set statically by my controller rather than from a promise.
I had a very similar issue where the title wouldn't update until i switched pages a couple of times. If i bound the title another place inside the page, it would update right away. I finally found in the ionic docs that parts of those pages are cached. This is described here http://ionicframework.com/docs/api/directive/ionNavView/
To solve my issue, I turned caching off for the view with the dynamic title:
<ion-view cache-view="false" view-title="{{title}}">
...
</ion-view>
I got this to work on older versions of Ionic using the <ion-view title={{myTitle}}> solution (as per plong0's answer).
I had to change to <ion-view view-title= in the more recent versions. However using beta-14 it's showing blank titles again.
The nearest I've got to a solution is to use $ionicNavBarDelegate.title(myTitle) directly from the controller. When I run this it shows the title briefly and a moment later blanks it.
Very frustrating.
It's the first time that I worked with dynamic title in Ionic 1.7 and I run into this problem. So I solved using $ionicNavBarDelegate.title(') from the controller, as mentioned Kevin Gurden. But additionally, I used cache-view="false".
View:
<ion-view cache-view="false"></ion-view>
Controller:
angular
.module('app', [])
.controller('DemoCtrl', DemoCtrl);
DemoCtrl.$inject = ['$ionicNavBarDelegate'];
function DemoCtrl($ionicNavBarDelegate) {
$ionicNavBarDelegate.title('Demo View');
}
Use ion-nav-title instead of the directive view-title.
see http://ionicframework.com/docs/api/directive/ionNavTitle/
This is the true solution: data bind the ion-nav-title directive
<ion-view>
<ion-nav-title ng-bind="content.title"></ion-nav-title>
<ion-content has-header="true" padding="true">
<p>{{ content.description }}</p>
<p><a class="button button-small icon ion-arrow-left-b" href="#/tab/pets"> Back to home</a></p>
</ion-content>
</ion-view>
http://ionicframework.com/docs/api/directive/ionNavTitle/
I m using ionic v1.3.3 with side menus based template. I tried all solutions given above but no luck.
I used the delegate from $ionicNavBarDelegate:
http://ionicframework.com/docs/v1/api/service/$ionicNavBarDelegate/
I created a function inside my angular controller to set the title :
angular.module('app.controllers').controller('contributionsCtrl', contributionsCtrl);
function contributionsCtrl($scope, $ionicNavBarDelegate) {
vm.setNavTitle = setNavTitle;
function setNavTitle() {
var title = "<span class='smc_color'> <i class='icon ion-images'></i> Your Title </span>"
$ionicNavBarDelegate.title(title);
}
}
Then inside my html just called the function vm.setNavTitle
<ion-view overflow-scroll=true ng-init="vm.setNavTitle()">
<ion-content></ion-content>
</ion-view>
<ion-view> <ion-nav-title>{{ result.title }}</ion-nav-title>
This work for me

Resources