Run process before load page - javascript

i am using cordova 6 with onsen-ui,jquery and javascript. So i am trying to make a simple login site, but i need to get if gps is active. I want to know WHERE i must do that validation. Now I do the following on ons.ready() event.
var options = {maximumAge: 0, timeout: 3000, enableHighAccuracy:true};
navigator.geolocation.getCurrentPosition(onGPSCheckSuccess, onGPSCheckError, options);
function onGPSCheckSuccess()
{
console.log("Encontro el GPS Activado");
}
function onGPSCheckError()
{
console.log("Error al chequear el GPS");
gpsDetect.switchToLocationSettings(onSwitchToLocationSettingsSuccess, onSwitchToLocationSettingsError);
}
function onSwitchToLocationSettingsSuccess() {
}
function onSwitchToLocationSettingsError(e) {
console.log("Error al activar el GPS");
alert("Error onSwitchToLocationSettingsError: "+e);
}
So if there a way to do this BEFORE my main page es loaded?
Regards

Actually, you can do a simple page redirect. You can have that code in a .htm file, which you call before your page. When this succeeds, you then store the result using localStorage, then redirect to the page you want, and retrieve the results from localStorage.

I think the best way to do this, it with the following code:
document.addEventListener("init", function(event){
if(event.target.id=='yourHomePageID') {
var options = {maximumAge: 0, timeout: 3000, enableHighAccuracy:true};
navigator.geolocation.getCurrentPosition(onGPSCheckSuccess, onGPSCheckError, options);
}
},false);
By using the init function for the homepage, this actually runs a bit before ons.ready() as discussed here by #fran-dios:
Onsen 2.0 - Adding event listener to Ons-Switch with Javascript
Hope this helps. It is what I am doing based on the aforementioned question and it solved my issue.

Related

IE is not refresh after call the download function

In the jsp, I use javascript, jquery and json to call a function for download, once the the download is finished, it will return the the current page.
However the problem is although the download is complete, I can able to download and view the file. In the screen, it still show the message indicate it is downloading.
I read this post, the accepted solution mentioned to disable the cache with ajaxSetup. I read my code, I have already include it in the code, however the Internet Explorer still not return to proper page when the download finished. Is there any method I can use to solve the problem. Thank you.
function startDownload() {
$.blockUI({ message: '<h1>Downloading, please wait...</h1>' });
var i = setInterval(function() {
$.ajaxSetup({ cache: false });
$.getJSON("ThePage/downloadProgress?jsoncallback=?",function(download_token) {
if (download_token.fileDownloadToken == "finished" ) {
$.unblockUI();
clearInterval(i);
}
});
}, 1000);
}
Update
I mentioned it occurs on IE because our company is mainly using IE for the web browser. So I intend to make to code works on the IE first. Sorry for the inconvenience that I have made.

How do you return a javascript object? it keeps throwing a "Converting circular structure to JSON"

I am working on an Ionic app, and I need to use firebase's phone authentication, to use that, I have to use google's recaptcha, which doesn't work in Ionic apps, so...
I made a web page that held the code for rendering the reCaptcha, and used cordova's inAppBrowser to navigate to it from inside my app.
after hours, I got everything working, and finally got the "recaptchaVerifier" object, that you need to pass to firebase.auth().signInWithPhoneNumber(phoneNumber,recaptchaVerifier)
.
I just need to pass the "recaptchaVerifier" object from the inAppBrowser, to my ionic app, I tried everything, and got stuck on a simple javascript function that would "return recaptchaVerifier" and I would grab it in Ionic, but it kept giving me Uncaught TypeError: Converting circular structure to JSON
What do I do? I just need to pass that object so I can send the verification sms from my app and continue registration/signing in.
the code for the static site that renders the recaptcha from inside the inAppBrowser:
<script>
var recaptchaVerifier;
function lol() {
alert("done");
};
$(document).ready(function() {
recaptchaVerifier = new firebase.auth.RecaptchaVerifier('gre', {
'size': 'invisible',
'callback': lol
});
recaptchaVerifier.render();
});
function getIt() {
console.log(recaptchaVerifier);
return recaptchaVerifier;
};
</script>
The code for opening the inAppBrowser and grabbing the recaptchaVerifier Object:
var myInterval;
var myValue : firebase.auth.ApplicationVerifier ;
const browser = this.inAppBrowser.create("https://demo.firebaseapp.com","_blank",
{"location":"no",clearcache:"yes",clearsessioncache:"yes"});
browser.on("loadstop").subscribe(x=>{
myInterval = setInterval(function(){
browser.executeScript({code:"getIt()"}).then(data=>{myValue = JSON.parse(data)});
},200);
});
browser.on("exit").subscribe(x=>{
clearInterval(myInterval);
this.presentAlert("Test Alert",myValue,"OK");
console.log("Adnan12 is error "+ myValue);
firebase.auth().signInWithPhoneNumber("+123456789",myValue)
.then(function (confirmationResult) {
this.presentAlert("alert title","sms sent","ok");
}).catch(function (error) {
this.presentAlert("alert title","sms NOT sent","ok");
});
});

