Question

I am wondering it is possible to create a working Google map in a virtual element which can then be pasted into any page at any time.

So here is my JS when targeting an element which already exists on the page.

var mapLatLong = new google.maps.LatLng(51.5174456, -0.1305081);
var markerLatlng = new google.maps.LatLng(51.5170951, -0.1367416);

var mapOptions = {
    zoom: 16,
    center: mapLatLong,
    mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map($('#map_canvas'), mapOptions);

var contentString = '<div id="content">'+
                        '<div id="siteNotice">'+
                        '</div>'+
                        '<h1 id="firstHeading" class="firstHeading">BrocklebankPenn</h1>'+
                        '<div id="bodyContent">'+
                            '<p>5th floor, 58-60 Berners Street,<br />London,<br />W1T 3NQ,<br />United Kingdom</p>'+
                            '<p>+44 (0)20 3137 7034</p>'+
                        '</div>'+
                    '</div>';

var infowindow = new google.maps.InfoWindow({
    content: contentString
});

var marker = new google.maps.Marker({
    position: markerLatlng,
    map: map,
    title: 'BrocklebankPenn'
});

google.maps.event.addListener(marker, 'click', function() {
    infowindow.open(map,marker);
});

infowindow.open(map,marker);

What I want to do is something like this:

this.mapCanvas = document.createElement('div');
this.mapCanvas.setAttribute('id', 'map_canvas');

var mapLatLong = new google.maps.LatLng(51.5174456, -0.1305081);
var markerLatlng = new google.maps.LatLng(51.5170951, -0.1367416);

var mapOptions = {
    zoom: 16,
    center: mapLatLong,
    mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map($(this.mapCanvas), mapOptions);

var contentString = '<div id="content">'+
                        '<div id="siteNotice">'+
                        '</div>'+
                        '<h1 id="firstHeading" class="firstHeading">BrocklebankPenn</h1>'+
                        '<div id="bodyContent">'+
                            '<p>5th floor, 58-60 Berners Street,<br />London,<br />W1T 3NQ,<br />United Kingdom</p>'+
                            '<p>+44 (0)20 3137 7034</p>'+
                        '</div>'+
                    '</div>';

var infowindow = new google.maps.InfoWindow({
    content: contentString
});

var marker = new google.maps.Marker({
    position: markerLatlng,
    map: map,
    title: 'BrocklebankPenn'
});

google.maps.event.addListener(marker, 'click', function() {
    infowindow.open(map,marker);
});

infowindow.open(map,marker);

this.$el.html(this.mapCanvas);

Basically the exact same thing but with a variable instead of #map_canvas, I have taken this approach with JS in the past but it does not seem to be working for Google maps, I get the following error:

Uncaught TypeError: Cannot set property 'position' of undefined 

Which I am not sure of.

If anyone can help that would be awesome.

Cheers, Luke.

Was it helpful?

Solution

Basically it's possible, Demo: http://jsfiddle.net/doktormolle/5SjnK/

The issues with your code:

var map = new google.maps.Map($(this.mapCanvas), mapOptions);

$(this.mapCanvas) is a jQuery-object, but it's expected to be an HTML-Element

this.$el.html(this.mapCanvas);

Don't set the html, you must insert the original node into the document.

But I wouldn't suggest it, there will be more issues, e.g. when you use API-methods that try to access the parentNode of the map-div or methods that need to calculate positions inside the document(both will fail before the node has been inserted into the document).

Related to pasted into any page:

It's not possible, the document where you use the map must be the same document where you load the API, the API internally uses references to the window/document where the API has been loaded. See this question: Marker drag not working in iframe under Chrome and Firefox

But as long as any page doesn't mean "any document"(regarding to your description it's always the same document) it's possible.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top