Angularjs + Phonegap anchor tag does not open web page - angularjs

I am using AngularJS and PhoneGap to create a mobile app. I've a HTML string with anchor tag, which I display on screen using ng-bind-html. But when I touch the link on the phone it does not open the web site at all. My intention is to open the web site in new browser window. The string that I am passing into ng-bind-html is :
"www.google.com";
Also, Im using InAppBrowser Phonegap plugin for this. But this is still not working.
Please advice.

You can use :
www.google.com
More... https://docs.angularjs.org/api/ng/directive/a
OR
www.google.com
$( "#a_id" ).click(function() {
var url = $(this).attr('href')
var ref = window.open(url, 'random_string', 'location=no');
ref.addEventListener('loadstart', function(event) {
console.log(event.type + ' - ' + event.url);
} );
ref.addEventListener('loadstop', function(event) {
console.log(event.type + ' - ' + event.url);
} );
ref.addEventListener('exit', function(event) {
//console.log(event.type + ' - ' + event.url);
} );
});

I came across this problem to enable links in a twitter list which I was showing in my app.
I ended up using the following with a little help of jQuery:
1) use a filter to add a class to your links
html:
<span ng-bind-html="myLinks | externalLinks"></span>
filter in controller.js
.filter('externalLinks', function() {
return function(text) {
return String(text).replace(/href=/gm, "class=\"ex-link\" href=");
}
});
2) in your controller you can use jQuery to add a click event to the links (I am using a timeout to be sure the links are loaded into the DOM and don't forget to inject $timeout in your controller)
$timeout(function(){
jQuery('.ex-link').click(function (e) {
var url = jQuery(this).attr('href');
e.preventDefault();
var system = "";
if(device.platform == "iOS"){
system = "_blank";
}
else {
system = "_system"
}
window.open(url, system, "location=yes");
})
},1000);
Hope this helps.

Related

Fotorama - deep linking and browser history

I love the fact that Fotorama updates the URL with a hash specific to each slide, but when I use the browser back button the slideshow doesn't update to the previously viewed slide.
Is there a way to have Fotorama record the deep linking in the browser history, so that using the browsers back/forward buttons update the slide show accordingly?
Thanks
There is no built-in way to do that. Write your own solution, using 'fotorama:show' event and fotorama.show()method:
<script>
$(function () {
window.onpopstate = function (e) {
var hash = location.hash.replace(/^#/, '');
if (fotorama && hash) {
fotorama.show(hash);
}
};
var fotorama = $('.fotorama')
.on('fotorama:show', function (e, fotorama) {
var hash = fotorama.activeFrame.id || fotorama.activeIndex;
console.log('fotorama:show', hash);
if (window.history && location.hash.replace(/^#/, '') != hash) {
history.pushState(null, null, '#' + hash);
}
})
.fotorama({
startindex: location.hash.replace(/^#/, '')
})
.data('fotorama');
});
</script>
<!-- Fotorama -->
<div class="fotorama"
data-auto="false">
</div>
Attribute data-auto="false" is important!
Demo: http://jsfiddle.net/artpolikarpov/2Enwa/show/
Original fiddle: http://jsfiddle.net/artpolikarpov/2Enwa/ (not working because of iframe)

Backbone - Overriding app links

I am using the following code to divert all clicked links to the Backbone router instead of hitting the server:
$(document).delegate("a:not([data-bypass])", "click", function(evt) {
var href = $(this).attr("href");
var protocol = this.protocol + "//";
if (href && href.slice(0, protocol.length) !== protocol &&
href.indexOf("javascript:") !== 0) {
evt.preventDefault();
Backbone.history.navigate(href, true);
}
});
It works well enough but it is causing issues when trying to use "preventDefault", for example:
onCancel: function(e){
e.preventDefault();
this.hide();
}
The preventDefault function here is being ignored and Backbone is following the link. I managed to fix this by adding the following line of code to the top function:
if(evt.isDefaultPrevented())
return false;
But I am wondering if there is a better way to accomplish what I am trying to do?

Cannot get leaflet popup to work with angularjs directive (and partial)

I am trying to write a directive to fill a leaflet marker pop-up. I have been banging my head against the wall trying to figure out what I am doing wrong. My pop-up is always empty.
Any one successfully done this before?
Here is a plunker showing the problem:
http://plnkr.co/edit/53bebb?p=preview
marker.bindPopup(e[0]); instead of marker.bindPopup(clonedElement[0]);
Try this:
var directiveTag = $(document.createElement("search-results-map-marker-popup"));
var compiledDirective = $compile(directiveTag)(popupScope);
newMarker.bindPopup(compiledDirective[0]);
You can use the new support for Angular content in angular-leaflet-directive:
var html = '<br><span ng-class="thumbsUpClass(item)" ' +
'ng-click="addChoice(item,set)"><span class="popup-container"><span ' +
'class="icon-stack thumbs-up-stack"><i class="icon-sign-blank ' +
'icon-stack-base"></i><i class="icon-thumbs-up"></i></span></span></span>';
...
$scope.markers.push( { lat: ...,
lng: ...,
message: html,
getMessageScope: function() { return $scope; },
});

Sencha with phonegap Native open external link

I have deployed a native app android + ios with sencha touch + phonegap.
If we click a link inside the app it opens inside the app and we cannot go out.
Does someone now how it is posible to let links open into the phone browser?
window.open("yoururl", '_blank');
The phonegap version I used was 2.9.0 if I am not mistaken.
I had the same problem and solved it as follows:
Embed the JQuery javascript file in your project. In my case it was:
<script type="text/javascript" charset="utf-8" src="js/jquery-1.10.2.min.js"></script>
Then I wrote the following function, which I called in the onDeviceReady function:
function enableHttpLinks() {
$('.externalLink').click(function(e) {
e.preventDefault();
url = $(this).attr("href");
window.open(url, '_system');
});
}
In order for this function to work, you have a assign the class externalLink to all the links you want to open in the device browser, as shown below:
your link title
good luck...
Just add this function inside "launch" function, in the app.js like this:
launch: function() {
// Destroy the #appLoadingIndicator element
//Ext.fly('appLoadingIndicator').destroy();
// Initialize the main view
Ext.Viewport.add(Ext.create('yourApp.view.Main'));
// Voila :
Ext.Viewport.element.dom.addEventListener('click', function (e) {
if (e.target.tagName !== 'A') {
return;
};
var url = e.target.getAttribute('href');
var containsHttp = new RegExp('http\\b');
//if href value begins with 'http'
if(containsHttp.test(url)) {
e.preventDefault();
window.open(url, "_system"); // For iOS
navigator.app.loadUrl(url, {openExternal: true}); //For Android
}
else {
return;
}
}, false);
}, //...
Then you can build for android and iOS at the same time.

Tracking Site Activity (Google Analytics) using Backbone

I am looking the best way to track the Site Activity in Google Analytics for a web app made with Backbone and Requires.
Looking At Google's Page, I found this drop-in plugin - Backbone.Analytics.
My questions are:
1) using Backbone.Analytics, should I change backbone.analytics.js in order to add _gaq.push(['_setAccount', 'UA-XXXXX-X']);?
2) Are there other possible solutions/plugins?
I prefer "do it yourself" style :) It's really simple:
var Router = Backbone.Router.extend({
initialize: function()
{
//track every route change as a page view in google analytics
this.bind('route', this.trackPageview);
},
trackPageview: function ()
{
var url = Backbone.history.getFragment();
//prepend slash
if (!/^\//.test(url) && url != "")
{
url = "/" + url;
}
_gaq.push(['_trackPageview', url]);
}
}
And you add google analytics script to your page as usual.
You shouldn't have to change anything. Just add your Google Analytics code snippet, like normal, and include Backbone.Analytics as you would any other Javascript library.
Just figured i'd share how i'm doing it. This might not work for larger apps but I like manually telling GA when to track page views or other events. I tried binding to "all" or "route" but couldn't quite get it to record all the actions that I need automajically.
App.Router = BB.Router.extend({
//...
track: function(){
var url = Backbone.history.getFragment();
// Add a slash if neccesary
if (!/^\//.test(url)) url = '/' + url;
// Record page view
ga('send', {
'hitType': 'pageview',
'page': url
});
}
});
So i just call App.Router.Main.track(); after I navigate or do anything i want to track.
Do note that I use the new Analytics.js tracking snippet which is currently in public beta but has an API so intuitive that it eliminates the need for a plugin to abstract any complexity what so ever. For example: I keep track of how many people scroll to end of an infinite scroll view like this:
onEnd: function(){
ga('send', 'event', 'scrollEvents', 'Scrolled to end');
}
Good luck.
I wrote a small post on this, hope it helps someone:
http://sizeableidea.com/adding-google-analytics-to-your-backbone-js-app/
var appRouter = Backbone.Router.extend({
initialize: function() {
this.bind('route', this.pageView);
},
routes: {
'dashboard': 'dashboardPageHandler'
},
dashboardPageHandler: function() {
// add your page-level logic here...
},
pageView : function(){
var url = Backbone.history.getFragment();
if (!/^\//.test(url) && url != ""){
url = "/" + url;
}
if(! _.isUndefined(_gaq)){
_gaq.push(['_trackPageview', url]);
}
}
});
var router = new appRouter();
Backbone.history.start();
Regarding other possible solutions/plugins, I've used https://github.com/aterris/backbone.analytics in a few projects and it works quite well as well. It also has options for a few more things like event tracking which can be handy at some point in your analytics integration.
If you use the new universal analytics.js, you can do that like this:
var Router = Backbone.Router.extend({
routes: {
"*path": "page",
},
initialize: function(){
// Track every route and call trackPage
this.bind('route', this.trackPage);
},
trackPage: function(){
var url = Backbone.history.getFragment();
// Add a slash if neccesary
if (!/^\//.test(url)) url = '/' + url;
// Analytics.js code to track pageview
ga('send', {
'hitType': 'pageview',
'page': url
});
},
// If you have a method that render pages in your application and
// call navigate to change the url, you can call trackPage after
// this.navigate()
pageview: function(path){
this.navigate(path);
pageView = new PageView;
pageView.render();
// It's better call trackPage after render because by default
// analytics.js passes the meta tag title to Google Analytics
this.trackPage();
}
}
All answers seem to be almost good, but out-of-date (Sept. 2015). Following this Google devs guide: https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications
Here's my version of the solution (I've added the suggested call to ga('set'...) ):
MyRouter = Backbone.Router.extend
...
initialize: () ->
# Track every route and call trackPage
#bind 'route', #trackPage
trackPage: () ->
url = Backbone.history.getFragment()
# Add a slash if neccesary
if not /^\//.test(url) then url = '/' + url
# Analytics.js code to track pageview
global.ga('set', {page: url})
global.ga('send', 'pageview')
...
Just posting an update to this question as it seems to be one I get a lot from backbone.js developers I know or work with who seem to fall at the last hurdle.
The Javascript:
App.trackPage = function() {
var url;
if (typeof ga !== "undefined" && ga !== null) {
url = Backbone.history.getFragment();
return ga('send', 'pageview', '/' + url);
}
};
Backbone.history.on("route", function() {
return App.trackPage();
});
The Tracking Snippet:
<head>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||
function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();
a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;
a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script',
'//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-X', 'auto');
</script>
</head>
The Tracking Snippet should be available on any page you wish to track activity. This could be your index.html where all your content is injected, but some sites may have multiple static pages or a mix. You can include the ga('send') function if you wish, but it will only fire on a page load.
I wrote a blog post that goes in to more detail, explaining rather than showing, the full process which you can find here: http://v9solutions.co.uk/tech/2016/02/15/how-to-add-google-analytics-to-backbone.js.html

Resources