Bing Maps in a hybrid app - visual-studio

I am currently trying to use the Bing Maps AJAX API v7 in the new 'Multi-device hybrid App" template provided in Visual Studio, which uses Apache Cordova to provide crossplatform compatibility. I have written the following code, following the template at http://msdn.microsoft.com/en-us/library/gg427624.aspx :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<meta charset="utf-8" />
<title>Wand</title>
<!-- Wand references -->
<link href="css/index.css" rel="stylesheet" />
<script charset="UTF-8" type="text/javascript" src="https://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&s=1">
</script>
<script type="text/javascript">
function GetMap() {
var map = new Microsoft.Maps.Map(document.getElementById("map"), { credentials: "AgegeewHkb9iTTQDLseMTuQyxQyZybs7uUv7aqIgKu6U8CiaflVNApy5WtDXqtHr " });
}
</script>
</head>
<body onload="GetMap();">
<div id='map' class="mainview"></div>
<div class="menu">This is the menu</div>
<!-- Cordova reference, this is added to your app when it's built. -->
<script src="cordova.js"></script>
<script src="scripts/index.js"></script>
</body>
</html>
But when I debug it in Windows 8.1, it says that Microsoft is not defined (in the GetMap function). I asume that the library from
https:// ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&s=1
has not been loaded properly. Is there anything wrong with my code? Should I use the AJAX WEB API, or is there another for apps (the only one I have seen is for Windows 8 only)?
I think that my app is unable to load the web library because it doesn't have the proper permisions. In the config.xml there is a domain access section, but it says it doesn't appy to the windows platform, so how can I set it to allow loading pages from https:// ecn.dev.virtualearth.net ?
EDIT: Loading the script from a Web context (ms-appx-web) makes the script run, but if I want the code to be multiplatform I cannot use it. The solution would be to include in the Windows 8 manifest a permission for the Bing maps URL, how can I do it?

INDEX.HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta charset="utf-8" />
<title>Cordova Bing Mapping</title>
<link href="css/index.css" rel="stylesheet" />
<!--Needed for iOS & Android-->
<script charset="UTF-8" type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
</head>
<body>
<div id='map' class="mainview"></div>
<div class="menu">This is the menu</div>
<!-- Cordova reference, this is added to your app when it's built. -->
<script src="cordova.js"></script>
<script src="scripts/index.js"></script>
</body>
INDEX.JS
(function () {
"use strict";
document.addEventListener( 'deviceready', onDeviceReady.bind( this ), false );
//Loads Scripts Dynamically
function loadScript(filename) {
var fileref = document.createElement('script')
fileref.setAttribute("type", "text/javascript")
fileref.setAttribute("src", filename)
}
function onDeviceReady() {
// Load Local Scripts if Windows
if (device.platform == "windows") {
MSApp.execUnsafeLocalFunction(
function () {
loadScript("scripts/veapicore.js"); //Bing Maps SDK VS 2013
loadScript("scripts/veapiModules.js"); //Bing Maps SDK VS 2013
loadScript("scripts/mapcontrol.js"); //downloaded from http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0
Microsoft.Maps.loadModule("Microsoft.Maps.Map", {
callback: loadMap
});
})
}
};
function loadMap() {
var map = new Microsoft.Maps.Map(document.getElementById("map"), {
credentials: "BING_MAPS_KEY"
});
}
})();
NOTES
* This will work on Windows 8, Windows Phone 8, iOS, Android
* Bing Maps SDK VS 2013
1. Download Location: https://visualstudiogallery.msdn.microsoft.com/224eb93a-ebc4-46ba-9be7-90ee777ad9e1
2. Local Location: C:\Users\[USER]\AppData\Local\Microsoft SDKs\Windows\v8.1\ExtensionSDKs\Bing.Maps.JavaScript\1.313.0825.1\redist\commonconfiguration\neutral\Bing.Maps.JavaScript\
* For Windows Phone (Universal) - Microsoft.Maps.loadModule("Microsoft.Maps.Map", { callback: loadMap }); is still undefined.

I've implemented Bing Maps in a "Multi-Device Hybrid App" by doing the following:
Copied the C:\Users\\AppData\Local\Microsoft SDKs\Windows\v8.1\ExtensionSDKs\Bing.Maps.JavaScript\1.313.0825.1\redist\commonconfiguration\neutral\Bing.Maps.JavaScript folder into my local project
Copied http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0 into my local project as remoteBingMaps.js
On "deviceready" (where addScript dynamically adds a script file to document.body)
a. If device.platform == "windows8", then MSApp.execUnsafeLocalFunction(function () {
addScript("Bing.Maps.JavaScript/js/veapicore.js");
addScript("Bing.Maps.JavaScript/js/veapiModules.js");
});
b. Else addScript("scripts/frameworks/remoteBingMaps.js")
When loading the map control (where loadMap initializes the map control)
a. If device.platform == "windows8", then Microsoft.Maps.loadModule("Microsoft.Maps.Map", {callback:loadMap}}
b. Else loadMap()
I've gotten this working for Windows 8.1, Windows Phone, Android, and iOS.

