iOS share sheet fires twice [Cordova/Ionic/Angular] - ios

For some reason, the share sheet in iOS is firing twice when I press the n-click share button in my app menu (i.e. first one sheet comes into view, followed by another on top of it).
menu.html...
<ion-nav-buttons side="right">
<button ng-cloak ng-if="sharable" ng-click="systemShare()" class="button button-icon button-clear ion-share"></button>
</ion-nav-buttons>
controller.js...
.controller('dataCtrl', function($scope, $rootScope, $stateParams, dataService, $cordovaSocialSharing) {
dataService.getData($stateParams.itemId).then(function(data){
$scope.data = data;
// set sharable
$rootScope.sharable=true;
document.addEventListener("deviceready", function () {
$rootScope.systemShare = function(){
$cordovaSocialSharing
.share($scope.data.title, $scope.data.title, null, $scope.data.url)
.then(function(result) {
// Success!
}, function(err) {
// An error occured. Show a message to the user
},false);
}
});
});
})
I have a couple controllers that follow this same pattern (and the code for each is basically identical in terms of what is shown above). They fetch the data, populate the view, then define the share button functionality and parameters using $rootScope.
The first time the button is presses it fires twice. Sometimes it happens a second time, but not always. The double-firing happens regardless of which version of the view/controller above is used first (that is, I have a controller for tours and a controller for stops: both are pretty much the same and whichever one I go to first will exhibit this behavior).
I'm guessing I need to change the way I define the systemShare() function, but I'm not sure how to do it other than via $rootScope since it needs to be accessible via the global menu.

Looks like this is an Ionic bug. See:
https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin/issues/465
The suggested fix (which worked for me) is to wrap the call in a timeout.
setTimeout(function() {
$cordovaSocialSharing
.share('Subject', 'Message', null, 'http://www.google.com') // Share via native share sheet
.then(function(result) {
console.log(result);
}, function(err) {
alert('Sharing failed. Please try again.');
});
}, 500);

Related

Is it possible to add buttons and control its event to toolbar of inappbrowser using javascript...?

