Google Maps v3 + Backbone + Marionette: Map fails to render the second time - google-maps

I'm trying to display a map by creating a view and inserting it into DOM, and it works fine the first time, but fails on subsequent invocations of the view, displaying a gray empty area.
Here is the JSFiddle of the problem: http://jsfiddle.net/dyuvH/14/
Everything works fine when you click on the 'Click to load map' link, but will fail if you do it again.
I'm loading a map into a view using the following:
onRender: function() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var mapView = new App.MapView();
var map = new google.maps.Map(mapView.el, mapOptions);
mapView.render();
this.ui.mapContainer.html(mapView.el);
}
Again, everything works perfectly the first time and fails the second. I'm thinking the view is holding on to some aspect of the map or vice-versa. I do create new instances of the map and the view using the "new" keyboard in both cases, so I'm not sure what's messed up.
Any help is appreciated.

The call to mapView.render() is not necessary, and can be removed or commented out. That will at least get the map to render upon subsequent clicks.
You will also need to compensate for Issue 1448 in the GMaps API v3. Something along this code should work to solve the off-centered map on subsequent renderings:
google.maps.event.addListener(map, "idle", function(){
map.setCenter(mapOptions.center);
google.maps.event.trigger(map, 'resize');
});
For reference, the updated jsFiddle with the above suggestions.

I had the same problem and after reading #19 of Issue1448 I decided to use onShow instead of onRender and then it worked like a charm. This way I didn't need to trigger any map resize event or trying to work out the center of the map.

Related

How to reinitialize Google map API?

I am new to the coding part.So I am in need for your kind ideas.
How can i reinitialize the loaded Google map API in one HTML page (eg: MapView.html) from parent HTML page using IFRAME tag?
Is there any possibilities to reload the Google map to view the updated markers in new page without pressing F5 key?
The iframe part makes it very difficult as iframe is used basically for accepting content from an external source without any changes. It would be easier if you injected the script which utilizes Google Map in every page you use it.
I don't understand much what you mean by parent HTML :( If it is a single-page application and the child HTML is a subview of the parent, you could be able to access the parent HTML's controller but I have the feeling that this is not the case :)
So generally you can reinitialize the map using JavaScript. Have a look in the API Reference for all the options:
https://developers.google.com/maps/documentation/javascript/3.exp/reference
If you could create the map in your child HTML, the Marker can be created and updated by following:
var map = new google.maps.Map(document.getElementById('map'), yourMapOptions); // This is the map initiation in a #map element
var marker = new google.maps.Marker({
position: new google.maps.LatLng(...), // the old position
map: map, // The map you created in your element by new google.maps.Map(...)
icon: 'assets/marker.png',
title: 'This is the pointer',
});
setTimeout(function() {
marker.position = new google.maps.LatLng(...); // new position
marker.setMap(map); // This reinitializes the marker
}, 10000); // For this example I set a 10s timeout
Sorry if the iframe is an important thing but without any code I assumed this could help you more than hacking an iframe.

Marker drag not working in iframe under Chrome and Firefox