There seems to be a couple of problems with the code.
Firstly, you are directly referencing a library from a URL. That might be causing issues on the Windows platform. You might want to download the file and add it to your project locally.
Secondly, your Bing Maps key has a space at the end, which is why the app is throwing errors at runtime.
<script type="text/javascript">
function GetMap() {
var map = new Microsoft.Maps.Map(document.getElementById("map"), { credentials: "AgegeewHkb9iTTQDLseMTuQyxQyZybs7uUv7aqIgKu6U8CiaflVNApy5WtDXqtHr " });
}
</script>
Change that to:
<script type="text/javascript">
function GetMap() {
var map = new Microsoft.Maps.Map(document.getElementById("map"), { credentials: "AgegeewHkb9iTTQDLseMTuQyxQyZybs7uUv7aqIgKu6U8CiaflVNApy5WtDXqtHr" });
}
</script>

I had the same issue, but neither of the proposed solutions worked for me. Interesting that Bing maps were loaded without any problems on the Ripple Simulator, but on Android emulator or device I had a problem with Microsoft namespace not defined - clearly namespace was not loaded. After some searching I found, that in the config.xml there is configuration for the Whitelist plugin, which controls which pages can be requested from the app (and you can configure that separately for each platform), so I just added:
<allow-intent href="https://ecn.dev.virtualearth.net/mapcontrol/*" />
for the android platform, commented out Content-Security-Policy from index.html and it started to work.

Related

Refused to frame '' because it violates the following Content Security Policy directive: "frame-src *" Trying to set for tel: explicity here

I'm currently trying to build a click to dial link in the browser as an Outlook Addin. I'm getting the error:
Refused to frame '' because it violates the following Content Security Policy directive: "frame-src *". Note that '*' matches only URLs with network schemes ('http', 'https', 'ws', 'wss'), or URLs whose scheme matches `self`'s scheme. tel:' must be added explicitely. [https://localhost:44371/]
I've set the meta tags a bunch of different ways trying to explicitly state the tel scheme that they mention. For instance:
<meta http-equiv="Content-Security-Policy" content="frame-src 'self' tel:">
I've tried about 20 different variations on this. I've also noticed that many people are saying something about changing the HTTP response headers, but I'm not sure exactly how to do this or even why it would be needed.
I'm working on Visual Studio using a template from their own program. Because I'm testing this out on my own computer, I've also tried to whitelist my own localhost. Still nothing.
Here is the html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Security-Policy" content="frame-src 'self' tel:">
<title>standard_item_properties</title>
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" media="all" href="default_entities.css" />
<script type="text/javascript" src="MicrosoftAjax.js"></script>
<script src="CallFunctionFile.js" type="text/javascript"></script>
<!-- Use the CDN reference to Office.js. -->
<script type="text/javascript" src="default_entities.js"></script>
</head>
<body>
<!-- NOTE: The body is empty on purpose. Since this is invoked via a button, there is no UI to render. -->
<div id="container">
<div><a id="tel-link">Make Call from Phone</a></div>
</div>
</body>
</html>
and here is the javascript:
// Global variables
let item;
let myEntities;
// The initialize function is required for all add-ins.
Office.initialize = function () {
const mailbox = Office.context.mailbox;
// Obtains the current item.
item = mailbox.item;
// Reads all instances of supported entities from the subject
// and body of the current item.
myEntities = item.getEntities();
JSON.stringify(myEntities.phoneNumbers[0].originalPhoneString));
// Checks for the DOM to load using the jQuery ready function.
window.addEventListener('DOMContentLoaded', (event) => {
// After the DOM is loaded, app-specific code can run.
});
let a = document.getElementById("tel-link");
a.href = "tel:" + encodeURIComponent(myEntities.phoneNumbers[0].originalPhoneString);
}

Flutter web the type File is defined in multiple classes

