Creating customized push notification in Worklight - ibm-mobilefirst

is there a way to direct the user to another html page upon opening a push notification?
Thank you in advanced.

If you will take a look at the sample Worklight project for Push Notifications, you can see the following in common\js\main.js:
function pushNotificationReceived(props, payload) {
alert("pushNotificationReceived invoked");
alert("props :: " + JSON.stringify(props));
alert("payload :: " + JSON.stringify(payload));
}
This function tells the application to display 3 alerts, telling us that:
a push notification was received
its props
its payload
Instead of the above, or in addition, you could - depending on your method of multi-page navigation in your app - to navigate to another "page".
You can take a look at:
the multi-page navigation Worklight sample project
Learn how to do it using jQuery Mobile, or any other framework of your choosing... (stand-alone sample project showing multi-page navigation using jQuery Mobile)
Here is a small example.
These are the modifications I did to the Push Notifications sample project:
common\css\main.css
Added a successfulPush ID
#AppBody, #AuthBody, #successfulPush {
margin: 0 auto;
background-color: #ccc;
overflow: hidden;
overflow-y: auto;
}
common\index.html
Added an additional DIV:
<div id="successfulPush" style="display:none">
<div class="wrapper">
<h2>Notification received</h2>
<button id="back" >back to application</button>
<p id="pushContents"></p>
</div>
</div>
common\js\main.js
Modified the following function:
function pushNotificationReceived(props, payload) {
$("#AppBody").hide();
$("#successfulPush").show();
$("#pushContents").html(
"<b>Notification contents:</b><br>" +
"<b>Payload:</b> " + JSON.stringify(payload) + "<br>" +
"<b>Props:</b> " + JSON.stringify(props)
);
}
Also binding the 'back' button in wlCommonInit:
$("#back").bind("click", function() {
$("#successfulPush").hide();
$("#AppBody").show();
});
The end result
After a push is received and you tap the notification in the notification bar, the app opens and you see the successfulPush DIV. There you have a button to return you to the AppBody DIV. Works just fine.
As explained, this is only one possible approach. You can do whatever you want...

Related

Polymer 2.0 capture long press on dynamically generated paper-cards

