How use google map API in hybrid app for mobile device - google-maps

I want download java Script google map API V3 and load them in HTML file from local host instead use them from google API online link.
Because when I'm load API from google server and my device is offline my app has error in use of google API method for render to project. and I'm online after run app but map doesn't work and doesn't load image map.

If you start your app when offline, script tags will throw a net::ERRxxx. You can see this on browser console.
Later, when you come back online, those scripts have failed loading and that is it.
I have tackle this using setTimeout and google maps callback parameter. Basically, I remove and reinject the script tag on page every 5 seconds and set google maps callback to stop the cycle and execute a user callback.
So, as you stated, when you are back online, your script will load and your google maps API will be available inside the callback.
Try this:
loadAPI( function(map) {
console.log('back to business!');
//...
}
code:
var loadAPITimer = null;
function loadAPI(callback) {
var googleMapsScriptId = 'googleMapsScript';
if ( (typeof(loadAPITimer))==="undefined") {
throw('global vars are not defined');
}
if (window.google && window.google.maps) { // API already loaded
window.googleMapsLoadCallback(callback);
return;
}
if (loadAPITimer !== null) { //already running
return;
}
//inject script every 5 seconds
loadAPITimer = setInterval(function() { injectScript(); },5000);
//---- LOCAL FUNCTIONS --------------------------------------------
//---- google maps callback
window.googleMapsLoadCallback = function(cback) {
console.log('done! Inside googleMapsLoadCallback');
if (loadAPITimer) { //still running, cleanUp
clearInterval(loadAPITimer);
loadAPITimer = null;
} else {
console.log('google maps already loaded.');
}
cback && cback(window.google.maps);
}
//---- inject script tag for maps
function injectScript() {
if ( window.google && window.google.maps ) {
console.log('Google Maps Loaded!');
window.googleMapsLoadCallback(callback);
}
else if (window.google && window.google.load) {
console.log('google is defined: loading maps');
window.google.load('maps', version || 3, {'other_params': '&sensor=false' , 'callback' : 'googleMapsLoadCallback'});
}
else {
console.log('injecting Google Maps script');
var script = window.document.getElementById(googleMapsScriptId);
if (script) {
script.parentNode.removeChild(script);
}
window.setTimeout( function() {
script = window.document.createElement('script');
script.id = googleMapsScriptId;
script.type = 'text/javascript';
script.src = 'http://maps.googleapis.com/maps/api/js?v=3&sensor=false&callback=googleMapsLoadCallback';
window.document.body.appendChild(script);
}, 100 );
}
}
}

Related

Executing Functions using the Apps Script API

I am trying to execute Apps Script function using Apps Script API. For this I set up a target script and calling script (JavaScript code) using instructions from Google here.
I followed exactly how it is described but I am getting the following errors.
Error in calling script:
ReferenceError: gapi is not defined
Error on target script while manually running the function "getFoldersUnderRoot()"
Exception: We're sorry, a server error occurred. Please wait a bit and try again.
function "getFoldersUnderRoot()" was running properly before connecting the target script to the GCP project.
Any help is appreciated to point out what I am doing wrong.
I figured out how to execute App Script functions using Apps Script API. So I am posting the answer for the benefit of others. Also I would try to plug in the missing information which Google has not provided in their instructions.
The target script is an App Script (e.g. "code.gs") file with the required functions to be executed. This script has to be attached to a GCP project with App Script API enabled.
The calling script has to be an html file saved in a local folder and not an App Script file. Below is an example "index.html" which calls two functions "callScriptFunction()" and "getSheets()".
<!DOCTYPE html>
<html>
<head>
<title>Google Apps Script API Quickstart</title>
<meta charset="utf-8" />
</head>
<body>
<p>Google Apps Script API Quickstart</p>
<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize_button" style="display: none;">Authorize</button>
<button id="signout_button" style="display: none;">Sign Out</button>
<pre id="content" style="white-space: pre-wrap;"></pre>
<script type="text/javascript">
// Client ID and API key from the Developer Console
var CLIENT_ID = 'YOUR_CLIENT_ID';
var API_KEY = 'YOUR_API_KEY';
// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://script.googleapis.com/$discovery/rest?version=v1"];
// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = 'https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.readonly';
var authorizeButton = document.getElementById('authorize_button');
var signoutButton = document.getElementById('signout_button');
/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
}, function(error) {
appendPre(JSON.stringify(error, null, 2));
});
}
/**
* Called when the signed in status changes, to update the UI
* appropriately. After a sign-in, the API is called.
*/
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
// callScriptFunction();
getSheets();
} else {
authorizeButton.style.display = 'block';
signoutButton.style.display = 'none';
}
}
/**
* Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
/**
* Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
/**
* Append a pre element to the body containing the given message
* as its text node. Used to display the results of the API call.
*
* #param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('content');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
/**
* Shows basic usage of the Apps Script API.
*
* Call the Apps Script API to create a new script project, upload files
* to the project, and log the script's URL to the user.
*/
function callScriptFunction() {
var scriptId = "TARGET_SCRIPT_ID";
// Call the Apps Script API run method
// 'scriptId' is the URL parameter that states what script to run
// 'resource' describes the run request body (with the function name
// to execute)
gapi.client.script.scripts.run({
'scriptId': scriptId,
'resource': {
'function': 'getFoldersUnderRoot',
'devMode': true
}
}).then(function(resp) {
var result = resp.result;
if (result.error && result.error.status) {
// The API encountered a problem before the script
// started executing.
appendPre('Error calling API:');
appendPre(JSON.stringify(result, null, 2));
} else if (result.error) {
// The API executed, but the script returned an error.
// Extract the first (and only) set of error details.
// The values of this object are the script's 'errorMessage' and
// 'errorType', and an array of stack trace elements.
var error = result.error.details[0];
appendPre('Script error message: ' + error.errorMessage);
if (error.scriptStackTraceElements) {
// There may not be a stacktrace if the script didn't start
// executing.
appendPre('Script error stacktrace:');
for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
var trace = error.scriptStackTraceElements[i];
appendPre('\t' + trace.function + ':' + trace.lineNumber);
}
}
} else {
// The structure of the result will depend upon what the Apps
// Script function returns. Here, the function returns an Apps
// Script Object with String keys and values, and so the result
// is treated as a JavaScript object (folderSet).
var folderSet = result.response.result;
if (Object.keys(folderSet).length == 0) {
appendPre('No folders returned!');
} else {
appendPre('Folders under your root folder:');
Object.keys(folderSet).forEach(function(id){
appendPre('\t' + folderSet[id] + ' (' + id + ')');
});
}
}
});
}
function getSheets() {
// ID of the script to call. Acquire this from the Apps Script editor,
// under Publish > Deploy as API executable.
var scriptId = "TARGET_SCRIPT_ID";
// Initialize parameters for function call.
var sheetId = "SPREADSHEET_ID";
gapi.client.script.scripts.run({
'scriptId': scriptId,
'resource': {
'function': 'getSheetNames',
'parameters': [sheetId],
'devMode': true
}
}).then(function(resp) {
var result = resp.result;
if (result.error && result.error.status) {
// The API encountered a problem before the script
// started executing.
appendPre('Error calling API:');
appendPre(JSON.stringify(result, null, 2));
} else if (result.error) {
// The API executed, but the script returned an error.
// Extract the first (and only) set of error details.
// The values of this object are the script's 'errorMessage' and
// 'errorType', and an array of stack trace elements.
var error = result.error.details[0];
appendPre('Script error message: ' + error.errorMessage);
if (error.scriptStackTraceElements) {
// There may not be a stacktrace if the script didn't start
// executing.
appendPre('Script error stacktrace:');
for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
var trace = error.scriptStackTraceElements[i];
appendPre('\t' + trace.function + ':' + trace.lineNumber);
}
}
} else {
// The structure of the result will depend upon what the Apps
// Script function returns. Here, the function returns an Apps
// Script Object with String keys and values, and so the result
// is treated as a JavaScript object (folderSet).
var names = result.response.result;
if (Object.keys(names).length == 0) {
appendPre('No sheetnames returned!');
} else {
appendPre(names);
}
}
});
}
</script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body>
</html>
Below is an example of target script.
function getFoldersUnderRoot() {
var root = DriveApp.getRootFolder();
var folders = root.getFolders();
var folderSet = {};
while (folders.hasNext()) {
var folder = folders.next();
folderSet[folder.getId()] = folder.getName();
}
return folderSet;
}
function getSheetNames(sheetId) {
var ss = SpreadsheetApp.openById(sheetId);
var sheets = ss.getSheets();
var names = sheets.map(function(sheet) {
return sheet.getName();
})
return names;
}
From terminal change to the working directory and execute python3 -m http.server 8000. Open browser and load "http://localhost:8000/". Authourize and proceed.
You need to whitelist "http://localhost:8000/" in the project credentials
You need to add required scopes in OAuth Consent Screen of the project.
I am able to execute the function "getSheetNames()" but "getFoldersUnderRoot()" is throwing error: Exception: We're sorry, a server error occurred. Please wait a bit and try again. Executing from the script editor also gives the same error. However "getFoldersUnderRoot()" is executable on any other script which is not attached to a GCP project