I have a Flutter web project, where I would like to select a picture from the device and upload it to Firebase Storage. I found this solution:
Future<void> uploadToFirebase(File imageFile) async { //I get the error here
final filePath = 'images/${DateTime.now()}.png';
StorageTaskSnapshot snapshot = await FirebaseStorage.instance
.ref()
.child(filePath)
.putFile(imageFile)
.onComplete;
print("UploadToFirebase");
if (snapshot.error == null) {
final String downloadUrl = await snapshot.ref.getDownloadURL();
await Firestore.instance
.collection("images")
.add({"url": downloadUrl, "name": "${DateTime.now()}.png"});
} else {
print('Error from image repo ${snapshot.error.toString()}');
throw ('This file is not an image');
}
}
void uploadImage() async {
InputElement uploadInput = FileUploadInputElement();
uploadInput.click();
uploadInput.onChange.listen(
(changeEvent) {
final file = uploadInput.files.first;
final reader = FileReader();
reader.readAsDataUrl(file);
reader.onLoadEnd.listen(
(loadEndEvent) async {
print("Calling uploadToFirebase");
uploadToFirebase(file);
print("Done");
},
);
},
);
}
But this code has the following error in the line with the comment:
The name 'File' is defined in the libraries 'dart:html' and 'dart:io'.
Try using 'as prefix' for one of the import directives, or hiding the name from all but one of the imports.dartambiguous_import
After this I added a hide in my import dart html:
import 'dart:html' hide File;
However this resulted in another error in the uploadImage function, where I call uploadToFirebase(file):
The argument type 'File (where File is defined in C:\Users\Asus\Documents\flutter\bin\cache\pkg\sky_engine\lib\html\html_dart2js.dart)' can't be assigned to the parameter type 'File (where File is defined in C:\Users\Asus\Documents\flutter\bin\cache\pkg\sky_engine\lib\io\file.dart)'.dartargument_type_not_assignable
html_dart2js.dart(15975, 7): File is defined in C:\Users\Asus\Documents\flutter\bin\cache\pkg\sky_engine\lib\html\html_dart2js.dart
file.dart(241, 16): File is defined in C:\Users\Asus\Documents\flutter\bin\cache\pkg\sky_engine\lib\io\file.dart
My index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="12 órás eventek kezelésére">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="event_maker">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>event_maker</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.19.0/firebase-app.js"></script>
<!-- TODO: Add SDKs for Firebase products that you want to use
https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/7.19.0/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.19.0/firebase-analytics.js"></script>
</script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
...
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
firebase.analytics();
</script>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('flutter_service_worker.js');
});
}
</script>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
Any other ideas on how to solve this? Or is there a better way to upload a file with a web app?
I'm a beginner to Flutter, so sorry, if it is a dumb question. Thanks for your help in advance!
I think you're missing a for Firebase storage. Try adding the following line:
<script src="https://www.gstatic.com/firebasejs/7.19.0/firebase-storage.js"></script>
dart:html 'File' extends Blob <-use this if uploading from web
dart:io 'File' extends FileSystemEntity <-use this if uploading from a platform with file access
in your case
use .putBlob(imageFile)
instead of .putFile(imageFile)

Foundation 6 Reveal ajax not working

I'm trying to create a reval Modal Foundation 6 and Ajac, but does not work.
I followed the official guide
Page html
<!DOCTYPE html><html lang="it">
<head>
<title>Avvisi</title>
<link href="http://ci.dev/assets/css/foundation.min.css" rel="stylesheet" type="text/css" />
<script src="http://ci.dev/assets/js/vendor/jquery.min.js" type="text/javascript">
</script><script src="http://ci.dev/assets/js/foundation.min.js" type="text/javascript"></script><script src="http://ci.dev/assets/js/foundation.reveal.js" type="text/javascript"></script><link href="http://ci.dev/assets/css/reveal.css" rel="stylesheet" type="text/css" /><link href="http://ci.dev/assets/css/motion-ui.css" rel="stylesheet" type="text/css" /><script src="http://ci.dev/assets/js/vendor/what-input.min.js" type="text/javascript"></script><script src="http://ci.dev/assets/js/vendor/motion-ui.js" type="text/javascript"></script></head>
<body>
<h2>Title</h2><p>Message</p>
<span><a href='http://ci.dev/AR-PIB/warn/edit_v/160/284'>Edit</a></span><span id='160|284'><a class='big-link' href='#' data-reveal-id='myModal' data-animation='fade'>Delete</a></span></div><hr/>
<script type="text/javascript">jQuery(document).ready(function() {
jQuery('.big-link').click(function(){
var dati = jQuery(this).parent().attr('id');
var $modal = $('#modal');
alert($modal)
$.ajax({'http://ci.dev/AR-PIB/Warn/delete'})
.done(function(resp){
alert(resp);
jQuery('body').append(resp);
$modal.html(resp.html).foundation('open');
conaole.log(resp);
});
});
});
</script>
<script src="http://ci.dev/assets/js/app.js" type="text/javascript"></script></body></html>
I'm not sure why it's not working exactly as I can't run your code (the links http://ci.dev/... seem to be local to your machine), but it may be one of the following:
You have an close div but no open
You're attempting to use the Foundation JS ($modal.html(resp.html).foundation('open'); etc.) before you have initialised Foundation (if in app.js, per your comment, this is after the Reveal code)
foundation.min.js (unless you have generated a slimmed down version) includes both the motion UI and the reveal so you don't need to add each JS file
You're missing a ; after alert($modal)
I think you mean console.log(resp); rather than conaole.log(resp);
You reference the element $('#modal') but there is no element on the page with the id modal (your link also has data-reveal-id='myModal')
According to the Foundation Docs:
http://foundation.zurb.com/sites/docs/javascript.html#adding-content-to-plugins
Just add a Foundation.reInit('abide'); and it should work right away!
I found a solution that works with Zurb Foundation 6.3.2, as explain in https://foundation.zurb.com/sites/docs/javascript.html#programmatic-use
in the ajax done function :
var $modalContent = new Foundation.Reveal($('#modalContent'));
$modalContent.open();