Detect when an iframe is loaded

I'm using an <iframe> (I know, I know, ...) in my app (single-page application with ExtJS 4.2) to do file downloads because they contain lots of data and can take a while to generate the Excel file (we're talking anything from 20 seconds to 20 minutes depending on the parameters).
The current state of things is : when the user clicks the download button, he is "redirected" by Javascript (window.location.href = xxx) to the page doing the export, but since it's done in PHP, and no headers are sent, the browser continuously loads the page, until the file is downloaded. But it's not very user-friendly, because nothing shows him whether it's still loading, done (except the file download), or failed (which causes the page to actually redirect, potentially making him lose the work he was doing).
So I created a small non-modal window docked in the bottom right corner that contains the iframe as well as a small message to reassure the user. What I need is to be able to detect when it's loaded and be able to differenciate 2 cases :
No data : OK => Close window
Text data : Error message => Display message to user + Close window
But I tried all 4 events (W3Schools doc) and none is ever fired. I could at least understand that if it's not HTML data returned, it may not be able to fire the event, but even if I force an error to return text data, it's not fired.
If anyone know of a solution for this, or an alternative system that may fit here, I'm all ears ! Thanks !
EDIT : Added iframe code. The idea is to get a better way to close it than a setTimeout.
var url = 'http://mywebsite.com/my_export_route';
var ifr = $('<iframe class="dl-frame" src="'+url+'" width="0" height="0" frameborder="0"></iframe>');
ifr.appendTo($('body'));
setTimeout(function() {
$('.dl-frame').remove();
}, 3000);
I wonder if it would require some significant changes in both frontend and backend code, but have you considered using AJAX? The workflow would be something like this: user sends AJAX request to start file generating and frontend constantly polls it's status from the server, when it's done - show a download link to the user. I believe that workflow would be more straightforward.
Well, you could also try this trick. In parent window create a callback function for the iframe's complete loading myOnLoadCallback, then call it from the iframe with parent.myOnLoadCallback(). But you would still have to use setTimeout to handle server errors/connection timeouts.
And one last thing - how did you tried to catch iframe's events? Maybe it something browser-related. Have you tried setting event callbacks in HTML attributes directly? Like
<iframe onload="done()" onerror="fail()"></iframe>
That's a bad practice, I know, but sometimes job need to be done fast, eh?
UPDATE
Well, I'm afraid you have to spend a long and painful day with a JS debugger. load event should work. I still have some suggestions, though:
1) Try to set event listener before setting element's src. Maybe onload event fires so fast that it slips between creating element and setting event's callback
2) At the same time try to check if your server code plays nicely with iframes. I have made a simple test which attempts to download a PDF from Dropbox, try to replace my URL with your backed route's.
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<iframe id="book"></iframe>
<button id="go">Request downloads!</button>
<script>
var bookUrl = 'https://www.dropbox.com/s/j4o7tw09lwncqa6/thinkpython.pdf';
$('#book').on('load', function(){
console.log('WOOT!', arguments);
});
$('#go').on('click', function(){
$('#book').attr('src', bookUrl);
});
</script>
UPDATE 2
3) Also, look at the Network tab of your browser's debugger, what happens when you set src to the iframe, it should show request and server's response with headers.
I've tried with jQuery and it worked just fine as you can see in this post.
I made a working example here.
It's basically this:
<iframe src="http://www.example.com" id="myFrame"></iframe>
And the code:
function test() {
alert('iframe loaded');
}
$('#myFrame').load(test);
Tested on IE11.
I guess I'll give a more hacky alternative to the more proper ways of doing it that the others have posted. If you have control over the PHP download script, perhaps you can just simply output javascript when the download is complete. Or perhaps redirect to a html page that runs javascript. The javascript run, can then try to call something in the parent frame. What will work depends if your app runs in the same domain or not
Same domain
Same domain frame can just use frame javascript objects to reference each other. so it could be something like, in your single page application you can have something like
window.downloadHasFinished=function(str){ //Global pollution. More unique name?
//code to be run when download has finished
}
And for your download php script, you can have it output this html+javascript when it's done
<script>
if(parent && parent.downloadHasFinished)
parent.downloadHasFinished("if you want to pass a data. maybe export url?")
</script>
Demo jsfiddle (Must run in fullscreen as the frames have different domain)
Parent jsfiddle
Child jsfiddle
Different Domains
For different domains, We can use postMessage. So in your single page application it will be something like
$(window).on("message",function(e){
var e=e.originalEvent
if(e.origin=="http://downloadphp.anotherdomain.com"){ //for security
var message=e.data //data passed if any
//code to be run when download has finished
}
});
and in your php download script you can have it output this html+javascript
<script>
parent.postMessage("if you want to pass data",
"http://downloadphp.anotherdomain.com");
</script>
Parent Demo
Child jsfiddle
Conclusion
Honestly, if the other answers work, you should probably use those. I just thought this was an interesting alternative so I posted it up.
You can use the following script. It comes from a project of mine.
$("#reportContent").html("<iframe id='reportFrame' sandbox='allow-same-origin allow-scripts' width='100%' height='300' scrolling='yes' onload='onReportFrameLoad();'\></iframe>");
Maybe you should use
$($('.dl-frame')[0].contentWindow.document).ready(function () {...})
Try this (pattern)
$(function () {
var session = function (url, filename) {
// `url` : URL of resource
// `filename` : `filename` for resource (optional)
var iframe = $("<iframe>", {
"class": "dl-frame",
"width": "150px",
"height": "150px",
"target": "_top"
})
// `iframe` `load` `event`
.one("load", function (e) {
$(e.target)
.contents()
.find("html")
.html("<html><body><div>"
+ $(e.target)[0].nodeName
+ " loaded" + "</div><br /></body></html>");
alert($(e.target)[0].nodeName
+ " loaded" + "\nClick link to download file");
return false
});
var _session = $.when($(iframe).appendTo("body"));
_session.then(function (data) {
var link = $("<a>", {
"id": "file",
"target": "_top",
"tabindex": "1",
"href": url,
"download": url,
"html": "Click to start {filename} download"
});
$(data)
.contents()
.find("body")
.append($(link))
.addBack()
.find("#file")
.attr("download", function (_, o) {
return (filename || o)
})
.html(function (_, o) {
return o.replace(/{filename}/,
(filename || $(this).attr("download")))
})
});
_session.always(function (data) {
$(data)
.contents()
.find("a#file")
.focus()
// start 6 second `download` `session`,
// on `link` `click`
.one("click", function (e) {
var timer = 6;
var t = setInterval(function () {
$(data)
.contents()
.find("div")
// `session` notifications
.html("Download session started at "
+ new Date() + "\n" + --timer);
}, 1000);
setTimeout(function () {
clearInterval(t);
$(data).replaceWith("<span class=session-notification>"
+ "Download session complete at\n"
+ new Date()
+ "</span><br class=session-notification />"
+ "<a class=session-restart href=#>"
+ "Restart download session</a>");
if ($("body *").is(".session-restart")) {
// start new `session`,
// on `.session-restart` `click`
$(".session-restart")
.on("click", function () {
$(".session-restart, .session-notification")
.remove()
// restart `session` (optional),
// or, other `session` `complete` `callback`
&& session(url, filename ? filename : null)
})
};
}, 6000);
});
});
};
// usage
session("http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf", "ECMA_JS.pdf")
});
jsfiddle http://jsfiddle.net/guest271314/frc82/
In regards to your comment about to get a better way to close it instead of setTimeout. You could use jQuery fadeOut option or any of the transitions and in the 'complete' callback remove the element. Below is an example you can dump right into a fiddle and only need to reference jQuery.
I also wrapped inside listener for 'load' event to not do the fade until the iFrame has been loaded as question originally was asking.
// plugin your URL here
var url = 'http://jquery.com';
// create the iFrame, set attrs, and append to body
var ifr = $("<iframe>")
.attr({
"src": url,
"width": 300,
"height": 100,
"frameborder": 0
})
.addClass("dl-frame")
.appendTo($('body'))
;
// log to show its part of DOM
console.log($(".dl-frame").length + " items found");
// create listener for load
ifr.one('load', function() {
console.log('iframe is loaded');
// call $ fadeOut to fade the iframe
ifr.fadeOut(3000, function() {
// remove iframe when fadeout is complete
ifr.remove();
// log after, should no longer exist in DOM
console.log($(".dl-frame").length + " items found");
});
});
If you are doing a file download from a iframe the load event wont fire :) I was doing this a week ago. The only solution to this problem is to call a download proxy script with a tag and then return that tag trough a cookie then the file is loaded. min while yo need to have a setInterval on the page witch will watch for that specific cookie.
// Jst to clearyfy
var token = new Date().getTime(); // ticks
$('<iframe>',{src:"yourproxy?file=somefile.file&token="+token}).appendTo('body');
var timers = [];
timers[timers.length+1] = setInterval(function(){
var _index = timers.length+1;
var cookie = $.cooke(token);
if(typeof cookie != "undefined"){
// File has been downloaded
$.removeCookie(token);
clearInterval(_index);
}
},400);
in your proxy script add the cookie with the name set to the string sent bay the token url parameter.
If you control the script in server that generates excel or whatever you are sending to iframe why don't you put a UID flag and store it in session with value 0, so... when iframe is created and server script is called just set UID flag to 1 and when script is finished (the iframe will be loaded) just put it to 2.
Then you only need a timer and a periodic AJAX call to the server to check the UID flag... if it's set to 0 the process doesn't started, if it's 1 the file is creating, and finally if it's 2 the process has been ended.
What do you think? If you need more information about this approach just ask.
What you are saying could be done for images and other media formats using $(iframe).load(function() {...});
For PDF files or other rich media, you can use the following Library:
http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/
Note: You will need JQuery UI
You can use this library. The code snippet for you purpose would be something like:
window.onload = function () {
rajax_obj = new Rajax('',
{
action : 'http://mywebsite.com/my_export_route',
onComplete : function(response) {
//This will only called if you have returned any response
// instead of file from your export script
// In your case 2
// Text data : Error message => Display message to user
}
});
}
Then you can call rajax_obj.post() on your download link click.
Download
NB: You should add some header to your PHP script so it force file download
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Content-Transfer-Encoding: binary');
There is two solutions that i can think of. Either you have PHP post it's progress to a MySQL table where from frontend will be pulling information from using AJAX calls to check up on the progress of the generation. Using somekind of unique key that is being generated when accessing the page would be ideal for multiple people generating excel files at the same time.
Another solution would be to use nodejs & then in PHP post the progress of the excel file using cURL or a socket to a nodejs service. Then when receiving updates from PHP in nodejs you simply write the progress of the excel file for the right socket. This will cut off some browser support though. Unless you go through with it using external libraries to bring websocket support for pretty much all browsers & versions.
Hope this answer helped. I was having the same issue previous year. Ended up doing AJAX polling having PHP post progress on the fly.
Try this:
Note: You should be on the same domain.
var url = 'http://mywebsite.com/my_export_route',
iFrameElem = $('body')
.append('<iframe class="dl-frame" src="' + url + '" width="0" height="0" frameborder="0"></iframe>')
.find('.dl-frame').get(0),
iDoc = iFrameElem.contentDocument || iFrameElem.contentWindow.document;
$(iDoc).ready(function (event) {
console.log('iframe ready!');
// do stuff here
});

