locked
The Metro application does not allow JavaScript to use external network file?

    Question

  • The Metro application does not allow JavaScript to use external network file?

    Sunday, October 09, 2011 1:23 PM

Answers

  • OK here is a simple example.

    First the main html file:

    default.html

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>Map Help Example</title>
        <!-- WinJS references -->
        <link rel="stylesheet" href="/winjs/css/ui-dark.css" />
        <script src="/winjs/js/base.js"></script>
        <script src="/winjs/js/ui.js" type="text/javascript"></script>
        <script type="text/javascript" src="winjs/js/binding.js"></script>
        <script src="/winjs/js/animations.js" type="text/javascript"></script>
        <script src="/winjs/js/uicollections.js" type="text/javascript"></script>
        <script src="/winjs/js/wwaapp.js"></script>
        <!-- WinWebApp2 references -->
        <link rel="stylesheet" href="/css/default.css" />
        <script src="/js/default.js"></script>
        <link href="/app-ui.css" rel="stylesheet" type="text/css">
    </head>
    <body>
        <div id="appBody">
            <h1 id="head_title">
                Map Example</h1>
            <div id="status">
                Hello</div>
            <button type="submit" id="paris">Paris</button>
            <div id="mapSection">
                <iframe id="mapIframe" src="ms-wwa-web:///map.html"></iframe>
            </div>
        </div>
    </body>
    </html>
    
    

    Add another html file to host the map api.  In this example it is named 'map.html'.

    map.html

    <!--This file is used to render the map API and will be included in an iFrame of the main html.-->
    <!DOCTYPE html>
    <html>
    <head>
    
        <title>Map</title>
        <link href="winjs/css/ui-light.css" rel="stylesheet" type="text/css" />
        <!-- We can include remote scripts because it is rendered in the web context (ms-wwa-web:///map.html)  -->
        <script src="http://maps.googleapis.com/maps/api/js?sensor=false" type="text/javascript"></script>
        <script src="js/map.js" type="text/javascript"></script>
        <style type="text/css">
           
            #map
            {
              position:absolute;
              width:100%;
              height:100%;
            }
    
        </style>
    </head>
    <body>
        <div id="map"></div>
    </body>
    </html>
    
    

    Here is the main JavaScript file which handles a button click event and sends a command to the map script.

    default.js

    (function () {
        'use strict';
        // Uncomment the following line to enable first chance exceptions.
        Debug.enableFirstChanceException(true);
    
        function id(elementId) {
            return document.getElementById(elementId);
        }
    
        WinJS.Application.onmainwindowactivated = function (e) {
            if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
                // TODO: startup code here
                WinJS.UI.processAll();
    
                //Button event listener
                paris.addEventListener("click", changeLocation, false);
            }
        }
    
        WinJS.Application.start();
    
        //Button event handler which sends command to map to go to Paris.
        function changeLocation(e) {
    
            id("status").innerText = "Zooming to Paris";
    
            //Construct a message to send
            var msg = {
                command: 'zoomTo',
                latitude: 48.863811,
                longitude: 2.351761,
                zoom: 8
            };
    
            //Convert message object to string and send to the map control.
            var msgS = JSON.stringify(msg);
            document.frames['mapIframe'].postMessage(msgS, "ms-wwa-web://" + document.location.host);
    
        }
    
    })();
    

    Add another JavaScript which is used by the map html file.  It will interact with the main program and the map API.

    map.js

    //This script handles all of the controls to the map API
    (function () {
        'use strict';
    
        var map;
    
        //Process messages from main script
        window.addEventListener("message", receiveMessage, false);
        function receiveMessage(event) {
            if (event.origin === "ms-wwa://" + document.location.host) {
    
                //Return the message string to an object
                var messageObject = JSON.parse(event.data);
               
    
                //If message is to zoom, change the location and zoom level
                if (messageObject.command == "zoomTo") {
                    var newCenter = new google.maps.LatLng(messageObject.latitude, messageObject.longitude);
                    var newOptions = {
                        zoom: 8,
                        center: newCenter,
                        mapTypeId: google.maps.MapTypeId.ROADMAP
                    };
                    map.setOptions(newOptions);
                }
            }
        }
    
    
        function initialize() {
            var latlng = new google.maps.LatLng(38.96, -96.78);
            var myOptions = {
                zoom: 4,
                center: latlng,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            map = new google.maps.Map(document.getElementById("map"),
            myOptions);
    
        }
    
        document.addEventListener("DOMContentLoaded", initialize, false);
    })();
    
    

    Finally, here is some css to format the example.

    app-ui.css

    body
    {
    }
    
    #appBody {
    	width: 100%;
    	height: 100%;
    	display: -ms-grid;
    	-ms-grid-rows: 100px 85px 520fr 60px;
    	-ms-grid-columns: 42px 405px 9px 846fr 64px;
    }
    
    #head_title {
    	margin-bottom: -8px;
    	margin-top: 0px;
    	-ms-grid-column: 2;
    	-ms-grid-row-align: end;
    	-ms-grid-column-span: 5;
    }
    
    	
    .Title {
    	-ms-grid-column: 2;
    	-ms-grid-row: 1;	
    }
    
    
    #mapSection
    {
        -ms-grid-column: 4;
        -ms-grid-row: 1;
        -ms-grid-row-span: 4;
        -ms-grid-column-span: 2;
    }
    
    #mapIframe {
    	width: 100%;
    	height: 100%;
    }
    
    #status {
    	-ms-grid-column: 2;
    	-ms-grid-row: 2;
    	-ms-grid-row-align: center;
    }
    
    #paris {
    	-ms-grid-column: 2;
    	-ms-grid-row: 3;
    	width: 59px;
    	height: 35px;
    }
    	
    	
    	

    I hope this helps.

     

    Monday, October 10, 2011 4:13 PM

