Google Maps: InfoWindow closing after auto pan - google-maps-api-3

I have a map with a bunch of markers, and a table of data that corresponds to each marker. When the user clicks on an item in the table, the InfoWindow for the corresponding marker is opened. Everything works fine when the map is zoomed out and the markers are all visible, but if the map is zoomed in, and an InfoWindow for an off-screen marker is opened by clicking the item in the table, here is what happens:
The map scrolls to the correct location, where the InfoWindow already appears open
The map stops panning, and the InfoWindow disappears.
Any suggestions as to what might be going on and how to solve this?

Alright, the issue related to the fact that I was using the Marker Clusterer on the map... essentially, the following was happening:
Click item in table, InfoWindow opens
Map gets panned to the location to display the InfoWindow
When panning is complete, the Marker Clusterer was then re-drawing (if needed), and forcing the InfoWindow closed.
My solution was that when an item in the table is clicked, I get the corresponding Marker's latlng, manually pan to this location, wait for the panning to complete via the 'idle' listener, and when complete (and the Clusterer has done it's re-draw), THEN I open the InfoWindow.
// get map, marker positions
var mapLatLng = GLOBAL_map.getCenter();
var markerLatLng = GLOBAL_markers[index].getPosition();
// pan the map
if(!markerLatLng.equals(mapLatLng)) {
// map will need to pan
GLOBAL_map.panTo(markerLatLng);
google.maps.event.addListenerOnce(GLOBAL_map, 'idle', function() {
// open InfoWindow
GLOBAL_infowindow.setContent(GLOBAL_markers_content[index]);
GLOBAL_infowindow.open(GLOBAL_map, GLOBAL_markers[index]);
});
} else {
// map won't be panning, which wouldn't trigger 'idle' listener
GLOBAL_infowindow.setContent(GLOBAL_markers_content[index]);
GLOBAL_infowindow.open(GLOBAL_map, GLOBAL_markers[index]);
}

This drove me crazy. My solution is simpler, though. I just set a timer so I don't refresh the map within one second after a pin is clicked.
start with the global:
// global timer variable
var clickTime = Date.now() - 1001;
then define you marker click like:
marker.addListener('click', function() {
infoWindow.setContent(infowincontent);
infoWindow.open(map, marker);
clickTime = Date.now();
});
then set up your idle like:
google.maps.event.addListener(map, 'idle', function () {
if (Date.now() > (clickTime + 1000))
updateMap();
});

Don't use idle event. Use dragend and zoom_changed events from the API spec instead which will allow you to open your infoBoxes without refreshing the map.
google.maps.event.addListener(map, 'dragend', function() {
getMarkers();
});
google.maps.event.addListener(map, 'zoom_changed', function() {
getMarkers();
});

Related

Why does google maps js api marker mousein event happen when slightly out of marker?

My goal is to have the following behavior:
mousein on marker - open infowindow;
mouseout of marker - close infowindow;
But, when I mousein from top of the marker, still not reaching the marker, but very close to the marker from top, the infowindow is opened; then, the mouse is on the tip of the infowindow, which now triggers the mouseout event from the marker - probably since the mouse is now considered on the tip of the infowindow. Then, the infowindow closes, and the mousein is triggered, and this happens infinitely.
Is there a way to "tell" the API to only trigger marker mousein event when the mouse is actually on the marker? Or, is there another way to avoid this loop?
EDIT: here is how fast the loop goes:
web.js:1447 mouseover: 10:53:56.209
web.js:1452 mouseout: 10:53:56.233
web.js:1447 mouseover: 10:53:56.258
web.js:1452 mouseout: 10:53:56.291
web.js:1447 mouseover: 10:53:56.297
web.js:1452 mouseout: 10:53:56.315
web.js:1447 mouseover: 10:53:56.339
web.js:1452 mouseout: 10:53:56.376
web.js:1447 mouseover: 10:53:56.401
web.js:1452 mouseout: 10:53:56.435
There is no event such as mousein in the JavaScript UI Events in Google Maps JS v3. You have to use mouseover instead of mousein. Please check the Events documentation to learn more about events and also the Marker class reference. You may see this in the doc:
Events: animation_changed, click, clickable_changed, cursor_changed, dblclick, drag, dragend, draggable_changed, dragstart, flat_changed, icon_changed, mousedown, mouseout, mouseover, mouseup, position_changed, rightclick, shape_changed, title_changed, visible_changed, zindex_changed
It should be used like this:
marker.addListener('mouseover', function() {
infowindow.open(map, marker);
});
marker.addListener('mouseout', function() {
infowindow.close();
});
Click on this link to see it in action.