JSON BTC/LTC ticker is not working anymore

I have been using this JSON ticker for the last month. It has been working like a charm, but today it stopped working; maybe anyone knows what could have gone wrong here?
$(function () {
startRefresh();
});
function startRefresh() {
setTimeout(startRefresh, 10000);
var turl = 'https://btc-e.com/api/2/ltc_btc/ticker';
$.getJSON('http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20where%20url%3D%22' + encodeURIComponent(turl) + '%22&format=json', function (data) {
jQuery('#ticker').html(data['query'].results.ticker.last);
jQuery('#ticker').append(' BTC');
});
}
http://jsfiddle.net/marcetin/9FHp3/4/
Here is the same example but with Cryptsy API and works well:
http://jsfiddle.net/marcetin/P2t9R/2/
I checked out https://btc-e.com/api/2/ltc_btc/ticker and got JSON back, so the issue is not with that site.
I checked out your code, and aside from being a little dirty, there was nothing that would keep it from pulling that service.
So, the issue seems to be at Yahoo's side. Purhaps that API is no longer available through Yahoo.
I have have cleaned up (and commented) your code:http://jsfiddle.net/9FHp3/27/
// Function for pulling JSON
function startRefresh() {
// This is the API URL
var turl = 'https://btc-e.com/api/2/ltc_btc/ticker';
// This sends the API URL through Yahoo?
$.getJSON('http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20where%20url%3D%22' + encodeURIComponent(turl) + '%22&format=json', function (data) {
// Writes to the page
$('#ticker').html(data['query'].results.ticker.last+' BTC');
});
}
// Do the initial pull
startRefresh();
// Refresh every 10000
setInterval(startRefresh, 10000);
However, you should really be pulling REST APIs from a server-side code such as PHP. Unless they are available in JSONP or CORS they are not really intended for cross-domain client-side script.
I hope this helps!