Polymer iron-ajax data binding example not working

I'm having problems with iron-ajax and data binding in Polymer 1.0.2. Not even a slightly changed example from the Polymer documentation is working.
Here is the code with my changes:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/iron-ajax/iron-ajax.html">
</head>
<body>
<template is="dom-bind">
<iron-ajax
auto
url="http://jsonplaceholder.typicode.com/posts/"
lastResponse="{{data}}"
handleAs="json">
</iron-ajax>
<template is="dom-repeat" items="{{data}}">
<div><span>{{item.id}}</span></div>
</template>
</template>
<script>
(function (document) {
'use strict';
var app = document.querySelector('#app');
window.addEventListener('WebComponentsReady', function() {
var ironAjax = document.querySelector('iron-ajax');
ironAjax.addEventListener('response', function() {
console.log(ironAjax.lastResponse[0].id);
});
ironAjax.generateRequest();
});
})(document);
</script>
</body>
</html>
All I changed was entering a URL to get a real JSON response and setting the auto and handleAs properties. I also added a small script with a listener for the response event. The listener is working fine and handles the response, but the spans in the dom-repeat template aren't rendered.
I'm using Polymer 1.0.2 and iron-elements 1.0.0
It seems the documentation you is missing a - character in the lastresponse attribute of the example.
You must change lastResponse to last-response.
Look at this example from the iron-ajax github page.
when you use a attribute on a element, you have to convert the camelcase sentence to dashes sentence, I mean:
lastResponse is maps to last-response
Property name to attribute name mapping

Read/write to Parse Core db from Google Apps Script

I'm just starting to use Parse Core (as Google'e ScriptDB is being decommissioned soon) and am having some trouble.
So I'm able to get Parse Core db to read/write using just a standard HTML page as shown below:
<!doctype html>
<head>
<meta charset="utf-8">
<title>My Parse App</title>
<meta name="description" content="My Parse App">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/styles.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-1.2.18.min.js"></script>
</head>
<body>
<div id="main">
<h1>You're ready to use Parse!</h1>
<p>Read the documentation and start building your JavaScript app:</p>
<ul>
<li>Parse JavaScript Guide</li>
<li>Parse JavaScript API Documentation</li>
</ul>
<div style="display:none" class="error">
Looks like there was a problem saving the test object. Make sure you've set your application ID and javascript key correctly in the call to <code>Parse.initialize</code> in this file.
</div>
<div style="display:none" class="success">
<p>We've also just created your first object using the following code:</p>
<code>
var TestObject = Parse.Object.extend("TestObject");<br/>
var testObject = new TestObject();<br/>
testObject.save({foo: "bar"});
</code>
</div>
</div>
<script type="text/javascript">
Parse.initialize("PyMFUxyBxR8IDgndjZ378CeEXH2c6WLK1wK2JHYX", "IgiMfiuy3LFjzH0ehmyf5Rkti8AmVtwcGqc6nttN");
var TestObject = Parse.Object.extend("TestObject");
var testObject = new TestObject();
testObject.save({foo: "bar"}, {
success: function(object) {
$(".success").show();
},
error: function(model, error) {
$(".error").show();
}
});
</script>
</body>
</html>
However, when I try to serve that up using the HtmlService shown below, I get no response from Parse. Parse Core.html basically has all of the code I have above ( only thing I changed was to remove the css calls).
function doGet() {
var htmlPage = HtmlService.createTemplateFromFile('Parse Core.html')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.NATIVE)
.setTitle('Parse Core Test');
return htmlPage;
}
Link to ParseDb Library for Apps Script
Here is the key to add the library: MxhsVzdWH6ZQMWWeAA9tObPxhMjh3Sh48
Install that library and it allows you to use most of the same methods that were used by ScriptDb. As far as saving and querying go they almost identical. Make sure to read the Library's notes, how to add the applicationId and restApiKey. It is a little different that you can silo data by classes which must be defined in the call to Parse.
Bruce here is leading the way on database connection for Apps Script, he has plenty of documentation on using Parse.com, and also his own DbConncection Drive that would allow you to use a number of back-end systems.
Excel Liberation - Bruce's Site.

Resources