I'm working on embedding the google map, into a page, containing multiple iframes. It can happen, that I load 2 maps, into 2 different iframes at the same time. This is the reason why the Map API loaded only once, in the main document's head section:
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDY0kkJiTPVd2U7aTOAwhc9ySH6oHxOIYM&v=3&sensor=false" type="text/javascript"></script>
For loading the map inside the iframe, I wrote the following code, which runs inside the iframe:
var googleAPI = window.top.google;
var latLong = new googleAPI.maps.LatLng(31.7655374094844,93.515625);
var map = new googleAPI.maps.Map(document.getElementById("map-container"), {
zoom: 8,
center: latLong,
mapTypeId: googleAPI.maps.MapTypeId.ROADMAP
});
The map appears correctly on the page, without any errors. I also add a marker on the map and I want to allow the users to change the marker's position, by drag&drop
var simpleMarker = new googleAPI.maps.Marker({
position: latLong,
map: map,
draggable: true,
animation: googleAPI.maps.Animation.DROP,
title: 'Marker'
});
While under IE the marker's drag&drop without any problems, under Chrome&Firefox the drag it's not working as expected: sometimes the drag stops or you even get an endless drag.
My guess is that this is caused because the API was loaded in the main document, and after referenced from inside the iframes. I do not wish to change this, mostly because like I previously mentioned, I can have several maps on the page.
Is there a fix for the drag&drop issue?
I would appreciate any help you could give me,
Thanks
I don't have a solution, I'm afraid this kind of API-usage is not intended.
Take a look at the start of the API (https://maps.gstatic.com/intl/en_ALL/mapfiles/api-3/16/10/main.js)
(function(){'use strict';var k=window/*..more code..*/}).call(this);
This function will be called in the parent document of the iframe, the variable k(which will be used internally by the API as reference to the window-object) will always refer to the parent window of the iframe what will result in incorrect values when observing events (e.g. mousemove when you drag a marker) in the iframe.

Google Maps API v3 not loading correctly in IE in hidden div with iframe but loads perfectly in all other browsers

Ok I have searched high and low for a solution to this. Everything I have found is not quite working. This is a similar problem to the Google maps not appearing in a hidden div using jquery tabs. However I have the map loading correctly staying loaded and holding the zoom when when navigating to another tab and back in Chrome, Firefox, Opera and Safari.
So my problem as usual is IE.
The way I have set it up is to hide the div initially and then to display it and load in an iframe with the map code in it. As I say it works fine on all but IE where it loads the map in the left hand corner with no resize ability. I'm assuming this is down to the way IE deals with processing javascript. I've tried loads of suggestions on here but all fail in IE so wonder if anyone has come across this before and if any workaround is available.
The code below is to initialise the map. The call to the function is the last thing in page after the closing html tag.
This page is then loaded into a div tag via an iframe when a ui.tab is pressed to change the div panel displayed.
Any clues or tips would be most welcome.
function initialize() {
var myLatlng = new google.maps.LatLng(50.66416319854267,-1.1316803097724914);
var myOptions = {
zoom: 10,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.SATELLITE
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var marker = new google.maps.Marker({
draggable: false,
position: myLatlng,
map: map,
icon: '../images/yellow-pin.png',
title: ""
});
google.maps.event.trigger(map, 'resize'); // added from another forum post does not work
}
That is the typical hidden "top left corner" issue.
Have you tried using an onload function to run the initialize function?
The problem is that the javascript code (the trigger "resize") in the iframe is being executed when the page is loaded, not when it is displayed. When it is loaded the div has zero size. You need to trigger the resize function on the map after the div is diplayed and has a size.

Recreating Standard Google Map embed with Google Maps API

So, having been recently somewhat dissapointed with lack of customizability of the regular google maps "embed" (iframe) code; I have started tinkering with the Google Maps API v3. Really, all I want to do is show a marker for a business on the map, so that you can click it and go to that "place" at mapsgoogle.com.
So pretty much, I just want to recreate the functionality of the iframe code below. I put in about an hour of reading the docs, but it seems extremely complicated just to get the marker associated with a 'place'
The place
https://maps.google.com/maps?cid=1311411133662139490
The standard Embed
<iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?cid=1311411133662139490&ie=UTF8&hq=&hnear=&t=m&iwloc=A&ll=41.097905,-73.405006&spn=0.006295,0.006295&output=embed"></iframe><br /><small>View Larger Map</small>
It appears as though there is no functionality in the api to use the cid.
To Elaborate a little
Generally I would use this just for small business websites. I was frustrated with the regular iframe embed and lack of customizability. Essentially I want a starting point from which I can play with stuff and heavily customize the look/feel, but have been unable to put a marker in that's associated with the data for a "place" - allowing for the little pop-up window, etc..
Honestly, I didn't really do enough research before asking this question - and came in with some misconceptions. I think, and I may be wrong, that the API is still what I want to be using ultimately, but had I know about the functionality in Rick's answer, I probably would have settled on that and procrastinated longer on learning the gmaps API.
Allow me to explain one option of achieving your goal. I use the marker and infoWindow objects that Google Maps API v3 offers, which you can find in the document I attached in the link. Feel free to follow along in the jsFiddle I created: http://jsfiddle.net/bgvYH/
First thing is first, you want to initiate your map with its options - I'm going to assume you know what the different variables in following code snippet represent:
var myLatlng = new google.maps.LatLng(41.097905,-73.405006);
var myOptions = {
zoom: 16,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
If you want to customize your map even more to your liking, have a look at the different options you can set in the API reference, you'll set these options in the myOptions object ( https://developers.google.com/maps/documentation/javascript/reference#MapOptions ).
Note: I set the center of the map to the Lat/Long coordinates of the restaurant - which I took from the URL you provided in the iframe ll=41.097905,-73.405006.
Now what you want to do next is determine the content you want to display in your infoWindow, so the restaurant information:
var contentString = "<div id='content'>";
contentString += "<div id='title'>Mr. Frosty's Deli and Grill</div>";
contentString += "<div id='info'><p>10 1st Street</p><p>Norwalk, CT 06855</p><p>(203) 956-5767</p><p><a href='http://thebeachburger.com/'>thebeachburger.com‎</a></p></div></div>";
You may even end up pulling this information from a database or JSON object in the future, depending on how deep you go into this project (for now I have it as static HTML).
Next we initialize the infoWindow object and set the contentString to the content option of the infoWindow. There are other options you can customize here (just like the map options, again look at the reference for InfoWindowOptions: https://developers.google.com/maps/documentation/javascript/reference#InfoWindowOptions )
var infowindow = new google.maps.InfoWindow({
content: contentString
});
After setting up your infoWindow object, you initialize your marker object - which will place the drop the bubble on the map. Once again, you set up the options for the marker when initializing much like you did with the map object and the infoWindow object - you can further customize it to your liking by looking at the reference (I think there's even an option in there for the marker where you can use custom icons - you can get pretty creative here).
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title:"Mr. Frosty's Deli and Grill"
});
And finally, you need to bind the Marker and the infoWindow together - so that when a user clicks on the marker the info pops up. This is achieved by using the event listener, and you listen for a "click" action on the marker variable. Read this document for information on events on google maps https://developers.google.com/maps/documentation/javascript/events. Likewise look through the API Reference for the different events you can listen to on an object.
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
That should do it, you should have a working alternative to the iframe you include - except now you can customize the map and the actions you perform on it to however you want. In the jsFiddle I also included some styling, just to make things look nice inside the infoWindow.
Now, I want to let you know - I believe there is another option to what your looking for - but I have yet to experiment with this API. It is the Google Places API, which you'll have register for. But from what I read through the documents, I think you may be able to achieve what you want to do. Have a look at it ( https://developers.google.com/maps/documentation/places/ ), and see what's good.
It looks like this was created through 'My Places' and made public. If you don't want to mess with the API then that's your best bet.
Visit maps.google.com, click 'My Places' and 'Create Map'. Customize and grab the embed code.
If the map doesn't need to be interactive (beyond the click action), use a static map. It's just an image so you can wrap it in an anchor that points exactly where you want.

Google Maps API V3 "Overview" option

Google Maps API V3 doesn't support the V2 GOverviewMapControl option, yet. I've come across a piece of code at http://dl.google.com/io/2009/pres/Th_1045_Maps_API_Mobile.pdf , silde 19, that gives the code to display the smaller map, but not the draggable, semi-transparent blue box that you generally see here. It's possible, but unofrtunately the code is 'ellided'. Anyone have any ideas how to generate this? Thanks
This is how it works out of the box in Maps v3:
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
overviewMapControl: true,
overviewMapControlOptions: {opened: true}
}
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
}
Please note the last two properties of the mapOptions object. They do the trick.
Within the overlayMap, add a draggable marker to display the frame of the RectangleOverlay, and a non-draggable marker to display the semi-transparent box itself. Then, add bindings to some of the maps' events to update size and position of the markers, i.e. the maps' bounds_changed, drag, and/or center_changed events. Finally, update the location of the maps when the frame is dragged by binding a function to its dragend event.
I am using v3 right now and the overviewMapControl seems to work. Can't find any documentation on it yet.
overviewMapControl: true
Then you see a small arrow in the right hand side of your map. Click will open it. Can't figure out how to trigger this click with javascript (jquery) doesn't seem to work.
Check out http://code.google.com/p/gmaps-api-v3-overviewmapcontrol It's an open-source project to approximate the functionality of v2's GOverviewMapControl.