All replies

  • Security restrictions prevent you from loading a script (the google API)  from an external source.

    However, you can load an external script through a local html file that can be displayed in an iframe element.  You can send commands to the iframe from your main application.  See the mashup sample to see how to do this.

    By the way, I think this is one thing that, at the moment, you can not do at all with C# Metro programming.


    • Edited by jrboddie Sunday, October 09, 2011 2:57 PM
    Sunday, October 09, 2011 2:56 PM
  • Hello,Please help me write an example of you?
    Monday, October 10, 2011 4:42 AM
  • OK here is a simple example.

    First the main html file:

    default.html

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>Map Help Example</title>
        <!-- WinJS references -->
        <link rel="stylesheet" href="/winjs/css/ui-dark.css" />
        <script src="/winjs/js/base.js"></script>
        <script src="/winjs/js/ui.js" type="text/javascript"></script>
        <script type="text/javascript" src="winjs/js/binding.js"></script>
        <script src="/winjs/js/animations.js" type="text/javascript"></script>
        <script src="/winjs/js/uicollections.js" type="text/javascript"></script>
        <script src="/winjs/js/wwaapp.js"></script>
        <!-- WinWebApp2 references -->
        <link rel="stylesheet" href="/css/default.css" />
        <script src="/js/default.js"></script>
        <link href="/app-ui.css" rel="stylesheet" type="text/css">
    </head>
    <body>
        <div id="appBody">
            <h1 id="head_title">
                Map Example</h1>
            <div id="status">
                Hello</div>
            <button type="submit" id="paris">Paris</button>
            <div id="mapSection">
                <iframe id="mapIframe" src="ms-wwa-web:///map.html"></iframe>
            </div>
        </div>
    </body>
    </html>
    
    

    Add another html file to host the map api.  In this example it is named 'map.html'.

    map.html

    <!--This file is used to render the map API and will be included in an iFrame of the main html.-->
    <!DOCTYPE html>
    <html>
    <head>
    
        <title>Map</title>
        <link href="winjs/css/ui-light.css" rel="stylesheet" type="text/css" />
        <!-- We can include remote scripts because it is rendered in the web context (ms-wwa-web:///map.html)  -->
        <script src="http://maps.googleapis.com/maps/api/js?sensor=false" type="text/javascript"></script>
        <script src="js/map.js" type="text/javascript"></script>
        <style type="text/css">
           
            #map
            {
              position:absolute;
              width:100%;
              height:100%;
            }
    
        </style>
    </head>
    <body>
        <div id="map"></div>
    </body>
    </html>
    
    

    Here is the main JavaScript file which handles a button click event and sends a command to the map script.

    default.js

    (function () {
        'use strict';
        // Uncomment the following line to enable first chance exceptions.
        Debug.enableFirstChanceException(true);
    
        function id(elementId) {
            return document.getElementById(elementId);
        }
    
        WinJS.Application.onmainwindowactivated = function (e) {
            if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
                // TODO: startup code here
                WinJS.UI.processAll();
    
                //Button event listener
                paris.addEventListener("click", changeLocation, false);
            }
        }
    
        WinJS.Application.start();
    
        //Button event handler which sends command to map to go to Paris.
        function changeLocation(e) {
    
            id("status").innerText = "Zooming to Paris";
    
            //Construct a message to send
            var msg = {
                command: 'zoomTo',
                latitude: 48.863811,
                longitude: 2.351761,
                zoom: 8
            };
    
            //Convert message object to string and send to the map control.
            var msgS = JSON.stringify(msg);
            document.frames['mapIframe'].postMessage(msgS, "ms-wwa-web://" + document.location.host);
    
        }
    
    })();
    

    Add another JavaScript which is used by the map html file.  It will interact with the main program and the map API.

    map.js

    //This script handles all of the controls to the map API
    (function () {
        'use strict';
    
        var map;
    
        //Process messages from main script
        window.addEventListener("message", receiveMessage, false);
        function receiveMessage(event) {
            if (event.origin === "ms-wwa://" + document.location.host) {
    
                //Return the message string to an object
                var messageObject = JSON.parse(event.data);
               
    
                //If message is to zoom, change the location and zoom level
                if (messageObject.command == "zoomTo") {
                    var newCenter = new google.maps.LatLng(messageObject.latitude, messageObject.longitude);
                    var newOptions = {
                        zoom: 8,
                        center: newCenter,
                        mapTypeId: google.maps.MapTypeId.ROADMAP
                    };
                    map.setOptions(newOptions);
                }
            }
        }
    
    
        function initialize() {
            var latlng = new google.maps.LatLng(38.96, -96.78);
            var myOptions = {
                zoom: 4,
                center: latlng,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            map = new google.maps.Map(document.getElementById("map"),
            myOptions);
    
        }
    
        document.addEventListener("DOMContentLoaded", initialize, false);
    })();
    
    

    Finally, here is some css to format the example.

    app-ui.css

    body
    {
    }
    
    #appBody {
    	width: 100%;
    	height: 100%;
    	display: -ms-grid;
    	-ms-grid-rows: 100px 85px 520fr 60px;
    	-ms-grid-columns: 42px 405px 9px 846fr 64px;
    }
    
    #head_title {
    	margin-bottom: -8px;
    	margin-top: 0px;
    	-ms-grid-column: 2;
    	-ms-grid-row-align: end;
    	-ms-grid-column-span: 5;
    }
    
    	
    .Title {
    	-ms-grid-column: 2;
    	-ms-grid-row: 1;	
    }
    
    
    #mapSection
    {
        -ms-grid-column: 4;
        -ms-grid-row: 1;
        -ms-grid-row-span: 4;
        -ms-grid-column-span: 2;
    }
    
    #mapIframe {
    	width: 100%;
    	height: 100%;
    }
    
    #status {
    	-ms-grid-column: 2;
    	-ms-grid-row: 2;
    	-ms-grid-row-align: center;
    }
    
    #paris {
    	-ms-grid-column: 2;
    	-ms-grid-row: 3;
    	width: 59px;
    	height: 35px;
    }
    	
    	
    	

    I hope this helps.

     

    Monday, October 10, 2011 4:13 PM
  • I followed your this reply and it worked. But now I want to use Google Maps Webservices like Geocoding API.
    So i will need to send Httprequest using "WinJS.xhr", right?
    So  did it and it actually fetched and parsed the JSON response. But i am not able to use it out of "xhr" block. So how to access the fetched lat&lng to display it on map in windows 8 ?

    I am writing two methods which i tried to display location on map using lat&lng fetched by xhr.

    1)i created separate file for displaying map for convenience.
    map.js
      var address1 = "http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false";
        var lat1;
        var lng1;
        //var place1;
        (function () {
            "use strict";
            function getData() {
                WinJS.xhr({ url: address1 }).then(function (response) {
    
                    var place1 = JSON.parse(response.response);
                    return place1;
    
    
                });
            }
            WinJS.Namespace.define('data', {
                getData: getData
            });
        })();
    
        lat1 = data.getData().results[0].geometry.location.lat;
        lng1 = data.getData().results[0].geometry.location.lng;
        var location1 = new google.maps.LatLng(lat1, lng1);
        function initialize() {
            var mapOptions = {
                center: location1,
                zoom: 8,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            var map = new google.maps.Map(document.getElementById("map-canvas"),
                mapOptions);
        }
        google.maps.event.addDomListener(window, 'load', initialize);
    
    2)In this mathod, lat1 & lng1 turns to be null after "xhr" code block but actually it stored correct data while parsing.
     
        var address1 = "http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false";
        var lat1;
        var lng1;
        var place1;
    
                WinJS.xhr({ url: address1 }).then(function (response) {
    
                    place1 = JSON.parse(response.response);
                    lat1 = place1.results[0].geometry.location.lat;
                    lng1 = place1.results[0].geometry.location.lng;
                });
        
        var location1 = new google.maps.LatLng(lat1, lng1);
        function initialize() {
            var mapOptions = {
                center: location1,
                zoom: 8,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            var map = new google.maps.Map(document.getElementById("map-canvas"),
                mapOptions);
        }
        google.maps.event.addDomListener(window, 'load', initialize);
    
    Please write a full code if i am doing completely wrong. I want to parse JSON formatted Google Maps service response and display it on Google Map on windows 8 application. I am building app using HTML CSS javascript

    Thank You


    Sunday, April 14, 2013 11:36 PM
  • it seems postMessage does not work with windows 8.1

    Monday, October 28, 2013 6:21 AM