how to add listener for markerclusterer finished loading?

I already added a map load listener after which i start adding markers to the cluster.
I wanna display a loading screen till the markerclusterer finishes the marker loading.
so how do i do that ?
this is my hide loading screen code which hides on map tiles load.
google.maps.event.addListener(map, 'tilesloaded', function() {
$("#loading").hide();
});
I know it's an old one but for anyone in the same situation I sort of found a solution.
Right after you are creating your cluster
markerCluster = new MarkerClusterer(map,
markers,
{
imagePath:
"/img/m/"
});
Add a listener for 'zoom_changed' like that:
google.maps.event.addListenerOnce(map,
'zoom_changed',
function(event) {
console.log("zoom occured");
});
(The listener once being key here, you don't want it to run every time the user zooms, you don't even need to set a different zoom value, nothing will happen visually)
and then:
map.setZoom(10);
I am using the same value (10) as in my InitMap function, so the user doesn't see any zoom in or outs.

addDomlistener on dynamically loaded google map

I have a button that toggles a chart on the page I'm creating. First I created it using the google maps api example, but then I found out there is no way to position it in a custom location except the predefined places, so I recreated it with html/css in my grid.
It works, however when I'm using .load() to replace the map canvas and chart with a new set, the if-else statement is ignored and with one mouse click the console log writes: click2, click. The map is not resized and the chart just jumps in and out. Also the classes I'm adding and removing are stay intact.
var chartbtn = document.getElementById('chart-id');
google.maps.event.addDomListener(chartbtn, 'click', function(event) {
if( $(chartbtn).hasClass('open') ) {
$('.plot').animate({"bottom" : "-190px"}, 200);
$('#map_canvas').height( winHeight - 40 + 'px');
$(chartbtn).removeClass('open').addClass('closed');
google.maps.event.trigger(map, 'resize');
map.fitBounds(bounds);
console.info('click');
} else {
$('.plot').animate({"bottom" : "0px"}, 200);
$('#map_canvas').height( winHeight - 230 + 'px');
$(chartbtn).removeClass('closed').addClass('open');
google.maps.event.trigger(map, 'resize');
var newbounds = map.getBounds();
map.fitBounds(newbounds);
console.info('click2');
}
});
How come that everything works with the newly loaded map (xml data, markers, infowindows etc.) but not this click function?

How to prevent infowindow data loss when drag or click a marker many times?

Let say i wanna make a new place in my app (based-on google map API v3). Whenever click on "add new place" button, a marker appears in my current location on the map. And when I click on the marker or drag it to somewhere that I wanna put my place, an infowindow bound with this marker appears so that i can input data.
But each time I click or drag my marker, all my text I've input into my infowindow before was lost. Someone can tell me the way to prevent data loss when drag or click on marker many times?
Here is my code to listen for clicking or dragend
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
google.maps.event.addListener(marker, 'dragend', function() {
infowindow.open(map, marker);
});
Thanks
p/s: my English isnt very good
In your maker click function you should check if the infowindow is already open and if it is then don't open it again.

marker clusterer - merging markers info window content

Does any one have a clue how to add an info windows to the cluster markers, containing the merged markers info window content?
This is an of the default marker clusterer behaviour:
http://www.psop.fr/MAP_Population_Google.php
thanks
You should listen to the clusterclick event on the markercluster. The object that is passed into the event contains an array of markers that are in the cluster and the position of the cluster.
google.maps.event.addListener(markerCluster, 'clusterclick', function(cluster) {
markers = cluster.getMarkers();
info = "";
$.each(markers, function(x, marker) {
if(me.infowindows[marker.__gm_id]){
info = info + "<br/>" + me.infowindows[marker.__gm_id].content;
}
});
.....
something like that works, you get the markers associated with the clusterclick. and then loop through the infowindows, i'm not sure how yours is set up. but the above code should make sense.
you also need to disable the zoom on click as the clusters get re-drawn for each zoom.
var contentString = 'This is an example';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});

Resources