PDA

View Full Version : Open External Links in new browser from a Button



SimonFlack
4 Apr 2011, 10:27 AM
I had some problems using window.open() from a button and found out that apps running in standalone mode on the iPhone can only open "<a href" style links.

Someone on the forum also said he had similar problems with "tel" and I guess maybe "mailto" links as well.

So I have created a little plugin to open links from a standard button that works in standalone mode on iPhone.

demo: http://www.whitefox.no/plugins/linkButton/

plugin: http://www.whitefox.no/plugins/linkButton/simfla.ux.plugins.linkButton.js

Usage:

{
xtype: 'button',
linkId: 'myLink3',
url: 'tel:+4790992724',
text: 'Call: Simon Flack',
plugins: [ new simfla.ux.plugins.linkButton() ]
}

I will post it here just incase other people are having problems with this too.

trinitrotoluen
5 Apr 2011, 7:58 AM
nice , thanks man.

jeffzamo
24 May 2011, 3:27 PM
thanks for the plugin. what is the best way to dynamically change the url value?

SimonFlack
24 May 2011, 11:46 PM
I had to do this on a recent project (m.parkenfestivalen.no -->YouTube links).

Here is my current solution. I have added a setUrl function to the plugin. (I will update the official plugin when I find a better way to do this).


your_button.plugins[0].setUrl(your_button,YourNewLink);

Modified plugin.

/*Copyright (C) 2011 by WhiteFox AS

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.*/

Ext.ns('simfla.ux.plugins');

simfla.ux.plugins.fireEvent = function (obj,evt){
var fireOnThis = obj;
if( document.createEvent ) {
var evObj = document.createEvent('MouseEvents');
evObj.initEvent( evt, true, false );
fireOnThis.dispatchEvent(evObj);
} else if( document.createEventObject ) {
fireOnThis.fireEvent('on'+evt);
}
}

simfla.ux.plugins.linkButton = Ext.extend(Ext.util.Observable, {

init: function(cmp){
this.cmp = cmp;

if(cmp.url && cmp.linkId){

cmp.html = '<a id="' + cmp.linkId + '" style="position:absolute; width: 0px; height: 0px; opacity: 0;" href="' + cmp.url + '">&nbsp;</a>';
if(cmp.rendered && cmp.html && document.getElementById(cmp.linkId)){
document.getElementById(cmp.linkId).href = cmp.url;
}
cmp.handler = function(){simfla.ux.plugins.fireEvent(document.getElementById(cmp.linkId),'click');}
}
},
setUrl: function(cmp, url){
cmp.url = url;
cmp.plugins[0].init(cmp);
}
});


Ext.preg('editableList', simfla.ux.plugins.linkButton);


Hope this helps you out.

tkzic
28 May 2011, 5:47 PM
Simon,

Thanks for writing this plugin. It solved a huge problem with a project I'm working on.

tkzic

pixelpartner
29 May 2011, 3:27 AM
It will help me as well =D>

profunctional
28 Nov 2011, 5:44 PM
Trying to use setUrl and I get Uncaught TypeError: Cannot call method 'dispatchEvent' of null

Any idea why?

This is the line in the plugin that throws it

fireOnThis.dispatchEvent(evObj);

profunctional
28 Nov 2011, 8:12 PM
I got setURL working on the webapp. But when i try it on the device using PhoneGap, the button doesn't always register the click event. Seems like it takes a triple tap to launch the link. I am using a tel:xxxxx for the link.

Has anyone else seen this?

SimonFlack
28 Nov 2011, 11:13 PM
Hey. I have not had any problems with it so far but I am mainly using it the same way in most of our apps. How are you using the plugin? Can you post some code?

profunctional
29 Nov 2011, 6:15 AM
This is the code that I'm using in PhoneGap. I actually pasted your sample, then deployed to the device using PhoneGap. You must click at leaset 10 times to get the call prompt.


{ xtype: 'button', linkId: 'myLink3', url: 'tel:+4790992724', text: 'Call: Simon Flack', plugins: [ new simfla.ux.plugins.linkButton() ] }

SimonFlack
29 Nov 2011, 6:18 AM
What phone/device are you using to test with?

iOS Simulator will not work unless you hold in the "Alt" key.

profunctional
29 Nov 2011, 6:24 AM
Using a iPhone 4s with iOS 5

profunctional
29 Nov 2011, 6:28 AM
regular links to pages work. Only the tel: prefix to launch the dialer does not work.

SimonFlack
29 Nov 2011, 6:39 AM
Can you test this app..

www.itunes.com/app/parken2011

Last tab "Whitefox" --> Telephone button

Does that work or are you having the same problems?

Where is the button in the UI. On a toolbar? etc etc

profunctional
29 Nov 2011, 6:45 AM
That app works. Can you send me code on how you implemented that?

profunctional
29 Nov 2011, 7:56 AM
I'm also using phonegap 1.2.0.

SimonFlack
29 Nov 2011, 8:50 AM
We used PhoneGap Build service while it was in Beta.