how to load google client.js dynamically

this is my first time to post here on stackoverflow.
My problem is simple (I think). I am tasked to allow users to sign up using either Facebook, Google Plus, LinkedIn and Twitter. Now, what I want to do is when the user clicks the Social Network button, it will redirect them to the registration page with a flag that determines which social network they want to use. No problem here.
I want to load each API dynamically depending on which social network they choose.
I have a problem when loading the Google JS API, dynamically. The sample found in here loads client.js in a straightforward manner. I have no problems if I follow the sample code. But I want to load it dynamically.
I tried using $.ajax, $.getScript and even tried adding the script to the page just like how you call Google Analytics asynchronously. None of the above worked. My call back function is NOT called all the time. Also, if i call the setApiKey from the call back function of $.ajax and $.getScript, the gapi.client is NULL. I don't know what to do next.
Codes that did not work:
(function () {
var gpjs = document.createElement('script'); gpjs.type = 'text/javascript'; gpjs.async = false;
gpjs.src = 'https://apis.google.com/js/client.js?onload=onClientLoadHandler';
var sgp = document.getElementsByTagName('script')[0]; sgp.parentNode.insertBefore(gpjs, sgp);})();
Using $.getScript
$.getScript("https://apis.google.com/js/client.js?onload=onClientLoadHandler", function () {
console.log("GP JS file loaded.");
SetKeyCheckAuthority();});
Using $.ajax
$(document).ready(function () {
$.ajax({
url: "https://apis.google.com/js/client.js?onload=onClientLoad",
dataType: "script",
success: function () {
console.log("GP load successful");
SetKeyCheckAuthority();
},
error: function () { console.log("GP load failed"); },
complete: function () { console.log("GP load complete"); }
});});
May I know what is the proper way of calling this js file dynamically? Any help would be appreciated. Thank you.
Ok, I just thought of a solution but i think it's a bad one. Please let me know what you think of it.
i used $.getScript to load the js file
$.getScript("https://apis.google.com/js/client.js?onload=onClientLoadHandler", function () {
console.log("GP JS file loaded.");
SetKeyCheckAuthority();});
and then on my SetKeyCheckAuthority function i placed a condition to call itself after 1 second when gapi.client is null.
function SetKeyCheckAuthority() {
if(null == gapi.client) {
window.setTimeout(SetKeyCheckAuthority,1000);
return;
}
//set API key and check for authorization here }

Categories

Resources