Issue: How to select multiple paper-cards and know which ones is selected on user long press/tap on the card.
Description:
I have dynamically generated paper-cards and I render them on the page using template Dom-repeat. At present I have included checkboxes on each paper-card so that the user can select those checkbox associated with the paper-card. That way the user on the screen can select multiple cards on which I can action the next functionality.
I guess the better user experience will be that the user be able to tap or click on the paper-card and be able to hold his finger/mouse for say .5sec and be able to select that card rather than checkbox style selection.
If I am able to get a working code snippet of how a multiple paper-card selection is used then I will be able to provide a better UX for the app.
Current Code Snippet:
(here I am using a paper-icon-button to get the user selected paper-card element).
<template is="dom-repeat" items="{{itemsList}}" as="item">
<paper-card style="float:center; width: 95%" class$="
{{_computeCardColorTran(item.type)}}" data-index$="{{item._id}}">
<paper-icon-button icon="icons:arrow-drop-down" style="color:
grey;" id$="bttn#{{item._id}}" item="[[item]]" on-
tap="doSomeDiffAction">
</paper-icon-button>
<iron-image class="pad"
src="../images/image1"
preload
sizing="contain"
style="" >
</iron-image>
</paper-card>
</template>
What I wish to have (something like below) -->
<template is="dom-repeat" items="{{itemsList}}" as="item">
<paper-card style="float:center; width: 95%" class$="
{{_computeCardColorTran(item.type)}}" data-index$="{{item._id}}"
something-like-user-pressed-longed="
callFunctionUserPressedForLong"
>
<paper-icon-button icon="icons:arrow-drop-down" style="color:
grey;" id$="bttn#{{item._id}}" item="[[item]]" on-
tap="doSomeDiffAction">
</paper-icon-button>
<iron-image class="pad"
src="../images/image1"
preload
sizing="contain"
style="" >
</iron-image>
</paper-card>
</template>
And in script javascript function in dom-module I can extract the paper-card selected
function callFunctionUserPressedForLong(e){
var id = e.model.item._id;
console.log('User pressed for long time on the paper-card = '+ id);
}
function doSomeDiffAction(e){
var id = e.model.item._id;
console.log('Not a long press event. User taped or clicked paper card button. Do different action e.g. open popup. = '+
id);
}
Thanks
You have to use on-down and on-up events from Polymer and watch time diff between these two events yourself.
In example below, on-down and on-up event functions are the same for both components (paper-card and paper-icon-button). Inside the on-down function (_onDown), the current time is saved to variable. Inside on-up method (_onUp) is detection for tap/click on button (if time diff between on-down and on-up is <0.5s and event target is the element with id=bttn#{{item._id}} and long-press somewhere inside paper-card (including paper-icon-button).
_onDown(e) {
this.startTime = Date.now()
}
_onUp(e) {
let id = e.model.item._id;
//stopPropagation because this is otherwise called twice - from paper-card and from paper-icon-button
e.stopPropagation()
let id = "1"
if (Date.now() - this.startTime > 500) {
console.log(`long press somewhere inside paper-card :: id=${id}`);
} else if (e.target.id == `bttn#${id}`) {
console.log(`Not a long press event. User taped or clicked paper card button :: id=${id}`);
}
}
<paper-card on-down="_onDown" on-up="_onUp">
<paper-icon-button on-down="_onDown" on-up="_onUp">Tap me</paper-icon-button>
</paper-card>

how do _mobile_* divs gets populated with html data when viewing a prestashop page in mobile

I want to understand how prestashop works regarding mobile displays.
I noticed in the used template, the header.tpl file contains the following html divs for mobile:
<div class="float-xs-right" id="_mobile_language_selector"></div>
<div class="float-xs-right" id="_mobile_user_info"></div>
<div class="float-xs-right" id="_mobile_cart"></div>
<div class="float-xs-right" id="_mobile_currency_selector"></div>
I also noticed that once I remove any of the components (for example the shopping card) from theme.yml:
global_settings:
configuration:
PS_IMAGE_QUALITY: png
modules:
to_enable:
- ps_linklist
hooks:
modules_to_hook:
displayNav1:
- ps_contactinfo
- tuxinmodaccessibility
displayNav2:
- ps_languageselector
- ps_currencyselector
- ps_customersignin
REMOVE THIS LINE ->>> - ps_shoppingcart
displayTop:
then the cart component is not displayed in the navbar. so the mobile and deskop version required this configuration to be set.
I noticed also that for each component besides having main div with _mobile_ prefix, there are also divs with _desktop_ prefix.
I'm trying to find out how to properly add my accessibility component to the navbar and that it will also be displayed on mobile.
so far it displays only on desktop and not on mobile so I was guessing that I need to add something like
<div class="float-xs-right" id="_mobile_tuxinmodaccessibility"></div>
no idea how to implement it properly.
I don't quite understand how for example, how this process works for mobile_cart div while the module name is ps_shoppingcart.
any information regarding the issue would be greatly.
You need to checkout themes/classic/_dev/js/responsive.js file.
The answer is in the theme.js file.
Script moves contents between desktop and mobile HTML elements in DOM. Every HTML element with ID that starts with id="_mobile_" gets content from corresponding desktop variation that starts with id="_desktop_" (if you inspect DOM in mobile view you'll notice that desktop elements got empty).
function o() {
u.default.responsive.mobile ? (0, s.default)("*[id^='_desktop_']").each(function(t, e) {
var n = (0, s.default)("#" + e.id.replace("_desktop_", "_mobile_"));
n.length && r((0, s.default)(e), n)
}) : (0, s.default)("*[id^='_mobile_']").each(function(t, e) {
var n = (0, s.default)("#" + e.id.replace("_mobile_", "_desktop_"));
n.length && r((0, s.default)(e), n)
}), u.default.emit("responsive update", {
mobile: u.default.responsive.mobile
})
}

How to keyboard navigate to reCAPTCHA in a modal dialog?

I need to open Google's latest reCAPTCHA widget in a popup (modal) dialog, a Dojo Dialog in my case, and I've got that working fine, but I just realized that the user cannot keyboard navigate to it.
When the reCAPTCHA widget is displayed in the main view, not a modal dialog, then of course the user can easily keyboard navigate to it.
Has anyone found a way to set focus on the reCAPTCHA widget so that the user can access it without a mouse when the reCAPTCHA is in a Dojo Dialog?
I did see that reCAPTCHA is generated within an <iframe>. Is that part of the hurdle - that keyboard navigation can't reach content within an iframe? I've even tried to call document.getElementById("recaptcha-anchor") since I saw that that's the id of the <span> that holds the "checkbox" - but that is returning null. How to reach an element within an iframe?
I have a jsfiddle example available for demonstration at
https://jsfiddle.net/gregorco/xqs8w5pm/5/
<script>
var onloadCaptchaCallback = function() {
console.log("jsfiddle: rendering captcha");
globalRecaptchaWidgetId = grecaptcha.render('captchaDiv', {
'sitekey' : '6LcgSAMTAAAAACc2C7rc6HB9ZmEX4SyB0bbAJvTG',
'callback' : verifyCaptchaCallback,
'tabindex' : 2
});
grecaptcha.reset();
}
var verifyCaptchaCallback = function(g_recaptcha_response) {
console.log("Response validated. Not a robot.");
};
</script>
<script src='https://www.google.com/recaptcha/api.js?onload=onloadCaptchaCallback&render=explicit' async defer></script>
<div id="testDiv">
<button type="dojo/form/Button" onClick="captchaPopup.show();">Open reCAPTCHA</button>
</div>
<div data-dojo-type="dijit/Dialog" data-dojo-id="captchaPopup" title="Human Verification" style="width:350px;">
Cannot keyboard navigate to the checkbox!
<table>
<tr>
<td>
<div id="captchaDiv"></div><br/>
</td>
</tr>
</table>
</div>
Give this fiddle a try. Normally Dijit dialogs don't work too well with iframes in them because it doesn't know how to parse the content inside an iframe. In this case, we can use some of Dojo's functions to work around it. One notable thing to point out is that I've disabled autofocus of the Dijit Dialog so that it won't automatically focus the closeNode inside the dialog.
After the dialog loads, tab>space will select the captcha.
This may help others facing similar issue, but with Bootstrap modal dialog. I found the following solution on GitHub. Add the following Javascript to override Bootstrap:
Bootstrap 3x
$.fn.modal.Constructor.prototype.enforceFocus = function () { };
Bootstrap 4x
$.fn.modal.Constructor.prototype._enforceFocus = function () { };

Google rending +1 button way above and left of page content

We have implemented google +1 buttons on our site and they have served reliably for some time. However we recently noticed that the buttons are not serving reliably. We rarely see them appear in their designated spaces.
For example on this page: Sample Page : you'll see a gray box of social buttons to left of the page. In it, there is SUPPOSED to be a Google +1 button.
We've requested the button with this code:
<div id="social-google" class="social">
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
<g:plusone size="medium"></g:plusone>
</div>
We've also tried this code:
<div id="social-google" class="social">
<!-- Place this tag where you want the share button to render. -->
<div class="g-plus" data-action="share" data-size="small" data-annotation="bubble"></div>
<!-- Place this tag after the last share tag. -->
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</div>
Occasionally we'll see a Google +1 button render but, more often than not, the space reserved for the button is apparently blank. When you examine things with firebug, you see that Google HAS attempted to render a button, but for some reason it has placed the button far above and left of the page boundaries.
Here is the top of the html Google generates for the button:
<div id="___plusone_0" style="position: absolute; width: 450px; left: -10000px;">
<iframe id="I0_1377554650466" width="100%" scrolling="no" frameborder="0" hspace="0 marginheight="0" marginwidth="0" style="position:absolute;top:-10000px;width:450px;margin:0px;border-style:none" tabindex="0" vspace="0" name="I0_1377554650466" src="https://apis.google.com/_/+1/fastbutton?bsv=o&usegapi=1&size=medium&hl=en-US&origin=http%3A%2F%2Fwww.comicbookresources.com&url=http%3A%2F%2Fwww.comicbookresources.com%2F%3Fpage%3Darticle%26id%3D47537&gsrc=3p&ic=1&jsh=m%3B%2F_%2Fscs%2Fapps- ...
As you can see Google gave its generated ___plusone_0 div a left position of -10000px and gave the inner iFrame a top position of -10000px. So the button is there. It's just floating out in space. If I manipulate theses position settings (to 0px) the button becomes visible in its appropriate spot.
Any idea why this would happen? Any idea how we can fix this?
You can try adding the following CSS declaration to your stylesheet:
#___plusone_0, #___plusone_0 iframe {
position:static !important;
}
This is a hackaround, so don't depend on it in long term.
Based on an old thread in Drupal Issues.
During the last few days I'm suffering from this problem too. I have a page building app. One of the widgets is google plus: users can enter a url, and the app generates a button. (So there can be more, than 1 button on the page.) Then user saves the page and can see it on Facebook.
Recommendations and observations...
Double check the protocol of google api script. For example, if your website is on https and you are trying to load http://apis.google.com/js/plusone.js, your buttons will probably fail to render.
When I tested this issue on my server, I occasionally opened the app in 2 browser tabs at the same time. Google buttons didn't appear in the first tab, but they did in the second one!
My app requires user to be authorized on Facebook. When I opened the app without authorization, the buttons were shown as expected. But when I logged in and refreshed the page - buttons disappeared.
When I opened the page on Facebook, buttons didn't appear, regardless of whether I was logged in or not.
I beg your pardon, if you think these notices have no sense, but they may save someone's time in future.
Workaround
Suppose, you're parsing the following code:
<!-- google button will be added into this div -->
<div class="googlePlus" data-href="http://google.com"></div>
jQuery function, which parse all .googlePlus divs.
$('.googlePlus').each(function () {
var $googleDiv = $(this);
// check, if button is already parsed
if (!$googleDiv.children().length) {
// add temporary id to the parent div
var $id = 'googlePlus-' + new Date().getTime();
$div.attr({
'id': $id
});
// create, add and render btn (IE compatible method)
var gPlusOne = document.createElement('g:plusone');
gPlusOne.setAttribute('href', $googleDiv.attr('data-href'));
document.getElementById($id).appendChild(gPlusOne);
gapi.plusone.go($id);
// function, correcting css styles
if (!$.isFunction($.fn.fixGooglePlus)) {
$.fn.fixGooglePlus = function () {
$(this).children('div').children('iframe').addBack().css({
position: 'static',
width: 106,
height: 24
});
}
}
// run function, until css is fixed
var $timer = setInterval(function () {
$googleDiv.fixGooglePlus();
if ($googleDiv.find('iframe').css('position') == 'static') {
clearInterval($timer);
$googleDiv.removeAttr('id');
}
}, 100);
} // button hasn't been parsed
});
Put the button code in a a new HTML file and put that file in an iframe. Compared to #U-D13's answer, it's less susceptible to changes by Google.

WIndows 8 Metro List View Event Listener

I am trying to create a simple HTML Metro App for Windows 8. I want to display a list view, and based on the clicked item display different content on the screen. It sounds trivial, right?
But it doesn't work! Here is my code:
<div id="frameListViewTemplate" data-win-control="WinJS.Binding.Template">
<img data-win-bind="src: picture" class="thumbnail" />
</div>
<div id="basicListView" data-win-control="WinJS.UI.ListView"
data-win-options="{itemDataSource : DataExample.itemList.dataSource, itemTemplate: select('#frameListViewTemplate'),onselectionchanged : handler}">
</div>
Than in the defult.js
var myListView = document.getElementById("basicListView").winControl;
myListView.addEventListener("selectionchanged", handler);
And the handler:
function handler() {
console.log("Inside the handler : ");
}
handler.supportedForProcessing = true;
So the handler is never called. My questions are: How can I add an event listener and its handler to the listview control.
How can I recognize which element on the list view was clicked.
P.S.
The listview is displayed properly in my app.
Thank you for help,
J
To get the item that is "clicked", you need to use itemInvoked. Selection changed would happen when the user cross slides on the item to select it, rather than taping/clicking to "invoke" it.
http://msdn.microsoft.com/en-us/library/windows/apps/br211827.aspx has some basic details.