I am developing a Hybrid App for iOS and Android using PhoneGap.Is it possible to add buttons and control its event to toolbar of inappbrowser using javascript.I know how to add it through ios native side but i cant use that process.I need to control the button event through a javascript method.
You have two options to do that.
The first option is, obviously, to patch the native plugin code, and that's it. Here you can find an example made for iOS, you will have to do the same to your Android Java code and for every other platform you want to support.
Another option is to hide the native toolbar and inject HTML and CSS to create a new one when the page is loaded.
Something like this:
// starting inappbrowser...
inAppWindow = window.open(URL_TO_LOAD, '_blank', 'location=no');
// Listen to the events, we need to know when the page is completely loaded
inAppWindow.addEventListener('loadstop', function () {
code = CustomHeader.html();
// Inject your JS code!
inAppWindow.executeScript({
code: code
}, function () {
console.log("injected (callback).");
});
// Inject CSS!
inAppWindow.insertCSS({
code: CustomHeader.css
}, function () {
console.log("CSS inserted!");
});
And you will have obviously to define the CustomHeader object, something like this:
var CustomHeader = {
css: '#customheader { your css here }',
html: function() {
var code = 'var div = document.createElement("div");\
div.id = "customheader";\
// Insert it just after the body tag
if (document.body.firstChild){ document.body.insertBefore(div, document.body.firstChild); } \
else { document.body.appendChild(div); }';
return code;
}
};
I had experience with this problem.
For my case, the second option was enough, not a critical task. Sometimes it takes a lot for the loadstop event to fire, and so you don't see the injected bar for >= 5 seconds.
And you have to pay attention even on the CSS of the loaded page, because obviously you can affect the original CSS, or the original CSS can affect the style of your toolbar.

Jquery mobile How to tap the screen to no avail

I tested on the Apple device, and when I click on the screen when there is no effect. This is my code. Click on the events of this writing there are questions?
<script>
$(function() {
$('#test').tap(function() {
$('#menuNum').text('1');
})
})
</script>
You need to change few things.
Do not use $(function() { or classic document ready to check for a correct state, they can cause problems with jQuery Mobile. Instead use jQuery Mobile alternative called page events.
Then don't bind tap event like that, use proper modern way of doing that. In your case element must be loaded into the DOM for that kind of binding to work. And because of $(function() { sometimes it can happen that element is still loading when binding is executed. So use it like this:
$(document).on('tap','#test',function() {
$('#menuNum').text('1');
});
This method don't care if element exist or not, it will even work if element is loaded into the DOM after binding process.
Working example: http://jsfiddle.net/Gajotres/SQ7DF/
In the end you want something like this:
$(document).on('pagebeforeshow', '#index', function(){
$(document).on('tap','#test',function() {
alert('Tap');
});
});

How to make Google Analytics count pop up posts

I have a wordpress site where you can view posts in two ways. You can view them on their single page or you can click on thumbs from the homepage and view them in an ajax popup that shows the full post. My problem obviously is that Analytics isn't counting the popup views. I use a template to popup the post and I'm looking for a way to make analytics recoginze it as a page view and tell me what post it was. I tried adding the analytics code to the top of the template page but that didn't do anything. Any ideas? I use the SimpleModal jquery plugin to popup posts and call them like this.
jQuery(document).ready(function() {
jQuery('a.postpopup').live('click', function(){
var id = jQuery(this).attr('rel');
jQuery('<div id="ajax-popup"></div>').hide().appendTo('body').load('http://mysite.com/ajax-handler/?id='+id).modal({
opacity:90,
position: ["0%"],
containerCss:{width:"100%"},
overlayClose:true,
onOpen: function (dialog) {
dialog.overlay.fadeIn('200', function () {
dialog.data.hide();
dialog.container.fadeIn('500', function () {
dialog.data.fadeIn('slow');
});
});
},
onClose: function (dialog) {
dialog.data.fadeOut('slow', function () {
dialog.container.hide('500', function () {
dialog.overlay.fadeOut('200', function () {
$.modal.close();
});
});
});
}
});
return false;
});
});
you can simulate a page view by using _trackPageView
Google Analytics has several options to track non-pageview related user activity that I think you could use here:
Virtual pageviews - as mentioned by user273895, you can add the call to your code when the dialog pops-up to see a "fake" pageview in your reports with a title like '/popup/post-name'
Events - you can instrument the above call with an event, for example: _trackEvent("popup", "click", "post-name"). The interaction is then trackable in the event reports and can be used to specify additional segments and filters for more advanced analysis.
Custom variables - you can set up a page or session level custom variable to record the interaction.
I'd suggest the first 2 options. Personally I tend to use events for this sort of thing but in your case it may make more sense to use a virtual pageview.

Is there any way to control the layout of the close button on a jQuery Mobile custom select menu?

I have a custom select menu (multiple) defined as follows:
<select name="DanceStyles" id="DanceStyles" multiple="multiple" data-native-menu="false">
Everything works fine except that I want to move the header's button icon over to the right AND display the Close text. (I have found some mobile users have a problem either realising what the X icon is for or they have trouble clicking it, so I want it on the right with the word 'Close' making too big to miss.) There don't seem to be any options for doing that on the select since its options apply to the select bar itself.
I have tried intercepting the create event and in there, finding the button anchor and adding a create handler for that, doing something like this (I have tried several variations, as you can see by the commenting out):
$('#search').live('pagecreate', function (event) {
$("#DanceStyles").selectmenu({
create: function (event, ui) {
$('ul#DanceStyles-menu').prev().find('a.ui-btn').button({
create: function (event, ui) {
var $btn = $(this);
$btn.attr('class', $btn.attr('class').replace('ui-btn-left', 'ui-btn-right'));
$btn.attr('class', $btn.attr('class').replace('ui-btn-icon-notext', 'ui-btn-icon-left'));
// $(this).button({ iconpos: 'right' });
// $btn.attr('class', $btn.attr('class').replace('ui-btn-icon-notext', 'ui-btn-icon-left'));
// // $btn.attr('data-iconpos', 'left');
$(this).button('refresh');
}
});
}
});
});
So I have tried resetting the button options and calling refresh (didn't work), and changing the CSS. Neither worked and I got weird formatting issues with the close icon having a line break.
Anyone know the right way to do this?
I got this to work cleanly after looking at the source code for the selectmenu plugin. It is not in fact using a button; the anchor tag is the source for the buttonMarkup plugin, which has already been created (natch) before the Create event fires.
This means that the markup has already been created. My first attempt (see my question) where I try to mangle the existing markup is too messy. It is cleaner and more reliable to remove the buttonMarkup and recreate it with my desired options. Note that the '#search' selector is the id of the JQ page-div, and '#DanceStyles' is the id of my native select element. I could see the latter being used for the id of the menu, which is why I select it first and navigate back up and down to the anchor; I couldn't see any other reliable way to get to the anchor.
$('#search').live('pagecreate', function (event) {
$("#DanceStyles").selectmenu({
create: function (event, ui) {
$('ul#DanceStyles-menu').prev().find('a.ui-btn')
.empty()
.text('Done')
.attr('class', 'ui-btn-right')
.attr("data-" + $.mobile.ns + "iconpos", '')
.attr("data-" + $.mobile.ns + "icon", '')
.attr("title", 'Done')
.buttonMarkup({ iconpos: 'left', icon: 'arrow-l' });
}
});
});
The buttonMarkup plugin uses the A element's text and class values when creating itself but the other data- attributes result from the previous buttonMarkup and have to be removed, as does the inner html that the buttonMarkup creates (child span, etc). The title attribute was not recreated, for some reason, so I set it myself.
PS If anyone knows of a better way to achieve this (buttonMarkup('remove')? for example), please let us know.
the way i achieved it was changing a bit of the jquery mobile code so that the close button always came to the right, without an icon and with the text, "Close"
not the best way i agree. but works..
I got a similar case, and I did some dirty hack about this :P
$("#DanceStyles-button").click(function() {
setTimeout(function(){
$("#DanceStyles-dialog a[role=button]").removeClass("ui-icon-delete").addClass("ui-icon-check");
$("#DanceStyles-dialog .ui-title").html("<span style='float:left;margin-left:25px' id='done'>Done</span>Dance Styles");
$("#DanceStyles-dialog .ui-title #done").click(function() {
$("#DanceStyles").selectmenu("close")
});
},1);
} );

jQuery / jQuery UI - $("a").live("click", ...) not working for tabs

So I have some jQuery UI tabs. The source code is as follows:
HTML:
<div class="tabs">
<ul>
<li>Ranges</li>
<li>Collections</li>
<li>Designs</li>
</ul>
<div id="ranges"></div>
<div id="collections"></div>
<div id="designs"></div>
</div>
jQuery:
$(document).ready(function() {
$(".tabs").tabs();
});
My problem is that I am trying to make each tab load a page into the content panel on click of the relevant link. To start with I am just trying to set the html of all the panels on clicking a link. From the code below, if I use method 1, it works for all links. However if I use method 2 it doesn't - but only for the links in the tabs (i.e. the labels you click to select a tab).
Method 1 (works for all links all the time, but would not be applied to links which are added after this is called):
$("a").click(function () {
$("#ranges, #collections, #designs").html("clicked");
});
Method 2 (works for all links which are not "tabified"):
$("a").live("click", function () {
$("#ranges, #collections, #designs").html("clicked");
});
Does anyone know why it is behaving like this? I would really like to get method 2 working properly as there may well be links which I need to add click events to which are added after the page is originally loaded.
Thanks in advance,
Richard
PS yes the function calls for .live and .click are both in the $(document).ready() function, before anyone says that that may be the problem - otherwise it wouldn't work at all..
Edit:
The solution I came up with involves an extra attribute in the anchors (data-url) and the following code (which outputs a 404 not found error if the page cannot be loaded). I aim to expand this over the next few weeks / months to be a lot more powerful.
$(".tabs").tabs({
select: function (event, ui) {
$(ui.panel).load($(ui.tab).attr("data-url"), function (responseText, textStatus, XMLHttpRequest) {
switch (XMLHttpRequest.status) {
case 200: break;
case 404:
$(ui.panel).html("<p>The requested page (" + $(ui.tab).attr("data-url") + ") could not be found.</p>");
break;
default:
$(ui.panel).html("<p title='Status: " + XMLHttpRequest.status + "; " + XMLHttpRequest.statusText + "'>An unknown error has occurred.</p>");
break;
};
});
}
});
I don't know if I understand what you are going for but basically you want to do something once a tab is clicked?
Here's the docs for setting up a callback function for selecting a tab.
EDIT: Don't know if that link is working correctly, you want to look at select under Events. But basically it is:
$("#tabs").tabs({
select: function(event, ui) { ... }
});
Where ui has information on the tab that was clicked.
jQuery UI tabs has an outstanding issue where return false; is used instead of event.preventDefault();. This effectively prevents event bubbling which live depends on. This is scheduled to be fixed with jQuery UI 1.9 but in the meantime the best approach is use the built in select event as suggested by #rolfwaffle.
Maybe the tabs() plugin that you are using is calling event.preventDefault(); (Reference) once it has created it's tabs.
Then it captures the click event and the bubbling stops, so it doesn't invoke your click-function. In jQuery this is done with
$(element).click(function(){
// Do stuff, then
return false; // Cancels the event
});
You'd have to alter the tabs() plugin code and remove this return false; statement, OR if you are lucky, the plugin might have an option to disable that behavior.
EDIT: Now I see you're using jQuery UI. Then you should check the documentation there, since it is an awesome plugin, it will do anything you want if you do the html right and pass it the right options.

Resources