dockedItems: [{ xtype: 'toolbar',
cls: 'parkentoolbar',
items: [{
xtype: 'button',
ui: 'parken',
iconCls: 'at',
iconMask: true,
linkId: 'mailwhitefox',
url: 'mailto:simon@whitefox.no',
plugins: [new simfla.ux.plugins.linkButton()]
},{
xtype: 'button',
ui: 'parken',
iconCls: 'phone1',
iconMask: true,
linkId: 'phonewhitefox',
url: 'tel:+4790992724',
plugins: [new simfla.ux.plugins.linkButton()]
},{
xtype: 'button',
ui: 'parken',
iconCls: 'info_plain2',
iconMask: true,
linkId: 'webwhitefox',
url: 'http://www.whitefox.no/app',
plugins: [new simfla.ux.plugins.linkButton()]
},{
xtype: 'container',
html: '<img src="images/foxplainsig.png" height="40" style="margin-top: 3px;">'
}]
}]

profunctional
29 Nov 2011, 8:58 AM
Is it possible that your plugin code posted in this thread is outdated? I just pasted your phone call button into my code and get the same behavior. I'm thinking the plugin I have is no good.

SimonFlack
29 Nov 2011, 9:02 AM
Here is the version I have been using in my apps.


/*Copyright (C) 2011 by WhiteFox AS

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:


The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.*/


Ext.ns('simfla.ux.plugins');


simfla.ux.plugins.fireEvent = function (obj,evt){
var fireOnThis = obj;
if( document.createEvent ) {
var evObj = document.createEvent('MouseEvents');
evObj.initEvent( evt, true, false );
fireOnThis.dispatchEvent(evObj);
} else if( document.createEventObject ) {
fireOnThis.fireEvent('on'+evt);
}
}


simfla.ux.plugins.linkButton = Ext.extend(Ext.util.Observable, {


init: function(cmp){
this.cmp = cmp;

if(cmp.url && cmp.linkId){

cmp.html = '<a id="' + cmp.linkId + '" style="position:absolute; width: 0px; height: 0px; opacity: 0;" href="' + cmp.url + '">&nbsp;</a>';
if(cmp.rendered && cmp.html && document.getElementById(cmp.linkId)){
document.getElementById(cmp.linkId).href = cmp.url;
}
cmp.handler = function(){simfla.ux.plugins.fireEvent(document.getElementById(cmp.linkId),'click');}
}
},
setUrl: function(cmp, url){
cmp.url = url;
cmp.plugins[0].init(cmp);
}
});



Ext.preg('linkbutton', simfla.ux.plugins.linkButton);

SimonFlack
29 Nov 2011, 9:06 AM
You dont have some other element masking the button like a "div" tag with width set to 100% or an image with transparency etc. Try setting the z-index (to a large number) of the button to bring it to the front.

profunctional
29 Nov 2011, 9:52 AM
I had to revert to using a straight <a href> link for the phone numbers. Here are a couple other issues I found with your latest plugin code for opening a webpage.

1. When you use the newest file with the iPhone simulator + PhoneGap 1.2, the webpage does not open.

2. When I reverted back to your old file (without setUrl), it opens fine in the simulator. However, when deployed on the actual device, the button opens some internal browser to show the webpage. There is no way to get back to the app.

SimonFlack
29 Nov 2011, 10:50 AM
There is a thread on PhoneGaps support forum about opening links in phone gap. Basically you will have to add some code to force the webview to open a new safari browser instead of opening within PhoneGaps webview.

Here is one article I found. http://solutions.michaelbrooks.ca/2011/02/15/open-external-links-in-safariapp/

The only thing that the plugin does is add a regular <a href=> to the buttons div tag. There is no real difference. Then I just use some javascript code to simulate a mouseclick on the link when the user taps the button.

try adding target="_blank"


cmp.html = '<a id="' + cmp.linkId + '" style="position:absolute; width: 0px; height: 0px; opacity: 0;" href="' + cmp.url + '" target="_blank">&nbsp;</a>'

profunctional
29 Nov 2011, 10:54 AM
I resolved the internal window issue by adding target="_blank" to your plugin. All is well for opening web pages. I still cannot open phone numbers, but that's ok.

bwags
17 May 2012, 6:19 AM
I fought this for at least a full day and found a solution I'm 1/2 way happy with.

I created a link w/id in my index.html like this:



<a id="uniqueLinkId" href="https://link.to.myExternalPage.html" target="_blank"></a>


Then with a listener on my button click:



onLinkButtonClick : function() {
Ext.Msg.confirm("Are you sure?",
"This is a message letting the user know that the button they are clicking on will hide the app.",
function(e) {


if (e == 'yes') {
var link = document.getElementById("uniqueLinkId");
var dispatch = document.createEvent("HTMLEvents");


dispatch.initEvent('click', true, true);
link.dispatchEvent(dispatch);
}
});
},



That got me what I wanted on iOS devices and on Android devices.

bwags