Check if user has run it

I run a Google Apps script that uploads a file to the user's Google Drive file:
function doGet(e) {
var blob = UrlFetchApp.fetch(e.parameters.url).getBlob();
DriveApp.createFile(blob);
return HtmlService.createHtmlOutput("DONE!");
}
My site loads a popup window that runs a Google Apps Script with that code. Works fine.
Now, how do I communicate back to my site that they user has successfully uploaded the file? As in, how can I communicate back to my server that the user has run doGet()?`
Some type of response handling must exist?
Full working code (test it out on JSBin):
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
</head>
<body>
<div class="google-upload" data-url="https://calibre-ebook.com/downloads/demos/demo.docx">
<span style="background-color: #ddd">Upload</span>
</div>
<script>
$(function() {
$(".google-upload").click(function() {
var url = "https://script.google.com/macros/s/AKfycbwsuIcO5R86Xgv4E1k1ZtgtfKaENaKq2ZfsLGWZ4aqR0d9WBYc/exec"; // Please input the URL here.
var withQuery = url + "?url=";
window.open(withQuery + $('.google-upload').attr("data-url"), "_blank", "width=600,height=600,scrollbars=1");
});
});
</script>
</body>
</html>
So to clarify, I want a way to find out whether if the user has successfully uploaded the file. Something like:
request.execute(function(response) {
if (response.code == 'uploaded') {
// uploaded, do stuff
} else {
// you get the idea...
}
});
Adding a bounty for a complete solution to this.
Rather than returning a HtmlService object, you can pass data using jQuery's $.getJSON method and retrieve data from the doGet function with ContentService. Google Apps Script does not accept CORS, so using JSONP is the best way to get data to and from your script. See this post for more.
Working CodePen Example
I split your HTML and scripts for clarity. None of the HTML changed from your original example.
Code.gs
function doGet(e) {
var returnValue;
// Set the callback param. See https://stackoverflow.com/questions/29525860/
var callback = e.parameter.callback;
// Get the file and create it in Drive
try {
var blob = UrlFetchApp.fetch(e.parameters.url).getBlob();
DriveApp.createFile(blob);
// If successful, return okay
// Structure this JSON however you want. Parsing happens on the client side.
returnValue = {status: 'okay'};
} catch(e) {
Logger.log(e);
// If a failure, return error message to the client
returnValue = {status: e.message}
}
// Returning as JSONP allows for crossorigin requests
return ContentService.createTextOutput(callback +'(' + JSON.stringify(returnValue) + ')').setMimeType(ContentService.MimeType.JAVASCRIPT);
}
Client JS
$(function() {
$(".google-upload").click(function() {
var appUrl = "https://script.google.com/macros/s/AKfycbyUvgKdhubzlpYmO3Marv7iFOZwJNJZaZrFTXCksxtl2kqW7vg/exec";
var query = appUrl + "?url=";
var popupUrl = query + $('.google-upload').attr("data-url") + "&callback=?";
console.log(popupUrl)
// Open this to start authentication.
// If already authenticated, the window will close on its own.
var popup = window.open(popupUrl, "_blank", "width=600,height=600,scrollbars=1");
$.getJSON(popupUrl, function(returnValue) {
// Log the value from the script
console.log(returnValue.status);
if(returnValue.status == "okay") {
// Do stuff, like notify the user, close the window
popup.close();
$("#result").html("Document successfully uploaded");
} else {
$("#result").html(returnValue);
}
})
});
});
You can test the error message by passing an empty string in the data-url param. The message is returned in the console as well as the page for the user.
Edit 3.7.18
The above solution has problems with controlling the authorization flow. After researching and speaking with a Drive engineer (see thread here) I've reworked this into a self-hosted example based on the Apps Script API and running the project as an API executable rather than an Apps Script Web App. This will allow you to access the [run](https://developers.google.com/apps-script/api/reference/rest/v1/scripts/run) method outside an Apps Script web app.
Setup
Follow the Google Apps Script API instructions for JavaScript. The Apps Script project should be a standalone (not linked to a document) and published as API executable. You'll need to open the Cloud Console and create OAuth credentials and an API key.
The instructions have you use a Python server on your computer. I use the Node JS server, http-server, but you can also put it live online and test from there. You'll need to whitelist your source in the Cloud Console.
The client
Since this is self hosted, you'll need a plain HTML page which authorizes the user through the OAuth2 API via JavaScript. This is preferrable because it keeps the user signed in, allowing for multiple API calls to your script without reauthorization. The code below works for this application and uses the authorization flow from the Google quickstart guides.
index.html
<body>
<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize-button" style="display: none;">Authorize</button>
<button id="signout-button" style="display: none;">Sign Out</button>
<button onclick="uploadDoc()" style="margin: 10px;" id="google-upload" data-url="https://calibre-ebook.com/downloads/demos/demo.docx">Upload doc</button>
<pre id="content"></pre>
</body>
index.js
// Client ID and API key from the Developer Console
var CLIENT_ID = 'YOUR_CLIENT_ID';
var API_KEY = 'YOUR_API_KEY';
var SCRIPT_ID = 'YOUR_SCRIPT_ID';
// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://script.googleapis.com/$discovery/rest?version=v1"];
// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = 'https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/script.external_request';
var authorizeButton = document.getElementById('authorize-button');
var signoutButton = document.getElementById('signout-button');
var uploadButton = document.getElementById('google-upload');
var docUrl = uploadButton.getAttribute('data-url').value;
// Set the global variable for user authentication
var isAuth = false;
/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
// uploadButton.onclick = uploadDoc;
});
}
/**
* Called when the Upload button is clicked. Reset the
* global variable to `true` and upload the document.
* Thanks to #JackBrown for the logic.
*/
function updateSigninStatus(isSignedIn) {
if (isSignedIn && !isAuth) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
uploadButton.style.display = 'block'
uploadButton.onclick = uploadDoc;
} else if (isSignedIn && isAuth) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
uploadButton.style.display = 'block';
uploadDoc();
} else {
authorizeButton.style.display = 'block';
signoutButton.style.display = 'none';
uploadButton.style.display = 'none';
isAuth = false;
}
}
/**
* Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
isAuth = true; // Update the global variable
}
/**
* Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
isAuth = false; // update the global variable
}
/**
* Append a pre element to the body containing the given message
* as its text node. Used to display the results of the API call.
*
* #param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
var pre = document.getElementById('content');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
/**
* Handle the login if signed out, return a Promise
* to call the upload Docs function after signin.
**/
function uploadDoc() {
console.log("clicked!")
var docUrl = document.getElementById('google-upload').getAttribute('data-url');
gapi.client.script.scripts.run({
'scriptId':SCRIPT_ID,
'function':'uploadDoc',
'parameters': [ docUrl ]
}).then(function(resp) {
var result = resp.result;
if(result.error && result.error.status) {
// Error before the script was Called
appendPre('Error calling API');
appendPre(JSON.parse(result, null, 2));
} else if(result.error) {
// The API executed, but the script returned an error.
// Extract the first (and only) set of error details.
// The values of this object are the script's 'errorMessage' and
// 'errorType', and an array of stack trace elements.
var error = result.error.details[0];
appendPre('Script error message: ' + error.errorMessage);
if (error.scriptStackTraceElements) {
// There may not be a stacktrace if the script didn't start
// executing.
appendPre('Script error stacktrace:');
for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
var trace = error.scriptStackTraceElements[i];
appendPre('\t' + trace.function + ':' + trace.lineNumber);
}
}
} else {
// The structure of the result will depend upon what the Apps
// Script function returns. Here, the function returns an Apps
// Script Object with String keys and values, and so the result
// is treated as a JavaScript object (folderSet).
console.log(resp.result)
var msg = resp.result.response.result;
appendPre(msg);
// do more stuff with the response code
}
})
}
Apps Script
The Apps Script code does not need to be modified much. Instead of returning using ContentService, we can return plain JSON objects to be used by the client.
function uploadDoc(e) {
Logger.log(e);
var returnValue = {};
// Set the callback URL. See https://stackoverflow.com/questions/29525860/
Logger.log("Uploading the document...");
try {
// Get the file and create it in Drive
var blob = UrlFetchApp.fetch(e).getBlob();
DriveApp.createFile(blob);
// If successful, return okay
var msg = "The document was successfully uploaded!";
return msg;
} catch(e) {
Logger.log(e);
// If a failure, return error message to the client
return e.message
}
}
I had a hard time getting CodePen whitelisted, so I have an example hosted securely on my own site using the code above. Feel free to inspect the source and take a look at the live Apps Script project.
Note that the user will need to reauthorize as you add or change scopes in your Apps Script project.

How to use setVolume() on SoundCloud

I want to use setVolume(0.01) on SoundCloud because it's way to loud for me.
As a temporary solution, I made the whole Chrome browser quieter, but then Youtube and other websites are too quiet.
I found that SoundCloud's volume can be controlled via the "SC.Widget method", but I have no idea what that is.
Can somebody explain how I can use that to set SoundCloud's volume to 0.01?
I already tried to put that just in the Chrome console but this gives me the following: VM1394:1 Uncaught ReferenceError: setVolume is not defined(…)
To change the volume on the Soundcloud website with a script there's no real API you can use, and no official way to do so. This should work:
webpackJsonp([], {
0: function(a, b, require) {
var modules = require.c;
modules[54].exports.broadcast("volume:set", 0.1);
}
});
Because the Soundcloude code is minified and not made to be used by other scripts, it is possible that the above solution might break with an error like this:
Uncaught TypeError: modules[54].exports.broadcast is not a function(…)
A hacky solution is to iterate over all modules and execute the volume:set broadcast:
webpackJsonp([], {
0: function(a, b, require) {
var modules = require.c;
for(var x in modules){
if(modules[x].exports.broadcast){
modules[x].exports.broadcast("volume:set", 1.0);
}
}
}
});
To change volume on Soundcloud widgets:
The HTML5 widget API is explained here. What you need to do first is include Soundcloud's API script, you can use this code which I borrowed from here:
var scapi = document.createElement('script');
scapi.src = "https://w.soundcloud.com/player/api.js";
document.getElementsByTagName('head')[0].appendChild(scapi);
The next step is finding the Soundcloud widget and use the API script to get the functionality we need, i.e. setVolume():
var sciframe = document.querySelector("iframe");
var widget = SC.Widget(sciframe);
widget.setVolume(0.1); // goes from 0 to 1
This you can use as a userscript with Greasemonkey or Tampermonkey and run it automatically:
var scapi = document.createElement('script');
scapi.src = "https://w.soundcloud.com/player/api.js";
document.getElementsByTagName('head')[0].appendChild(scapi);
function waitAndRegister() {
window.setTimeout(function(){
if(typeof(SC) == 'undefined') {
waitAndRegister();
} else {
quiet();
}
}, 100);
};
waitAndRegister();
function quiet() {
var scWidgets = document.querySelectorAll('iframe[src^="https://w.soundcloud.com/player"]');
if(scWidgets.length > 0) {
for (var i = 0; i < scWidgets.length; ++i) {
var widget = SC.Widget(scWidgets[i]);
widget.bind(SC.Widget.Events.PLAY, function() {
widget.setVolume(0.1);
});
}
}
}
Chrome > ctrl+shift+i > Application Tab > Storage > Local Storage > V2::local::settings
and set volume you need (eg: volume":0.05,")
Works like a charm for me.

Adobe DPS HTML Alert when tapping link that no internet connection available

I created an HTML page that has some external links, when the user taps the external link how can I prompt the user that there is no internet connection available? Thanks.
You will probably need some JavaScript and Adobe's store api (for banners or store) or reading api (for html articles or web view in folios). The api provides the singleton object adobeDPS.deviceService which can tell you if the device is online or not. Additionally it provides a signal to indicate a change.
For each link element you register an onclick event handler that checks online state and either passes the click through or catches it and gives a message to the user.
The following code could work:
<script src="js/AdobeLibraryAPI.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", myLinkChecker.register, false);
var myLinkChecker = {
register: function(){
if (typeof(adobeDPS) !== 'object') {
console.log("Adobe Library not loaded :-(");
this.check = function() { return true } // Fallback
}
var linkList = document.querySelectorAll("a, map > area");
for (var i=0; i < linkList.length; i++){
var e = linkList[i];
if (e.hasAttribute('href'))
e.addEventListener('click', myLinkChecker.check, false);
}
},
check: function(ev){
if (adobeDPS.deviceService.isOnline) { // let <a> process the click
console.log("online");
return true
} else { // cancel click event and show message
event.stopPropagation();
event.preventDefault();
alert("Sorry, your device is not online")
return false;
}
}
}
</script>
Remote debugging html in DPS apps can be done using iOS developer apps and desktop Safari, or Android apps with Google Chrome.

Displaying multiple Google Maps asynchronously

I currently have a page which shows results of a search. When the user clicks on a result, details are fetched using ajax and loaded into the page. In these details, there is a Google map.
Previously, I had the Gmaps script with callback in the details page. But I ran into this problem that the Gmaps script was inserted multiples times if the user clicked on several results.
Now, I load the script in the results page and the details page calls the initialize function while passing all the necessary parameters. But I get an undefined is not a function error.
So my question is: how to structure the Gmaps script, callback, and asynchronous initializing of the maps between the two pages (results, and details)?
results page
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&key=[key]"></script>
function initialize(params) {
var directionsService, directionsDisplay, map;
directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();
// your typical gmaps stuff
}
details page
<div id="map_canvas"></div>
initialize(params);
You can just see if the Google Map's script has already loaded by checking for the "google" global variable that gets added to the DOM.
Full jsfiddle example here: http://jsfiddle.net/gavinfoley/yD8Qt/.
// dom ready
$(function () {
if (typeof google === "undefined") {
alert("Lazy loading Google maps");
lazyLoadGoogleMaps();
} else {
alert("Google Maps is already loaded");
googleMapsLoaded();
}
});
function lazyLoadGoogleMaps() {
// Note the callback function name
$.getScript("http://maps.google.com/maps/api/js?sensor=true&callback=googleMapsLoaded")
.done(function (script, textStatus) {
alert("Google maps loaded successfully");
})
.fail(function (jqxhr, settings, ex) {
alert("Could not load Google Maps: ", ex);
});
}
// This function name is passed in to the Google maps script load above
// and will be called once Google maps has loaded
function googleMapsLoaded() {
alert("Done!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>